সি তে ম্যাক্রো বনাম ফাংশন


104

আমি সর্বদা উদাহরণ এবং ক্ষেত্রে দেখেছি যেখানে ম্যাক্রো ব্যবহার করা ফাংশন ব্যবহারের চেয়ে ভাল।

কোনও ফাংশনের তুলনায় ম্যাক্রোর অসুবিধে কেউ আমাকে উদাহরণ দিয়ে ব্যাখ্যা করতে পারেন?


21
প্রশ্নটি তার মাথায় ঘুরিয়ে দিন। কোন পরিস্থিতিতে ম্যাক্রো ভাল? আপনি যদি না ম্যাক্রো আরও ভাল rate
ডেভিড হেফারনান

উত্তর:


115

ম্যাক্রোগুলি ত্রুটি-প্রবণ কারণ তারা পাঠ্য প্রতিস্থাপনার উপর নির্ভর করে এবং প্রকার-চেকিং করে না। উদাহরণস্বরূপ, এই ম্যাক্রো:

#define square(a) a * a

একটি পূর্ণসংখ্যার সাথে ব্যবহৃত হলে সূক্ষ্মভাবে কাজ করে:

square(5) --> 5 * 5 --> 25

তবে খুব অদ্ভুত কাজগুলি যখন প্রকাশের সাথে ব্যবহৃত হয়:

square(1 + 2) --> 1 + 2 * 1 + 2 --> 1 + 2 + 2 --> 5
square(x++) --> x++ * x++ --> increments x twice

যুক্তিগুলির চারপাশে প্রথম বন্ধন রাখার সাহায্য করে তবে এই সমস্যাগুলি সম্পূর্ণরূপে মুছে ফেলা হয় না।

যখন ম্যাক্রোতে একাধিক বিবৃতি থাকে, আপনি নিয়ন্ত্রণ-প্রবাহের নির্মাণগুলি নিয়ে সমস্যায় পড়তে পারেন:

#define swap(x, y) t = x; x = y; y = t;

if (x < y) swap(x, y); -->
if (x < y) t = x; x = y; y = t; --> if (x < y) { t = x; } x = y; y = t;

এটি ঠিক করার জন্য সাধারণ কৌশলটি হ'ল "ডু {...} করার সময় (0)" লুপের মধ্যে বিবৃতি রাখা।

যদি আপনার কাছে দুটি কাঠামো থাকে যা একই নামের সাথে পৃথক শব্দার্থবিজ্ঞানের ক্ষেত্র ধারণ করে তবে একই ম্যাক্রো অদ্ভুত ফলাফল সহ উভয়কেই কার্যকর করতে পারে:

struct shirt 
{
    int numButtons;
};

struct webpage 
{
    int numButtons;
};

#define num_button_holes(shirt)  ((shirt).numButtons * 4)

struct webpage page;
page.numButtons = 2;
num_button_holes(page) -> 8

অবশেষে, ম্যাক্রোগুলি ডিবাগ করা কঠিন হতে পারে, অদ্ভুত সিনট্যাক্স ত্রুটি বা রানটাইম ত্রুটিগুলি যা আপনাকে বুঝতে বাড়াতে হবে (উদাহরণস্বরূপ gcc -E সহ) তৈরি করতে পারে, কারণ ডিবাগারগুলি ম্যাক্রোগুলির মাধ্যমে পদক্ষেপ নিতে পারে না, উদাহরণস্বরূপ:

#define print(x, y)  printf(x y)  /* accidentally forgot comma */
print("foo %s", "bar") /* prints "foo %sbar" */

ইনলাইন ফাংশন এবং ধ্রুবকগুলি ম্যাক্রোগুলির সাথে এই সমস্যাগুলির অনেকগুলি এড়াতে সহায়তা করে তবে সর্বদা প্রযোজ্য নয়। যেখানে ম্যাক্রোজগুলি ইচ্ছাকৃতভাবে পলিমারফিক আচরণ নির্দিষ্ট করতে ব্যবহৃত হয়, সেখানে অনিচ্ছাকৃত বহুবচন এড়ানো কঠিন হতে পারে। সি ++ এর অনেকগুলি বৈশিষ্ট্য রয়েছে যেমন ম্যাক্রো ব্যবহার না করে টাইপসেজাল পদ্ধতিতে জটিল পলিমারফিক কন্সট্রাক্টস তৈরিতে সহায়তা করার জন্য টেমপ্লেটগুলি; বিশদ জানতে স্ট্রাস্ট্রপের সি ++ প্রোগ্রামিং ভাষা দেখুন।


44
সি ++ বিজ্ঞাপনে কী আছে?
পেসারিয়ার

4
একমত, এটি একটি সি প্রশ্ন, পক্ষপাত যুক্ত করার দরকার নেই।
ধারণাগুলি 42

17
সি ++ হ'ল সি এর একটি এক্সটেনশান যা সি এর নির্দিষ্ট সীমাবদ্ধতা সমাধানের উদ্দেশ্যে উদ্দিষ্ট বৈশিষ্ট্যগুলি যুক্ত করে (অন্যান্য জিনিসের মধ্যে) আমি সি ++ এর কোন অনুরাগী নই, তবে আমি মনে করি এটি এখানে বিষয়বস্তুতে রয়েছে।
ডি কোটজি

4
ম্যাক্রোস, ইনলাইন ফাংশন এবং টেমপ্লেটগুলি প্রায়শই পারফরম্যান্স বাড়ানোর চেষ্টায় ব্যবহৃত হয়। এগুলি অতিরিক্ত ব্যবহার করা হয় এবং কোড ব্লাটের কারণে পারফরম্যান্সের ক্ষতি করতে থাকে, যা সিপিইউ নির্দেশনা ক্যাশের কার্যকারিতা হ্রাস করে। আমরা এই কৌশলগুলি ব্যবহার না করে সি তে দ্রুত জেনেরিক ডেটা স্ট্রাকচার তৈরি করতে পারি।
স্যাম ওয়াটকিন্স

4
আইএসও / আইইসি 9899: 1999 §6.5.1 অনুযায়ী, "পূর্ববর্তী এবং পরবর্তী ক্রমিক পয়েন্টের মধ্যে কোনও বস্তুর তার সঞ্চিত মানটি একবারে এক্সপ্রেশনের মূল্যায়নের মাধ্যমে সংশোধন করতে হবে" " (একই শব্দটি পূর্ববর্তী এবং পরবর্তী সি স্ট্যান্ডার্ডগুলিতে বিদ্যমান।) সুতরাং অভিব্যক্তিটি দুবার x++*x++বৃদ্ধি হিসাবে বলা যায় না x; এটি প্রকৃতপক্ষে অপরিবর্তিত আচরণের জন্য আহ্বান করে , যার অর্থ সংকলকটি যে কোনও কিছু করতে পারে নিখরচায় — এটি xদ্বিগুণ বা একবার বৃদ্ধি পেতে পারে বা আদৌ নয়; এটি কোনও ত্রুটির সাথে বাতিল করতে পারে বা এমনকি আপনার নাক থেকে অসুরদেরও উড়ে যেতে পারে
সাইকোনাট

42

ম্যাক্রো বৈশিষ্ট্যগুলি :

  • ম্যাক্রো প্রিপ্রোসেসড
  • কোনও প্রকারের চেকিং নেই
  • কোড দৈর্ঘ্য বৃদ্ধি
  • ম্যাক্রোর ব্যবহার পার্শ্ব প্রতিক্রিয়া হতে পারে
  • কার্যকর করার গতি দ্রুততর
  • সংকলনের আগে ম্যাক্রো নামটি ম্যাক্রো মান দ্বারা প্রতিস্থাপিত হয়
  • দরকারী কোড যেখানে ছোট কোডটি অনেক সময় উপস্থিত হয়
  • ম্যাক্রো সংকলন ত্রুটিগুলি পরীক্ষা করে না

ফাংশন বৈশিষ্ট্য :

  • ফাংশন হয় সংকলিত হয়
  • প্রকারের চেকিং সম্পন্ন হয়
  • কোড দৈর্ঘ্য একই থাকে
  • না পার্শ্ব প্রতিক্রিয়া
  • কার্যকর করার গতি ধীর
  • ফাংশন কলের সময়, ট্রান্সফার অফ কন্ট্রোল হয়
  • দরকারী যেখানে বড় কোডটি অনেক সময় উপস্থিত হয়
  • ফাংশন চেকগুলি কম্পাইল ত্রুটিগুলি

4
"কার্যকর করার গতি দ্রুত" রেফারেন্স প্রয়োজন required গত দশকের যে কোনও এমনকি কিছুটা সক্ষম সংকলক এটি কার্যকারিতা সুবিধা প্রদান করবে বলে যদি মনে করে তবে এটি ঠিকঠাক ফাংশনগুলিকে ইনলাইন করবে।
ভু

4
এটি কি নয়, নিম্ন-স্তরের এমসিইউ (এভিআরগুলি, অর্থাৎ এটিএমটিগ 32) কম্পিউটিংয়ের প্রসঙ্গে ম্যাক্রোগুলি ভাল পছন্দ, কারণ তারা কল স্ট্যাকের মতো ফাংশন কল করেন না?
হার্ডিওয়েলেস

4
পছন্দ করেছেন সংকলকগণ এমনকি একটি এভিআরের জন্যও কোডটি খুব বুদ্ধিমানভাবে ইনলাইন করতে পারে। এখানে একটি উদাহরণ দেওয়া আছে: Godbolt.org/z/Ic21iM
এডওয়ার্ড

34

পার্শ্ব প্রতিক্রিয়া একটি বড় এক। এখানে একটি সাধারণ কেস রয়েছে:

#define min(a, b) (a < b ? a : b)

min(x++, y)

এতে প্রসারিত হয়:

(x++ < y ? x++ : y)

xএকই বিবৃতিতে দুবার বর্ধিত হয়। (এবং অপরিবর্তিত আচরণ)


মাল্টি-লাইন ম্যাক্রোগুলি লেখাও ব্যথা:

#define foo(a,b,c)  \
    a += 10;        \
    b += 10;        \
    c += 10;

\প্রতিটি লাইনের শেষে তাদের প্রয়োজন require


আপনি যদি এটিকে একটি একক অভিব্যক্তি না করেন তবে ম্যাক্রোস "ফিরিয়ে" দিতে পারে না:

int foo(int *a, int *b){
    side_effect0();
    side_effect1();
    return a[0] + b[0];
}

আপনি জিসিসির প্রকাশের বিবৃতি ব্যবহার না করা পর্যন্ত ম্যাক্রোতে এটি করতে পারবেন না। (সম্পাদনা: আপনি কমা অপারেটরটি ব্যবহার করতে পারেন যদিও ... এটি উপেক্ষা করেছেন ... তবে এটি এখনও কম পাঠযোগ্য হতে পারে))


পরিচালনার ক্রম: (@ouah এর সৌজন্যে)

#define min(a,b) (a < b ? a : b)

min(x & 0xFF, 42)

এতে প্রসারিত হয়:

(x & 0xFF < 42 ? x & 0xFF : 42)

তবে &এর চেয়ে কম নজির রয়েছে <। তাই 0xFF < 42প্রথমে মূল্যায়ন হয়।


5
এবং ম্যাক্রো সংজ্ঞাতে ম্যাক্রো যুক্তিগুলির সাথে প্রথম বন্ধনী স্থাপন না করা অগ্রাধিকারের সমস্যার দিকে নিয়ে যেতে পারে: উদাহরণস্বরূপ,min(a & 0xFF, 42)
বাহু

অই হ্যাঁ. আমি পোস্টটি আপডেট করার সময় আপনার মন্তব্যটি দেখিনি। আমার ধারণা আমিও সেটার উল্লেখ করব।
রহস্যময়

14

উদাহরণ 1:

#define SQUARE(x) ((x)*(x))

int main() {
  int x = 2;
  int y = SQUARE(x++); // Undefined behavior even though it doesn't look 
                       // like it here
  return 0;
}

যদিও:

int square(int x) {
  return x * x;
}

int main() {
  int x = 2;
  int y = square(x++); // fine
  return 0;
}

উদাহরণ 2:

struct foo {
  int bar;
};

#define GET_BAR(f) ((f)->bar)

int main() {
  struct foo f;
  int a = GET_BAR(&f); // fine
  int b = GET_BAR(&a); // error, but the message won't make much sense unless you
                       // know what the macro does
  return 0;
}

তুলনা করা:

struct foo {
  int bar;
};

int get_bar(struct foo *f) {
  return f->bar;
}

int main() {
  struct foo f;
  int a = get_bar(&f); // fine
  int b = get_bar(&a); // error, but compiler complains about passing int* where 
                       // struct foo* should be given
  return 0;
}

13

সন্দেহ হলে, ফাংশন (বা ইনলাইন ফাংশন) ব্যবহার করুন।

তবে এখানে উত্তরগুলি বেশিরভাগই ম্যাক্রোগুলির সাথে সমস্যাগুলি ব্যাখ্যা করে, ম্যাক্রোগুলি মন্দ বলে কিছু সাধারণ দৃষ্টিভঙ্গির পরিবর্তে মূ accidents় দুর্ঘটনা সম্ভব।
সমস্যাগুলি সম্পর্কে আপনি সচেতন হতে পারেন এবং সেগুলি এড়াতে শিখতে পারেন। তারপরে ম্যাক্রোগুলি কেবল তখনই ব্যবহার করুন যখন কোনও ভাল কারণ আছে।

কিছু ব্যতিক্রমী মামলা রয়েছে যেখানে ম্যাক্রোগুলি ব্যবহারের সুবিধা রয়েছে, এর মধ্যে রয়েছে:

  • জেনেরিক ফাংশন, যেমন নীচে উল্লিখিত হয়েছে, আপনার কাছে ম্যাক্রো থাকতে পারে যা বিভিন্ন ধরণের ইনপুট আর্গুমেন্টে ব্যবহার করা যেতে পারে।
  • পরিবর্তিত সংখ্যক আর্গুমেন্ট সি এর পরিবর্তে বিভিন্ন ফাংশনে ম্যাপ করতে পারে va_args
    উদাঃ https://stackoverflow.com/a/24837037/432509
  • তারা করতে পারেন ঐচ্ছিকভাবে এই ধরনের ডিবাগ স্ট্রিং যেমন স্থানীয় তথ্য, অন্তর্ভুক্ত:
    ( __FILE__, __LINE__, __func__)। প্রাক / পোস্টের শর্তগুলির জন্য পরীক্ষা করুন,assert ব্যর্থতা বা এমনকি স্থির-জরুরী হিসাবে পরীক্ষা করুন যাতে কোডটি অনুচিত ব্যবহারের জন্য সংকলন না করে (বেশিরভাগ ডিবাগ বিল্ডগুলির জন্য দরকারী)।
  • ইনপুট আরগগুলি পরিদর্শন করুন, আপনি ইনপুট আরগগুলিতে যেমন পরীক্ষা করতে পারেন যেমন তাদের প্রকারের আকার, মাপের পরীক্ষা করা, structকাস্টিংয়ের আগে চেক সদস্য উপস্থিত আছেন
    (পলিমারফিক প্রকারের জন্য দরকারী হতে পারে)
    অথবা একটি অ্যারে কিছু দৈর্ঘ্যের শর্ত পূরণ করে দেখুন।
    দেখুন: https://stackoverflow.com/a/29926435/432509
  • যদিও এতে উল্লেখ করা হয়েছে যে ফাংশনগুলি টাইপ চেকিং করে, সি মানগুলিও জোর করে তোলে (উদাহরণস্বরূপ ইনটস / ফ্লোটস)) বিরল ক্ষেত্রে এটি সমস্যাযুক্ত হতে পারে। ম্যাক্রোগুলি লেখা সম্ভব যা আরও ইনস্যাক্ট করে তার ইনপুট আরগগুলি সম্পর্কে একটি ফাংশন। দেখুন: https://stackoverflow.com/a/25988779/432509
  • ফাংশনগুলিতে মোড়ক হিসাবে তাদের ব্যবহার, কিছু ক্ষেত্রে আপনি নিজের পুনরাবৃত্তি এড়াতে চাইতে পারেন, যেমন ... func(FOO, "FOO");, আপনি কোনও ম্যাক্রো সংজ্ঞায়িত করতে পারেন যা আপনার জন্য স্ট্রিং প্রসারিত করেfunc_wrapper(FOO);
  • আপনি যখন কলারদের স্থানীয় স্কোপগুলিতে ভেরিয়েবলগুলি পরিচালনা করতে চান, তখন পয়েন্টারটির কাছে পয়েন্টারটি পৌঁছানো ঠিক স্বাভাবিকভাবে কাজ করে, তবে কিছু ক্ষেত্রে এখনও ম্যাক্রো ব্যবহার করতে কম সমস্যা হয়।
    (প্রতি পিক্সেল ক্রিয়াকলাপের জন্য একাধিক ভেরিয়েবলের অ্যাসাইনমেন্ট, এটি একটি উদাহরণ যা আপনি কোনও ফাংশনের চেয়ে ম্যাক্রোকে পছন্দ করতে পারেন ... যদিও এটি এখনও প্রসঙ্গে নির্ভর করে, যেহেতু inlineফাংশনগুলি একটি বিকল্প হতে পারে)

স্বীকার্যভাবে, এর মধ্যে কয়েকটি সংকলক এক্সটেনশনের উপর নির্ভর করে যা মান সি না হয় অর্থাত্ আপনি কম পোর্টেবল কোড দিয়ে শেষ করতে পারেন বা এগুলিতে থাকতে পারেন ifdef, তাই সংকলক যখন সমর্থন করে তখন সেগুলি কেবল তারাই গ্রহণ করা হবে।


একাধিক যুক্তি তাত্পর্য এড়ানো

এটি ম্যাক্রোগুলিতে ত্রুটির অন্যতম সাধারণ কারণ হিসাবে উদাহরণস্বরূপ লক্ষ করা ( x++উদাহরণস্বরূপ, যেখানে ম্যাক্রো একাধিকবার বৃদ্ধি করতে পারে)

যুক্তিগুলির একাধিক তাত্ক্ষণিকের সাথে পার্শ্ব-প্রতিক্রিয়া এড়ানো ম্যাক্রোগুলি লেখা এটি সম্ভব।

সি 11 জেনেরিক

আপনি যদি squareম্যাক্রো রাখতে চান যা বিভিন্ন ধরণের সাথে কাজ করে এবং সি 11 সমর্থন করে, আপনি এটি করতে পারেন ...

inline float           _square_fl(float a) { return a * a; }
inline double          _square_dbl(float a) { return a * a; }
inline int             _square_i(int a) { return a * a; }
inline unsigned int    _square_ui(unsigned int a) { return a * a; }
inline short           _square_s(short a) { return a * a; }
inline unsigned short  _square_us(unsigned short a) { return a * a; }
/* ... long, char ... etc */

#define square(a)                        \
    _Generic((a),                        \
        float:          _square_fl(a),   \
        double:         _square_dbl(a),  \
        int:            _square_i(a),    \
        unsigned int:   _square_ui(a),   \
        short:          _square_s(a),    \
        unsigned short: _square_us(a))

বিবৃতি প্রকাশ

এটি জিসিসি, ক্ল্যাং, ইকোপাথ এবং ইন্টেল সি ++ (তবে এমএসভিসি নয়) দ্বারা সমর্থিত একটি সংকলক এক্সটেনশন ;

#define square(a_) __extension__ ({  \
    typeof(a_) a = (a_); \
    (a * a); })

সুতরাং ম্যাক্রোগুলির অসুবিধাগুলি হ'ল এগুলি শুরু করার জন্য আপনার ব্যবহার করা জেনে রাখা উচিত এবং এগুলি ব্যাপকভাবে সমর্থিত নয়।

একটি সুবিধা হ'ল এই ক্ষেত্রে, আপনি একই squareফাংশনটি বিভিন্ন ধরণের জন্য ব্যবহার করতে পারেন ।


4
"... হিসাবে ব্যাপকভাবে সমর্থিত .." আমি আপনার দ্বারা বর্ণিত স্টেটমেন্ট এক্সপ্রেশন বাজিটি cl.exe দ্বারা সমর্থিত নয়? (এমএস এর সংকলক)
জিডিয়ন

4
@ জিডিয়ন, ডান সম্পাদিত উত্তর, যদিও প্রতিটি বৈশিষ্ট্যের জন্য উল্লেখ করা হয়েছে, নিশ্চিত না যে এটির কয়েকটি সংকলক-বৈশিষ্ট্য-সমর্থন ম্যাট্রিক্স থাকা প্রয়োজন।
ধারণাগুলি 42

12

প্যারামিটার এবং কোডের কোনও ধরণের চেকিং পুনরাবৃত্তি করা হয় যা কোড ফোলা বাড়ে। ম্যাক্রো সিনট্যাক্সের ফলে অনেকগুলি অদ্ভুত প্রান্তের ঘটনাও ঘটতে পারে যেখানে আধা-কলোন বা অগ্রাধিকারের অর্ডার আসতে পারে। এখানে একটি লিঙ্ক যা কিছু ম্যাক্রো অশুভতা প্রদর্শন করে


6

ম্যাক্রোগুলির একটি অপূর্ণতা হ'ল ডিবাগারগুলি সোর্স কোডটি পড়েন, যার ম্যাক্রোগুলি প্রসারিত হয় না, সুতরাং ম্যাক্রোতে একটি ডিবাগার চালানো প্রয়োজনীয় দরকারী নয়। বলা বাহুল্য, আপনি কোনও ম্যাক্রোর ভিতরে কোনও কার্যকারিতা সহ কোনও ব্রেকপয়েন্টটি সেট করতে পারবেন না।


ব্রেকপয়েন্টটি এখানে একটি খুব গুরুত্বপূর্ণ চুক্তি, এটি দেখানোর জন্য ধন্যবাদ।
হ্যান্স

6

ফাংশনগুলি টাইপ চেকিং করে। এটি আপনাকে সুরক্ষার অতিরিক্ত স্তর দেয়।


6

এই উত্তরে যুক্ত করা হচ্ছে ..

ম্যাক্রোগুলি প্রিপ্রোসেসর দ্বারা সরাসরি প্রোগ্রামে প্রতিস্থাপিত হয় (যেহেতু তারা মূলত প্রিপ্রোসেসর নির্দেশিকা)। সুতরাং তারা অনিবার্যভাবে একটি সম্পর্কিত ফাংশন চেয়ে বেশি মেমরি স্পেস ব্যবহার। অন্যদিকে, কোনও ফাংশনটির জন্য ডাকা এবং ফলাফলগুলি ফিরে পেতে আরও বেশি সময় প্রয়োজন এবং ম্যাক্রো ব্যবহার করে এই ওভারহেড এড়ানো যেতে পারে।

এছাড়াও বিভিন্ন প্ল্যাটফর্মগুলিতে প্রোগ্রাম বহনযোগ্যতার জন্য ম্যাক্রোগুলির কাছে কিছু বিশেষ সরঞ্জাম রয়েছে।

ফাংশনের বিপরীতে ম্যাক্রোগুলিকে তাদের যুক্তিগুলির জন্য কোনও ডেটা টাইপ দেওয়ার দরকার নেই।

সামগ্রিকভাবে তারা প্রোগ্রামিংয়ে একটি দরকারী সরঞ্জাম। এবং উভয় ম্যাক্রোইনস্ট্রাকশন এবং ফাংশন পরিস্থিতিগুলির উপর নির্ভর করে ব্যবহার করা যেতে পারে।


3

আমি উপরের উত্তরগুলিতে লক্ষ্য করিনি, ম্যাক্রোগুলির উপরে ফাংশনগুলির একটি সুবিধা যা আমি মনে করি এটি অত্যন্ত গুরুত্বপূর্ণ:

ফাংশনগুলি আর্গুমেন্ট হিসাবে পাস করা যেতে পারে, ম্যাক্রোগুলি পারে না।

কংক্রিট উদাহরণ: আপনি স্ট্যান্ডার্ড 'strpbrk' ফাংশনের একটি বিকল্প সংস্করণ লিখতে চান যা অন্য স্ট্রিংয়ের মধ্যে অনুসন্ধানের জন্য অক্ষরের একটি সুস্পষ্ট তালিকার পরিবর্তে, (একটি পয়েন্টার) ফাংশন যা অক্ষর না হওয়া পর্যন্ত 0 ফিরে আসবে পাওয়া গেছে যে কিছু পরীক্ষা পাস করে (ব্যবহারকারী সংজ্ঞায়িত)। আপনি এটি করতে চাইলে একটি কারণ আপনি অন্যান্য স্ট্যান্ডার্ড লাইব্রেরি ফাংশনগুলি কাজে লাগাতে পারেন: যতিচিহ্নে পূর্ণ স্পষ্ট স্ট্রিং সরবরাহ না করে আপনি ctype.h এর 'ispunct' বদলে পাস করতে পারেন, যদি 'ispunct' কেবল হিসাবে প্রয়োগ করা হত একটি ম্যাক্রো, এটি কাজ করবে না।

অন্যান্য প্রচুর উদাহরণ রয়েছে। উদাহরণস্বরূপ, যদি আপনার তুলনা ফাংশন না করে ম্যাক্রো দ্বারা সম্পন্ন হয় তবে আপনি এটিকে stdlib.h- এর 'qsort' এ দিতে পারবেন না।

পাইথনের অ্যানালগীয় পরিস্থিতি হ'ল সংস্করণ 2 বনাম সংস্করণ 3 (প্রেরণযোগ্য ফাংশন বনাম পাসযোগ্য ফাংশন) এর 'মুদ্রণ'।


4
এই উত্তরের জন্য ধন্যবাদ
কায়রোল

1

আপনি যদি ম্যাক্রোর আর্গুমেন্ট হিসাবে ফাংশনটি পাস করেন তবে এটি প্রতিবার মূল্যায়ন করা হবে। উদাহরণস্বরূপ, আপনি যদি সর্বাধিক জনপ্রিয় কোনও ম্যাক্রো কল করেন:

#define MIN(a,b) ((a)<(b) ? (a) : (b))

সে রকমই

int min = MIN(functionThatTakeLongTime(1),functionThatTakeLongTime(2));

ফাংশনটিটেকলংটাইম 5 বার মূল্যায়ন করা হবে যা পারফরম্যান্স উল্লেখযোগ্যভাবে হ্রাস করতে পারে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.