এই ওয়েবসাইটটি Google Analytics এবং Google Adsense এবং Giscus ব্যবহার করে। আমাদের পড়ুন
শর্তাবলী এবং গোপনীয়তা নীতি
প্রকাশিত

সি-তে ফাংশন পয়েন্টার - ইন্টারমিডিয়েট সি কনসেপ্টস পার্ট ৭

লেখক
লেখক
  • avatar
    নাম
    মো: নাসিম শেখ
    টুইটার
    টুইটার
    @nasimStg

ডেটা ছাড়িয়ে: সি-তে Function Pointer বোঝা এবং ব্যবহার করা

"ইন্টারমিডিয়েট সি কনসেপ্টস সিরিজ" সিরিজে আপনাকে আবার স্বাগতম! আমরা dynamic memory, linked list, stack, queue, tree, graph, এবং even bitwise operation এর intricacy এর মাধ্যমে যাত্রা করেছি। এখন, আমরা সি-এর একটি truly powerful এবং প্রায়শই misunderstood feature explore করতে চলেছি: function pointer

সি-তে, pointer গুলি কেবল variable গুলোর memory address ধারণ করার মধ্যে limited নয়। তারা function গুলিতেও point করতে পারে, যা আপনাকে functions কে data হিসাবে treat করার অনুমতি দেয়। এটি আরও flexible, dynamic, এবং elegant code লেখার জন্য possibilities এর একটি বিশ্ব খুলে দেয়। function pointer callback, generic algorithm তৈরি, এবং আরও modular software design করার key।

এটিকে এভাবে ভাবুন: ঠিক যেমন একটি regular pointer memory তে একটি variable এর address ধারণ করে, তেমনি একটি function pointer memory তে একটি function এর code এর starting address ধারণ করে। এই আপাতদৃষ্টিতে simple concept আপনার সি প্রোগ্রামগুলি কীভাবে structure এবং execute করেন তার জন্য profound implication আছে।

সুচিপত্র

চলুন সি-তে function pointer define, assign, এবং use কিভাবে করতে হয় তার বিস্তারিত আলোচনা করি।

ফাংশন পয়েন্টার define করা: সিনট্যাক্স

একটি function pointer declare করার সিনট্যাক্স প্রথমে কিছুটা unusual লাগতে পারে, কিন্তু একবার আপনি এটিকে break down করলে, এটি বেশ logical হয়ে ওঠে। এখানে general form:

return_type (*pointer_name)(parameter_list);

চলুন প্রতিটি অংশ break down করি:

  • return_type: এটি হলো data type যা এই pointer দ্বারা pointed function return করবে।
  • *: asterisk indicate করে যে আপনি একটি pointer declare করছেন।
  • pointer_name: এটি হলো আপনার function pointer variable এর জন্য আপনি যে নাম select করেন।
  • parameter_list: এটি specify করে parameter এর type এবং number যা এই pointer দ্বারা pointed function accept করতে হবে।

উদাহরণ:

ধরুন আপনার কাছে একটি function আছে যা দুটি integer নেয় এবং একটি integer return করে:

int add(int a, int b) {
  return a + b;
}

এই add function এ point করতে পারে এমন একটি function pointer declare করতে, আপনি লিখবেন:

int (*ptr_to_add)(int, int);

এখানে, ptr_to_add হলো একটি pointer যা দুটি integer argument হিসাবে নেয় এবং একটি integer return করে এমন যেকোনো function এ point করতে পারে।

Function গুলিকে Function Pointer এ Assign করা

একবার আপনি একটি function pointer declare করার পর, আপনি একটি function এর address এটিতে assign করতে পারেন। যখন আপনি parentheses ছাড়া একটি function এর নাম ব্যবহার করেন, এটি implicitly সেই function এর একটি pointer এ decay হয়।

উদাহরণ (পূর্ববর্তী উদাহরণ থেকে continuant):

#include <stdio.h>

int add(int a, int b) {
  return a + b;
}

int main() {
  int (*ptr_to_add)(int, int); // function pointer declare করুন

  ptr_to_add = add; // 'add' function এর address pointer এ assign করুন

  printf("Address of add function: %p\n", (void *)add);
  printf("Value of ptr_to_add: %p\n", (void *)ptr_to_add);

  return 0;
}

output থেকে যেমন আপনি দেখতে পাচ্ছেন, add এবং ptr_to_add উভয়ই একই memory address ধারণ করে (যদিও আপনার system এর উপর নির্ভর করে আপনি সামান্য ভিন্ন representation দেখতে পারেন)।

Function Pointer এর মাধ্যমে Functions Calling

এখন যেহেতু আপনার function pointer একটি function এর address ধারণ করে, আপনি সেই function কে call করতে এটি ব্যবহার করতে পারেন। এটি করার দুটি common way আছে:

১.  pointer name সরাসরি ব্যবহার করে: আপনি function pointer variable কে function name itself এর মতো treat করতে পারেন। ২.  dereference operator (*) ব্যবহার করে: আপনি call করার আগে pointer কে explicitly dereference করতে পারেন।

উভয় method একই result অর্জন করে।

উদাহরণ:

#include <stdio.h>

int add(int a, int b) {
  return a + b;
}

int main() {
  int (*ptr_to_add)(int, int) = add; // declare এবং initialize করুন

  int sum1 = ptr_to_add(5, 3); // pointer এর মাধ্যমে সরাসরি calling করা
  int sum2 = (*ptr_to_add)(10, 2); // dereferenced pointer এর মাধ্যমে calling করা

  printf("Sum 1: %d\n", sum1); // Output: Sum 1: 8
  printf("Sum 2: %d\n", sum2); // Output: Sum 2: 12

  return 0;
}

যেমন আপনি দেখতে পাচ্ছেন, pointer এর মাধ্যমে function call করার উভয় উপায় সঠিকভাবে কাজ করে। প্রথম method (ptr_to_add(5, 3)) সাধারণত আরও readable হিসাবে বিবেচিত হয়।

Argument হিসাবে Function Pointer: Callbacks

function pointer এর সবচেয়ে শক্তিশালী অ্যাপ্লিকেশনগুলির মধ্যে একটি হলো argument হিসাবে অন্যান্য function গুলিতে pass করার ability। এটি আপনাকে এমন function তৈরি করার অনুমতি দেয় যা তাদের গ্রহণ করা function pointer এর উপর নির্ভর করে বিভিন্ন action perform করতে পারে। এই concept টি callbacks নামে পরিচিত।

ভাবুন আপনি একটি generic sorting function লিখতে চান যা integers এর একটি array ascending বা descending order এ sort করতে পারে। আপনি আপনার sorting function এ একটি comparison function pointer pass করে এটি অর্জন করতে পারেন।

উদাহরণ:

#include <stdio.h>
#include <stdlib.h>

// ascending order এর জন্য comparison function
int compareAscending(const void *a, const void *b) {
  return (*(int*)a - *(int*)b);
}

// descending order এর জন্য comparison function
int compareDescending(const void *a, const void *b) {
  return (*(int*)b - *(int*)a);
}

// comparison এর জন্য function pointer ব্যবহার করে generic sorting function
void sortArray(int arr[], int size, int (*compare)(const void *, const void *)) {
  qsort(arr, size, sizeof(int), compare);
}

int main() {
  int numbers[] = {5, 2, 8, 1, 9, 4};
  int size = sizeof(numbers) / sizeof(numbers[0]);

  printf("Original array: ");
  for (int i = 0; i < size; i++) {
    printf("%d ", numbers[i]);
  }
  printf("\n");

  // ascending order এ sort করুন
  sortArray(numbers, size, compareAscending);
  printf("Sorted in ascending order: ");
  for (int i = 0; i < size; i++) {
    printf("%d ", numbers[i]);
  }
  printf("\n");

  // descending order এ sort করুন
  sortArray(numbers, size, compareDescending);
  printf("Sorted in descending order: ");
  for (int i = 0; i < size; i++) {
    printf("%d ", numbers[i]);
  }
  printf("\n");

  return 0;
}

এই উদাহরণে, sortArray function একটি argument হিসাবে একটি function pointer compare নেয়। আপনি compareAscending বা compareDescending pass করেন কিনা তার উপর নির্ভর করে, array টি respective order এ sort হবে। এটি flexible এবং reusable code তৈরির জন্য function pointer ব্যবহার করার শক্তি demonstrate করে।

Function Pointer এর Array

আপনি function pointer এর array ও তৈরি করতে পারেন। এটি menu-driven program বা dispatch table এর মতো জিনিস implement করার জন্য useful হতে পারে যেখানে আপনি কিছু input এর উপর ভিত্তি করে একটি specific function select এবং execute করতে চান।

উদাহরণ:

#include <stdio.h>

int operation1(int a, int b) {
  printf("Performing operation 1: ");
  return a + b;
}

int operation2(int a, int b) {
  printf("Performing operation 2: ");
  return a - b;
}

int main() {
  int (*operations[2])(int, int); // দুটি function pointer এর array

  operations[0] = operation1;
  operations[1] = operation2;

  int choice = 0; // ধরুন ব্যবহারকারী operation 1 select করেছেন

  int result = operations[choice](10, 5);
  printf("%d\n", result); // Output: Performing operation 1: 15

  choice = 1; // এখন ব্যবহারকারী operation 2 select করেছেন

  result = operations[choice](10, 5);
  printf("%d\n", result); // Output: Performing operation 2: 5

  return 0;
}

এখানে, operations হলো একটি array যেখানে প্রতিটি element হলো একটি function pointer যা দুটি integer নেয় এবং একটি integer return করে এমন একটি function এ point করতে পারে।

Function Pointer এর সাথে typedef ব্যবহার করা

Function pointer declare করার সিনট্যাক্স কিছুটা cumbersome হতে পারে, বিশেষ করে complex function signature deal করার সময়। typedef keyword ব্যবহার করে function pointer type এর জন্য একটি alias তৈরি করা যেতে পারে, যা আপনার code কে cleaner এবং আরও readable করে তোলে।

উদাহরণ:

#include <stdio.h>

typedef int (*BinaryOperation)(int, int); // একটি type alias define করুন

int add(int a, int b) {
  return a + b;
}

int subtract(int a, int b) {
  return a - b;
}

int main() {
  BinaryOperation ptr_add = add;
  BinaryOperation ptr_subtract = subtract;

  printf("Addition: %d\n", ptr_add(7, 3)); // Output: Addition: 10
  printf("Subtraction: %d\n", ptr_subtract(10, 4)); // Output: Subtraction: 6

  return 0;
}

typedef ব্যবহার করে function pointer variable declare করা অনেক simpler করে তোলে।

উপসংহার: Function Pointer এর Flexibility গ্রহণ করা

Function pointer সি প্রোগ্রামারের arsenal এ একটি শক্তিশালী tool। তারা function গুলিকে data হিসাবে treat করে আপনাকে আরও dynamic, flexible, এবং reusable code লিখতে অনুমতি দেয়। Function pointer বোঝা এবং কার্যকরভাবে ব্যবহার করা advanced C programming technique আয়ত্ত করার দিকে একটি significant step। Callback implement করা থেকে generic algorithm তৈরি করা পর্যন্ত, possibilities vast।

"ইন্টারমিডিয়েট সি কনসেপ্টস" সিরিজের আমাদের পরবর্তী installment এ, আমরা অন্য একটি exciting topic এ delve করব যা আমরা স্থাপন করেছি foundation গুলোর উপর build করে। Stay tuned!

পরামর্শ:

এই পোস্টে আলোচিত ধারণাগুলি আরও enhance করার জন্য, আমাদের ব্লগের নিম্নলিখিত article গুলি আপনার জন্য সহায়ক হতে পারে:

  • সি-তে শুরু করা: পার্ট ৬ - সি-তে পয়েন্টার: মেমরি ম্যানেজমেন্ট বোঝা: এই পোস্টটি সি-তে pointer এর fundamental knowledge প্রদান করে, যা function pointer ধারণা grasp করার জন্য essential।     * সি-তে পয়েন্টার
  • ইন্টারমিডিয়েট সি কনসেপ্টস: পার্ট ১ - সি-তে ডাইনামিক মেমরি অ্যালোকেশন: Custom memory allocator implement করার সময় বা dynamically created data structure deal করার সময় function pointer প্রায়শই dynamic memory management জড়িত scenario গুলিতে ব্যবহৃত হয়।     * সি-তে ডাইনামিক মেমরি অ্যালোকেশন
  • ইন্টারমিডিয়েট সি কনসেপ্টস: পার্ট ৩ - সি-তে Stack এবং Queue Implement করা: আপনি এমন situation encounter করতে পারেন যেখানে function pointer stack বা queue operation এর behavior customize করতে ব্যবহার করা যেতে পারে।     * সি-তে Stack এবং Queue Implement করা

আমরা আশা করি সি-তে function pointer এর এই বিস্তারিত explanation টি insightful ছিল। আপনার কোন প্রশ্ন থাকলে বা function pointer নিয়ে আপনার experience শেয়ার করতে চাইলে, নিচে comment করতে free feel করুন!