ফাংশন পয়েন্টার বিন্দু কি?


96

ফাংশন পয়েন্টারগুলির ইউটিলিটিটি দেখতে আমার সমস্যা হয়। আমি অনুমান করি যে এটি কিছু ক্ষেত্রে কার্যকর হতে পারে (সেগুলি বিদ্যমান রয়েছে) তবে আমি এমন কোনও ক্ষেত্রে ভাবতে পারি না যেখানে কোনও ফাংশন পয়েন্টার ব্যবহার করা ভাল বা অপরিহার্য।

আপনি ফাংশন পয়েন্টার (সি বা সি ++) এর ভাল ব্যবহারের কিছু উদাহরণ দিতে পারেন?


4
আপনি এই সম্পর্কিত এসও প্রশ্নে ফাংশন পয়েন্টারগুলি সম্পর্কে বেশ খানিকটা আলোচনার সন্ধান করতে পারেন ।
itmatt

20
@ আইস্ম্যাট: সত্যই নয়। "টিভি কীভাবে কাজ করে?" "একটি টিভি দিয়ে আমি কী করব?" এর চেয়ে একেবারে আলাদা প্রশ্ন?
এসবিআই

6
সি ++ এ আপনি সম্ভবত এর পরিবর্তে একটি ফান্ট্রার ব্যবহার করবেন ( en.wikedia.org/wiki/Function_object#In_C_and_C.2B.2B )।
কেনেটিএম

11
পুরানো অন্ধকার দিনগুলিতে যখন সি ++ কে সি-তে "সংকলিত" করা হত, আপনি আসলে দেখতে পেলেন ভার্চুয়াল পদ্ধতিগুলি কীভাবে প্রয়োগ করা হয় - হ্যাঁ, ফাংশন পয়েন্টার সহ।
এসবিকে

4
যখন আপনি একটি পরিচালিত সি ++ বা সি # দিয়ে সি ++ ব্যবহার করতে চান তখন অত্যন্ত প্রয়োজনীয়, অর্থাত্ ডেলিগেটস এবং কলব্যাকস
মাহের

উত্তর:


109

সর্বাধিক উদাহরণ ফুটাইয়া কমান callbacks : আপনি একটি ফাংশন কল f()অন্য ফাংশনের ঠিকানা ক্ষণস্থায়ী g(), এবং f()কল g()কিছু নির্দিষ্ট কাজের জন্য। আপনি যদি f()এর h()পরিবর্তে ঠিকানাটি পাস করেন , তবে পরিবর্তে f()আবার কল করবেন h()

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

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

class functor {
  public:
     void operator()(int i) {std::cout << "the answer is: " << i << '\n';}
};

functor f;
f(42);

এর পিছনে ধারণাটি হ'ল, কোনও ফাংশন পয়েন্টারের বিপরীতে, একটি ফাংশন অবজেক্ট কেবল একটি অ্যালগোরিদমই নয়, ডেটাও বহন করতে পারে:

class functor {
  public:
     functor(const std::string& prompt) : prompt_(prompt) {}
     void operator()(int i) {std::cout << prompt_ << i << '\n';}
  private:
     std::string prompt_;
};

functor f("the answer is: ");
f(42);

আরেকটি সুবিধা হ'ল ফাংশন পয়েন্টারগুলির মাধ্যমে কলগুলির চেয়ে কখনও কখনও ফাংশন অবজেক্টগুলিতে কলগুলি ইনলাইন করা সহজ। এই কারণেই সি ++ এ বাছাই করা মাঝে মাঝে সি বাছাইয়ের চেয়ে দ্রুত হয় is


4
+1, আরও একটি উদাহরণের জন্য এই উত্তরটি দেখুন: stackoverflow.com/questions/1727824/…
শার্পথথ

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

4
@ ক্রিএনার: ভার্চুয়াল ফাংশনগুলি কেবল সংকলক প্রয়োগকারীদের ফাংশন পয়েন্টার এবং যদি আপনি তাদের ভাল কি তা জিজ্ঞাসা করতে পারেন তবে আপনি সম্ভবত (আশাবাদী!) একটি সংকলকের ভার্চুয়াল ফাংশন প্রক্রিয়া বাস্তবায়নের প্রয়োজন হবেন না।
এসবিআই

@ এসবিআই: আপনি অবশ্যই ঠিক বলেছেন। তবে আমি মনে করি এটি বিমূর্তির অভ্যন্তরে কী চলছে তা বুঝতে সহায়তা করে। এছাড়াও, সিতে আপনার নিজস্ব ভিটিবেল বাস্তবায়ন করুন এবং অবজেক্ট ওরিয়েন্টেড কোড লিখুন সত্যিকারের একটি ভাল শিক্ষার অভিজ্ঞতা রয়েছে।
ফ্লোরিয়ান

জীবন, মহাবিশ্ব এবং সমস্ত কিছুর উত্তর দেওয়ার জন্য
ব্রাউন পয়েন্টগুলি

41

ওয়েল, আমি সাধারণত তাদের ( পেশাদারভাবে ) লাফ টেবিলগুলিতে ব্যবহার করি ( এটি এই স্ট্যাকওভারফ্লো প্রশ্নটিও দেখুন )।

লাফ টেবিলগুলি সাধারণত (তবে একচেটিয়াভাবে নয়) সীমাবদ্ধ রাষ্ট্র মেশিনগুলিতে তাদের ডেটা চালিত করতে ব্যবহৃত হয় । নেস্টেড সুইচ / কেস পরিবর্তে

  switch (state)
     case A:
       switch (event):
         case e1: ....
         case e2: ....
     case B:
       switch (event):
         case e3: ....
         case e1: ....

আপনি ফাংশন পয়েন্টারগুলির 2 ডি অ্যারে করতে পারেন এবং কেবল কল করতে পারেন handleEvent[state][event]


24

উদাহরণ:

  1. কাস্টম বাছাই / অনুসন্ধানগুলি
  2. বিভিন্ন নিদর্শন (যেমন কৌশল, পর্যবেক্ষক)
  3. কলব্যাকস

4
জাম্প টেবিল এটির অন্যতম গুরুত্বপূর্ণ ব্যবহার।
আশীষ

যদি কিছু কাজের উদাহরণ থাকে তবে এটি আমার উত্সাহ পেতে পারে।
ডোনাল ফেলো 12

4
কৌশল এবং পর্যবেক্ষক সম্ভবত ভার্চুয়াল ফাংশন ব্যবহার করে আরও ভাল প্রয়োগ করা হয়েছে, যদি সি ++ উপলব্ধ থাকে। অন্যথায় +1।
বিলি ওনিল

আমি মনে করি ফাংশন পয়েন্টারগুলির বুদ্ধিমান ব্যবহার পর্যবেক্ষকদের আরও কমপ্যাক্ট এবং হালকা ওজন তৈরি করতে পারে
আন্দ্রে

@ বিলিওনিল কেবলমাত্র যদি আপনি জাওএফ সংজ্ঞাটি কঠোরভাবে আঁকড়ে রাখেন তবে এর সাথে জাভাসগুলি ফুটে উঠেছে। আমি বর্ণনা করবেন std::sort'র compপরামিতি কৌশল হিসেবে
Caleth

10

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


7

উপরোক্ত, প্লাস .... এর সাথে একমত হোন আপনি রানটাইমের সময় যখন কোনও ডেল ডায়নামালি লোড করবেন তখন আপনাকে ফাংশনগুলি কল করার জন্য ফাংশন পয়েন্টার প্রয়োজন।


4
আমি উইন্ডোজ এক্সপি সমর্থন করার জন্য এটি সর্বদা করি এবং এখনও উইন্ডোজ 7 গুডি ব্যবহার করি। +1
বিলি ওনিল

7

আমি এখানে কারেন্টের বিপরীতে যাচ্ছি।

সিতে, ফাংশন পয়েন্টারগুলি কাস্টমাইজেশন বাস্তবায়নের একমাত্র উপায়, কারণ সেখানে কোনও ওও নেই।

সি ++ এ আপনি একই ফলাফলের জন্য ফাংশন পয়েন্টার বা ফান্টেক্টর (ফাংশন অবজেক্ট) ব্যবহার করতে পারেন।

ফ্যান্টেক্টরগুলির কাঁচা ফাংশন পয়েন্টারগুলির তুলনায় তাদের বেশ কয়েকটি সুবিধা রয়েছে, তাদের বস্তুর প্রকৃতির কারণে, উল্লেখযোগ্য:

  • তারা এর বেশ কয়েকটি ওভারলোড উপস্থাপন করতে পারে operator()
  • তাদের বিদ্যমান ভেরিয়েবলগুলির স্থিতি / রেফারেন্স থাকতে পারে
  • সেগুলি স্পটটিতে নির্মিত হতে পারে ( lambdaএবং bind)

আমি ব্যক্তিগতভাবে ফান্টেক্টরগুলিকে ফাংশন পয়েন্টারগুলিতে পছন্দ করি (বয়লারপ্লেট কোড সত্ত্বেও), বেশিরভাগ কারণ ফাংশন পয়েন্টারগুলির সিনট্যাক্স সহজেই লোমশ হয়ে উঠতে পারে ( ফাংশন পয়েন্টার টিউটোরিয়াল থেকে ):

typedef float(*pt2Func)(float, float);
  // defines a symbol pt2Func, pointer to a (float, float) -> float function

typedef int (TMyClass::*pt2Member)(float, char, char);
  // defines a symbol pt2Member, pointer to a (float, char, char) -> int function
  // belonging to the class TMyClass

কেবলমাত্র আমি একবারই ফাংশন পয়েন্টার ব্যবহার করতে দেখেছি যেখানে বুস্ট.স্পিরিটে ফান্টাররা থাকতে পারে না। তারা একক টেম্পলেট প্যারামিটার হিসাবে একটি নির্বিচার সংখ্যক পরামিতি পাস করার জন্য সিনট্যাক্সটিকে পুরোপুরি গালি দিয়েছে abused

 typedef SpecialClass<float(float,float)> class_type;

তবে যেহেতু ভেরিয়াদিক টেম্পলেট এবং ল্যাম্বডাস কোণার চারপাশে রয়েছে তাই আমি নিশ্চিত নই যে আমরা দীর্ঘ সময়ের জন্য খাঁটি সি ++ কোডে ফাংশন পয়েন্টার ব্যবহার করব।


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

4
@ ক্রাইনার: আমি বিনয়ের সাথে একমত হব না। আপনি যা দেখেন এবং টাইপ করেন তা কী গুরুত্বপূর্ণ তা আপনি ব্যবহার করেন এমন সিনট্যাক্স। এটি কীভাবে পর্দার আড়ালে সমস্ত কাজ করে তা আপনার বিবেচ্য নয়: এটি বিমূর্ততা সম্পর্কে।
ম্যাথিউ এম।

5

সি-তে, ক্লাসিক ব্যবহারটি হল Qsort ফাংশন , যেখানে চতুর্থ প্যারামিটারটি কোনও ক্রমে নির্দেশ করে যাতে সাজানোর মধ্যে ক্রম সম্পাদন করতে ব্যবহৃত হয়। সি ++ এ, এই ধরণের জিনিসটির জন্য কেউ ফান্টেক্টর (ফাংশনগুলির মতো দেখায় এমন বস্তু) ব্যবহার করার প্রবণতা রাখে।


4
@ কেনিটিএম: আমি সি স্ট্যান্ডার্ড লাইব্রেরিতে এর একমাত্র অন্য উদাহরণটি দেখিয়েছিলাম। আপনি যে উদাহরণগুলি উদ্ধৃত করেছেন তা হ'ল তৃতীয় পক্ষের গ্রন্থাগারের অংশ।
বিলি ওনিল

5

আমি একটি বিমূর্ত স্তর তৈরি করতে সম্প্রতি ফাংশন পয়েন্টার ব্যবহার করেছি।

আমার খাঁটি সি তে লেখা একটি প্রোগ্রাম রয়েছে যা এম্বেড থাকা সিস্টেমে চলে। এটি একাধিক হার্ডওয়্যার বৈকল্পিক সমর্থন করে। আমি যে হার্ডওয়্যারটি চালাচ্ছি তার উপর নির্ভর করে এর জন্য কিছু ফাংশনের বিভিন্ন সংস্করণ কল করা দরকার।

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

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

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


3

ভালো লেগেছে রিচ উপরে বলেন, এটা কিছু ঠিকানা যা সঞ্চয় ফাংশন রেফারেন্স উইন্ডোজে ফাংশন পয়েন্টার জন্য খুবই স্বাভাবিক হয়।

আপনি যখন C languageউইন্ডোজ প্ল্যাটফর্মে প্রোগ্রামিং করেন আপনি মূলত প্রাথমিক মেমরিতে কিছু ডিএলএল ফাইল লোড করেন (ব্যবহার করে LoadLibrary) এবং ডিএলএলে সঞ্চিত ফাংশনগুলি ব্যবহার করার জন্য আপনাকে ফাংশন পয়েন্টার তৈরি করতে হবে এবং এই ঠিকানাগুলিতে নির্দেশ করতে হবে (ব্যবহার করে GetProcAddress)।

তথ্যসূত্র:


2

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


2

সেগুলির মধ্যে আমার প্রধান ব্যবহারটি কলব্যাকগুলি হয়েছে: যখন আপনাকে পরে কল করার জন্য কোনও ফাংশন সম্পর্কিত তথ্য সংরক্ষণ করতে হবে

বলুন আপনি বমবারম্যান লিখছেন। বোমাটি ছোঁড়ার 5 সেকেন্ড পরে, এটি বিস্ফোরিত হওয়া উচিত ( explode()ফাংশনটি কল করুন )।

এখন এটি করার 2 টি উপায় রয়েছে। একটি উপায় হ'ল পর্দার সমস্ত বোমা "তদন্ত করা" তা দেখার জন্য যে তারা মূল লুপে বিস্ফোরণের জন্য প্রস্তুত কিনা।

foreach bomb in game 
   if bomb.boomtime()
       bomb.explode()

অন্য উপায়টি হ'ল আপনার ক্লক সিস্টেমে একটি কলব্যাক সংযুক্ত করা। যখন একটি বোমা রোপণ করা হলে আপনি () এটা bomb.explode কল করতে সঠিক সময় এলে একটি কলব্যাক যোগ

// user placed a bomb
Bomb* bomb = new Bomb()
make callback( function=bomb.explode, time=5 seconds ) ;

// IN the main loop:
foreach callback in callbacks
    if callback.timeToRun
         callback.function()

এখানে কোনও ফাংশনcallback.function() হতে পারে , কারণ এটি একটি ফাংশন পয়েন্টার।


প্রশ্নটি অন্য কোনও ভাষার ট্যাগ নয়, [সি] এবং [সি ++] দিয়ে ট্যাগ করা হয়েছে। সুতরাং, অন্য ভাষায় কোড স্নিপেট সরবরাহ করা কিছুটা অফ-টপিক।
cmaster - পুনর্বহাল মনিকা

2

ফাংশন পয়েন্টার ব্যবহার

ডায়নামিকভাবে ফাংশন কল করতেব্যবহারকারী ইনপুট উপর ভিত্তি করে । এক্ষেত্রে স্ট্রিং এবং ফাংশন পয়েন্টারের একটি মানচিত্র তৈরি করে।

#include<iostream>
#include<map>
using namespace std;
//typedef  map<string, int (*)(int x, int y) > funMap;
#define funMap map<string, int (*)(int, int)>
funMap objFunMap;

int Add(int x, int y)
{
    return x+y;
}
int Sub(int x, int y)
{
        return x-y;
}
int Multi(int x, int y)
{
        return x*y;
}
void initializeFunc()
{
        objFunMap["Add"]=Add;
        objFunMap["Sub"]=Sub;
        objFunMap["Multi"]=Multi;
}
int main()
{
    initializeFunc();

    while(1)
    {
        string func;
        cout<<"Enter your choice( 1. Add 2. Sub 3. Multi) : ";
        int no, a, b;
        cin>>no;

        if(no==1)
            func = "Add";
        else if(no==2)
            func = "Sub";
        else if(no==3)
            func = "Multi";
        else 
            break;

        cout<<"\nEnter 2 no :";
                cin>>a>>b;

        //function is called using function pointer based on user input
        //If user input is 2, and a=10, b=3 then below line will expand as "objFuncMap["Sub"](10, 3)"
        int ret = objFunMap[func](a, b);      
        cout<<ret<<endl;
    }
    return 0;
}

এইভাবে আমরা আমাদের প্রকৃত কোম্পানির কোডটিতে ফাংশন পয়েন্টার ব্যবহার করেছি। আপনি 'এন' ফাংশনের নম্বর লিখতে পারেন এবং এই পদ্ধতিটি ব্যবহার করে তাদের কল করতে পারেন।

আউটপুট:

    আপনার পছন্দ লিখুন (1. যোগ 2. সাব 3. বহু): 1
    2 নম্বর: 2 4 প্রবেশ করান
    ।
    আপনার পছন্দ লিখুন (1. যোগ করুন 2. সাব 3. বহু): 2
    2 নং: 10 3 লিখুন
    7
    আপনার পছন্দ লিখুন (1. যোগ 2. সাব 3. বহু): 3
    2 নম্বর: 3 6 প্রবেশ করান
    18

2

এখানে অন্যান্য ভাল উত্তর ছাড়াও একটি ভিন্ন দৃষ্টিকোণ:

সি তে, আপনি কেবল ফাংশন পয়েন্টার ব্যবহার করেন, (সরাসরি) ফাংশন নয়।

আমি বলতে চাচ্ছি, আপনি ফাংশন লিখতে, কিন্তু আপনি নাকিসুরে কথা নিপূণভাবে ফাংশন। কোনও ফাংশনের কোনও রান-টাইম উপস্থাপনা নেই যা আপনি ব্যবহার করতে সক্ষম। এমনকি আপনি "একটি ফাংশন" বলতে পারবেন না। আপনি যখন লিখবেন:

my_function(my_arg);

আপনি আসলে যা বলছেন তা হ'ল " my_functionনির্দিষ্ট যুক্তির সাহায্যে পয়েন্টারে একটি কল করা "। আপনি একটি ফাংশন পয়েন্টার মাধ্যমে কল করছেন। ফাংশন পয়েন্টারের এই ক্ষয়ের অর্থ নিম্নলিখিত কমান্ডগুলি পূর্ববর্তী ফাংশন কলের সমতুল্য:

(&my_function)(my_arg);
(*my_function)(my_arg);
(**my_function)(my_arg);
(&**my_function)(my_arg);
(***my_function)(my_arg);

এবং এইভাবেই (ধন্যবাদ @ লুভিনহফুক)।

সুতরাং, আপনি ইতিমধ্যে ফাংশন পয়েন্টারকে মান হিসাবে ব্যবহার করছেন । স্পষ্টতই আপনি সেই মানগুলির জন্য ভেরিয়েবলগুলি রাখতে চাইবেন - এবং এখানে অন্যান্য মেশনের সমস্ত ব্যবহার আসে: পলিমারফিজম / কাস্টমাইজেশন (যেমন কিউএসোর্টে), কলব্যাকস, জাম্প টেবিল ইত্যাদি

সি ++ তে জিনিসগুলি আরও জটিল, যেহেতু আমাদের কাছে ল্যাম্বডাস রয়েছে, এবং operator()একটি std::functionশ্রেণীর সাথে বস্তুও রয়েছে তবে নীতিটি এখনও বেশিরভাগ ক্ষেত্রে একই।


4
এমনকি আরো মজার ব্যাপার হচ্ছে, আপনি ফাংশন কল করতে পারেন যেমন (&my_function)(my_arg), (*my_function)(my_arg), (**my_function)(my_arg), (&**my_function)(my_arg), (***my_function)(my_arg)... কারন ফাংশন ফাংশন পয়েন্টার থেকে ক্ষয়
phuclv

1

ওও ভাষাগুলির জন্য, পর্দার পিছনে পলিমারফিক কল করা (এটি আমার ধারণা অনুমানযোগ্য সি পর্যন্তও বৈধ)।

তদুপরি, রানটাইমের সময় অন্য ফাংশনে (ফু) বিভিন্ন আচরণ ব্যবহার করতে তারা খুব দরকারী। এটি ফাংশন foo উচ্চ-অর্ডার ফাংশন করে। এটি নমনীয়তা ছাড়াও, এটি ফু কোডটি আরও পঠনযোগ্য করে তোলে এটি আপনাকে "যদি-অন্য" এর অতিরিক্ত যুক্তিটি এড়িয়ে দেয়।

এটি পাইথনের আরও অনেক দরকারী জিনিস যেমন জেনারেটর, ক্লোজার ইত্যাদি সক্ষম করে ables


0

আমি 1-বাইট অপকোডযুক্ত মাইক্রোপ্রসেসরগুলি অনুকরণের জন্য ফাংশন পয়েন্টারগুলি ব্যাপকভাবে ব্যবহার করি। 256 ফাংশন পয়েন্টারগুলির একটি অ্যারে এটি কার্যকর করার প্রাকৃতিক উপায়।


0

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


0

আমি এখানে কিছুটা বিস্তৃত তালিকা দেওয়ার চেষ্টা করব:

  • কলব্যাকস : ব্যবহারকারীর সরবরাহিত কোডের সাথে কিছু (গ্রন্থাগার) কার্যকারিতা কাস্টমাইজ করুন। প্রধান উদাহরণটি হ'ল qsort(), তবে ইভেন্টগুলি হ্যান্ডেল করার জন্যও দরকারী (কল করার পরে কলব্যাক করার জন্য বোতামের মতো) বা থ্রেড শুরু করতে প্রয়োজনীয় ( pthread_create())।

  • পলিমরফিজ্ম : একটি সি ++ ক্লাসে vtable কিছুই কিন্তু ফাংশন পয়েন্টার একটি টেবিল। এবং একটি সি প্রোগ্রাম এর কিছু বস্তুর জন্য একটি ভিটিবেল সরবরাহ করতেও পছন্দ করতে পারে:

    struct Base;
    struct Base_vtable {
        void (*destruct)(struct Base* me);
    };
    struct Base {
        struct Base_vtable* vtable;
    };
    
    struct Derived;
    struct Derived_vtable {
        struct Base_vtable;
        void (*frobnicate)(struct Derived* me);
    };
    struct Derived {
        struct Base;
        int bar, baz;
    }
    

    এর কনস্ট্রাক্টর Derivedতার vtableসদস্যের পরিবর্তনশীলকে একটি গ্লোবাল অবজেক্টের সাথে সংযুক্ত করে ডাইরেক্টের শ্রেণীর প্রয়োগ এবং এর কোড প্রয়োগ করে destructএবং frobnicateযে কোডটি নষ্ট করার দরকার ছিল struct Base*তা কেবল কল করত base->vtable->destruct(base), যা ডাস্ট্রেক্টরটির সঠিক সংস্করণকে কল করত, যার থেকে উদ্ভূত শ্রেণি baseপ্রকৃতপক্ষে নির্দেশ করে ।

    ফাংশন পয়েন্টার ছাড়াই পলিমারফিজমের মতো সুইচ কনস্ট্রাক্টসের একটি বাহিনী দিয়ে কোড করা দরকার

    switch(me->type) {
        case TYPE_BASE: base_implementation(); break;
        case TYPE_DERIVED1: derived1_implementation(); break;
        case TYPE_DERIVED2: derived2_implementation(); break;
        case TYPE_DERIVED3: derived3_implementation(); break;
    }
    

    এটি বরং অনাকাঙ্ক্ষিত হয়ে যায় বরং দ্রুত।

  • ডায়নামিকালি লোড কোড : যখন কোনও প্রোগ্রাম মেমোরিতে একটি মডিউল লোড করে এবং তার কোডটিতে কল করার চেষ্টা করে, তখন এটি অবশ্যই একটি ফাংশন পয়েন্টারটির মধ্য দিয়ে যেতে হবে।

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

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