উত্তর:
প্রিপ্রসেসর ম্যাক্রোগুলি কেবলমাত্র আপনার কোডে প্রয়োগ করা প্রতিস্থাপনের নিদর্শন। এগুলি আপনার কোডের প্রায় যে কোনও জায়গায় ব্যবহার করা যেতে পারে কারণ কোনও সংকলন শুরুর আগে সেগুলি তাদের বিস্তৃত জায়গায় প্রতিস্থাপন করা হয়েছিল।
ইনলাইন ফাংশনগুলি হ'ল আসল ফাংশন যার শরীর সরাসরি তাদের কল সাইটে intoুকিয়ে দেয়। সেগুলি কেবল সেখানে ব্যবহার করা যেতে পারে যেখানে কোনও ফাংশন কল উপযুক্ত।
এখন, ম্যাক্রো বনাম ইন-ইনলাইন ফাংশন যেমন কোনও ফাংশন-জাতীয় প্রসঙ্গে ব্যবহার করার পরামর্শ দেওয়া হচ্ছে:
প্রথমত, প্রিপ্রসেসর ম্যাক্রোগুলি সংকলনের আগে কোডে কেবল "কপি পেস্ট" হয় are সুতরাং কোনও ধরণের চেকিং নেই , এবং কিছু পার্শ্ব প্রতিক্রিয়া উপস্থিত হতে পারে
উদাহরণস্বরূপ, আপনি যদি 2 টি মান তুলনা করতে চান:
#define max(a,b) ((a<b)?b:a)
পার্শ্ব প্রতিক্রিয়াগুলি প্রদর্শিত হয় যদি আপনি max(a++,b++)
উদাহরণস্বরূপ ব্যবহার করেন ( a
বা b
দুবার বাড়ানো হবে)। পরিবর্তে, ব্যবহার করুন (উদাহরণস্বরূপ)
inline int max( int a, int b) { return ((a<b)?b:a); }
max(fibonacci(100), factorial(10000))
ইনলাইন ফাংশনটি সংকলক দ্বারা প্রসারিত করা হয়েছে যেখানে ম্যাক্রো প্রিপ্রসেসর দ্বারা প্রসারিত করা হয়েছে যা কেবল পাঠ্য প্রতিস্থাপন।
ফাংশন কল চলাকালীন টাইপ চেকিং করা হয় যখন ম্যাক্রো অনুরোধ সময় কোন ধরণের চেকিং হয়।
যুক্তি পুনরায় মূল্যায়ন এবং ক্রিয়াকলাপের ক্রমের কারণে ম্যাক্রো বিস্তারের সময় অযাচিত ফলাফল এবং অদক্ষতা দেখা দিতে পারে। উদাহরণ স্বরূপ
#define MAX(a,b) ((a)>(b) ? (a) : (b))
int i = 5, j = MAX(i++, 0);
ফলাফল হবে
int i = 5, j = ((i++)>(0) ? (i++) : (0));
ম্যাক্রো যুক্তিগুলি ম্যাক্রো প্রসারণের আগে মূল্যায়ন করা হয় না
#define MUL(a, b) a*b
int main()
{
// The macro is expended as 2 + 3 * 3 + 5, not as 5*8
printf("%d", MUL(2+3, 3+5));
return 0;
}
// Output: 16`
ফাংশনের ক্ষেত্রে মানগুলি ফেরত দিতে রিটার্ন কীওয়ার্ডটি ম্যাক্রোগুলিতে ব্যবহার করা যায় না।
ইনলাইন ফাংশনগুলি ওভারলোড করা যায়
টোকেন-পেস্টিং অপারেটর নামে ## অপারেটর ব্যবহার করে ম্যাক্রোগুলিতে পাস হওয়া টোকেনগুলি সংহত করা যেতে পারে।
ম্যাক্রোগুলি সাধারণত কোড পুনরায় ব্যবহারের জন্য ব্যবহৃত হয় যেখানে ইনলাইন ফাংশন হিসাবে ফাংশন কল চলাকালীন সময় ওভারহেড (অতিরিক্ত সময়) নির্মূল করতে ব্যবহৃত হয় (সাব্রোটিনে ঝাঁপ এড়ানো)।
মূল পার্থক্য হ'ল টাইপ চেকিং। সংকলকটি ইনপুট মান হিসাবে যা পাস করবে তা ফাংশনে প্রেরণ করা যায় কি না তা পরীক্ষা করে। এটি প্রিপ্রোসেসর ম্যাক্রোগুলির সাথে সত্য নয় - এগুলি কোনও প্রকারের চেকিংয়ের আগে প্রসারিত হয় এবং এর ফলে ত্রুটিগুলি সনাক্ত করা গুরুতর এবং শক্ত হতে পারে।
এখানে আরও কয়েকটি কম সুস্পষ্ট পয়েন্ট বর্ণিত হয়েছে।
ইতিমধ্যে প্রদত্তদের মধ্যে আরও একটি পার্থক্য যুক্ত করতে: আপনি #define
ডিবাগারে কোনও পদক্ষেপ নিতে পারবেন না , তবে আপনি একটি ইনলাইন ফাংশনটি দিয়ে যেতে পারেন।
ম্যাক্রোস নেমস্পেসগুলি উপেক্ষা করছে। এবং এটি তাদের খারাপ করে তোলে।
ইনলাইন ফাংশনগুলি ম্যাক্রোগুলির সমান (কারণ ফাংশন কোডটি সংকলনের সময় কলের বিন্দুতে প্রসারিত হয়), ইনলাইন ফাংশনগুলি সংকলক দ্বারা পার্স করা হয়, যেখানে ম্যাক্রো প্রিপ্রসেসর দ্বারা প্রসারিত হয়। ফলস্বরূপ, বেশ কয়েকটি গুরুত্বপূর্ণ পার্থক্য রয়েছে:
কিছু ক্ষেত্রে ম্যাক্রোগুলির পক্ষে যুক্তি হিসাবে প্রকাশিত অভিব্যক্তিগুলি একাধিকবার মূল্যায়ন করা যেতে পারে। http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx
প্রাক-সংকলনের সময় ম্যাক্রোগুলি প্রসারিত হয়, আপনি সেগুলি ডিবাগিংয়ের জন্য ব্যবহার করতে পারবেন না, তবে আপনি ইনলাইন ফাংশন ব্যবহার করতে পারেন।
- ভাল নিবন্ধ : http://www.codeguru.com/forum/showpost.php?p=1093923&postcount=1
;
একটি ইনলাইন ফাংশন মান শব্দার্থবিজ্ঞান বজায় রাখে, তবে একটি প্রিপ্রসেসর ম্যাক্রো কেবল সিনট্যাক্সটি অনুলিপি করে। আপনি একাধিকবার আর্গুমেন্ট ব্যবহার করলে আপনি প্রিপ্রোসেসর ম্যাক্রো সহ খুব সূক্ষ্ম বাগ পেতে পারেন - উদাহরণস্বরূপ যদি যুক্তিতে "i ++" এর মত মিউটেশন থাকে যা দুবার মৃত্যুদণ্ড কার্যকর করা বেশ অবাক করে। একটি ইনলাইন ফাংশনটিতে এই সমস্যা থাকবে না।
ম্যাক্রো এবং ইনলাইন ফাংশনের মধ্যে পার্থক্য জানতে , প্রথমে আমাদের জানা উচিত যে তারা ঠিক কী এবং কখন তাদের ব্যবহার করা উচিত।
ফাংশন :
int Square(int x){
return(x*X);
}
int main()
{
int value = 5;
int result = Square(value);
cout << result << endl;
}
ফাংশন কলগুলির সাথে ওভারহেড যুক্ত রয়েছে, ফাংশন কার্যকর হওয়ার পরে এটি কোথায় ফিরে আসতে হবে তা জানতে হবে এবং স্ট্যাক মেমোরিতে মানটি সংরক্ষণ করতে হবে।
ছোট অ্যাপ্লিকেশনগুলির জন্য এটি কোনও সমস্যা হবে না, তবে আসুন আর্থিক অ্যাপ্লিকেশনগুলির একটি উদাহরণ নেওয়া যাক যেখানে প্রতি সেকেন্ডে কয়েক হাজার লেনদেন হয়, আমরা ফাংশন কল দিয়ে যেতে পারি না।
ম্যাক্রো:
# define Square(x) x*x;
int main()
{
int value = 5;
int result = Square(value);
cout << result << endl;
}
int ফলাফল = বর্গ (x * x)
তবে ম্যাক্রোগুলির সাথে এর সাথে সম্পর্কিত বাগ রয়েছে।
#define Square(x) x*x
int main() {
int val = 5;
int result = Square(val + 1);
cout << result << endl;
return 0;
}
এখানে আউটপুট 11 নয় 36 ।
অনলাইন কাজ :
inline int Square(int x) {
return x * x;
}
int main() {
using namespace std;
int val = 5;
int result = Square(val + 1);
cout << result << endl;
return 0;
}
আউটপুট 36
ইনলাইন কীওয়ার্ডটি ফাংশনটির মূল অংশের সাথে ফাংশন কলটি প্রতিস্থাপনের জন্য কম্পাইলারকে অনুরোধ করে, এখানে আউটপুট সঠিক কারণ এটি প্রথমে এক্সপ্রেশনটি মূল্যায়ন করে এবং পরে পাস হয়ে যায় the ফাংশন কল ওভারহেড হ্রাস করে কারণ রিটার্নের ঠিকানা এবং স্ট্যাক সংরক্ষণ করার প্রয়োজন নেই ফাংশন যুক্তিগুলির জন্য মেমরির প্রয়োজন হয় না।
ম্যাক্রো এবং ইনলাইন ফাংশনগুলির মধ্যে তুলনা:
উপসংহার:
ইনলাইন ফাংশনগুলি কখনও কখনও ম্যাক্রোর চেয়ে বেশি কার্যকর হয় কারণ এটি কার্যকারিতা উন্নত করে এবং নিরাপদ এবং ফাংশন কল ওভারহেডকে হ্রাস করে। এটি কেবল সংকলকের কাছে একটি অনুরোধ, নির্দিষ্ট ফাংশনগুলি এইভাবে প্রবেশ করানো হবে না:
যা একটি ভাল জিনিস, কারণ এটি যখনই সংকলক মনে করে যে জিনিসগুলি অন্যভাবে করা ভাল।
জিসিসিতে (আমি অন্যের বিষয়ে নিশ্চিত নই), কোনও ফাংশনটিকে ইনলাইনে ঘোষণা করা সংকলকটির জন্য কেবল একটি ইঙ্গিত। এটি যখনই ডাকা হয় তখন এটি ফাংশনের মূল অংশটি অন্তর্ভুক্ত করে কিনা তা নির্ধারণের জন্য দিন শেষে সংকলকটি এখনও নির্ভর করে।
ইন-লাইন ফাংশন এবং প্রিপ্রেসেসর ম্যাক্রোর মধ্যে পার্থক্য তুলনামূলকভাবে বড় large প্রিপ্রসেসর ম্যাক্রোগুলি দিনের শেষে কেবল পাঠ্য প্রতিস্থাপন। আপনি সংকলকটির পক্ষে আর্গুমেন্ট এবং রিটার্ন টাইপের প্রকার পরীক্ষা করে পরীক্ষা করার জন্য যথেষ্ট ক্ষমতা ছেড়ে দেন। আর্গুমেন্টগুলির মূল্যায়ন অনেক আলাদা (যদি আপনি ফাংশনগুলিতে প্রবেশ করেন এমন প্রকাশগুলিগুলির পার্শ্ব-প্রতিক্রিয়া থাকে তবে আপনার একটি খুব মজাদার সময় ডিবাগিং হবে)। ফাংশন এবং ম্যাক্রোগুলি কোথায় ব্যবহার করা যায় সে সম্পর্কে সূক্ষ্ম পার্থক্য রয়েছে। উদাহরণস্বরূপ যদি আমার কাছে থাকে:
#define MACRO_FUNC(X) ...
যেখানে MACRO_FUNC স্পষ্টতই ফাংশনটির মূল সংজ্ঞা দেয়। বিশেষ যত্ন নেওয়া দরকার তাই এটি সঠিকভাবে চলতে পারে সমস্ত ক্ষেত্রেই একটি ফাংশন ব্যবহার করা যেতে পারে, উদাহরণস্বরূপ একটি দুর্বল লিখিত MACRO_FUNC এতে ত্রুটির কারণ হতে পারে
if(MACRO_FUNC(y)) {
...body
}
কোনও সমস্যা নেই সেখানে একটি সাধারণ ফাংশন ব্যবহার করা যেতে পারে।
কোডিংয়ের দৃষ্টিকোণ থেকে, একটি ইনলাইন ফাংশন একটি ফাংশনের মতো। সুতরাং, একটি ইনলাইন ফাংশন এবং ম্যাক্রোর মধ্যে পার্থক্যগুলি কোনও ফাংশন এবং ম্যাক্রোর মধ্যে পার্থক্যগুলির সমান।
সংকলনের দৃষ্টিকোণ থেকে, একটি ইনলাইন ফাংশন ম্যাক্রোর অনুরূপ। এটি সরাসরি কোডে ইনজেকশন দেওয়া হয়, বলা হয় না।
সাধারণভাবে, আপনাকে কিছুটা অপেক্ষাকৃত অপ্টিমাইজেশান মিশ্রিত করার সাথে ইনলাইন ফাংশনগুলিকে নিয়মিত ফাংশন হিসাবে বিবেচনা করা উচিত And প্রায়শই সংকলক বিভিন্ন কারণে কোনও ক্রিয়াকলাপটি ইনলাইন করার জন্য প্রোগ্রামার কর্তৃক যে প্রচেষ্টা চালিয়ে যায় তা আনন্দের সাথে উপেক্ষা করবে।
ইনলাইন ফাংশনগুলি এতে কোনও পুনরাবৃত্ত বা পুনরাবৃত্ত বিবৃতি উপস্থিত থাকলে ফাংশন কল হিসাবে আচরণ করবে, যাতে নির্দেশের বারবার সম্পাদনা রোধ করতে পারে। আপনার প্রোগ্রামের সামগ্রিক স্মৃতি সংরক্ষণ করতে এটি বেশ সহায়ক।
#include<iostream>
using namespace std;
#define NUMBER 10 //macros are preprocessed while functions are not.
int number()
{
return 10;
}
/*In macros, no type checking(incompatible operand, etc.) is done and thus use of micros can lead to errors/side-effects in some cases.
However, this is not the case with functions.
Also, macros do not check for compilation error (if any). Consider:- */
#define CUBE(b) b*b*b
int cube(int a)
{
return a*a*a;
}
int main()
{
cout<<NUMBER<<endl<<number()<<endl;
cout<<CUBE(1+3); //Unexpected output 10
cout<<endl<<cube(1+3);// As expected 64
return 0;
}
ম্যাক্রোগুলি ফাংশনগুলির তুলনায় সাধারণত দ্রুত হয় কারণ এগুলি প্রকৃত ফাংশন কল ওভারহেডের সাথে জড়িত না।
ম্যাক্রোর কিছু অসুবিধাগুলি: কোনও প্রকারের চেকিং নেই ug ডিবাগ করার জন্য কারণ এগুলি সরল প্রতিস্থাপনের কারণ হয়। ম্যাক্রোর নাম স্থান নেই, তাই কোডের একটি বিভাগে থাকা একটি ম্যাক্রো অন্য বিভাগকে প্রভাবিত করতে পারে। উপরের কিউব () উদাহরণ হিসাবে দেখানো হয়েছে ম্যাক্রোগুলি পার্শ্ব প্রতিক্রিয়া সৃষ্টি করতে পারে।
ম্যাক্রো সাধারণত একটি লাইনার হয়। তবে এগুলি একাধিক লাইনের সমন্বয়ে থাকতে পারে functions কার্যক্রমে এ জাতীয় কোনও বাধা নেই।
#define TWO_N(n) 2 << n
তারপরে আর কত মজা পাবেন cout << CUBE(TWO_N(3 + 1)) << endl;
? (আউটপুটটির লাইনগুলি endl
শুরু করার চেয়ে শেষ করা ভাল ))