আমি কীভাবে ফাংশন পয়েন্টারগুলির একটি অ্যারে ব্যবহার করতে পারি?


উত্তর:


194

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

int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);

int (*p[4]) (int x, int y);

int main(void)
{
  int result;
  int i, j, op;

  p[0] = sum; /* address of sum() */
  p[1] = subtract; /* address of subtract() */
  p[2] = mul; /* address of mul() */
  p[3] = div; /* address of div() */
[...]

এই ফাংশন পয়েন্টারগুলির মধ্যে একটিকে কল করতে:

result = (*p[op]) (i, j); // op being the index of one of the four functions

3
ভাল উত্তর - যদিও আপনাকে কোনও ক্রিয়াকলাপ কল করতে হবে তা দেখানোর জন্য এটি বাড়ানো উচিত।
জোনাথন লেফলার

1
ব্রাউন কার্নিগান এবং ডেনিস রিচি রচিত @ ক্রুসিফাইডসল "দ্য সি প্রোগ্রামিং ল্যাঙ্গুয়েজ"? এটি হতে পারে তবে সাড়ে তিন বছর আগে উত্তরটি লেখার সময় আমার কাছে রেফারেন্স হিসাবে এটি ছিল না। সুতরাং আমি জানি না।
ভোনসি

12
আমি যোগ করতে সঙ্গে আপনি পি আরম্ভ করতে পারেন চাই(*p[4]) (int, int) {sum,substract,mul,div}
jiggunjer

1
@ ভনসি: দুর্দান্ত উত্তর। লিঙ্কগুলির জন্য +1।
ধ্বংসকারী

@ জিগগুনজার এস / সাবস্ট্রাক্ট / সাবট্র্যাক্ট /: পি। তবে এই মন্তব্যের জন্য ধন্যবাদ, খুব দরকারী :) :) +1 টি।
রাস্তাজেদি

41

উপরের উত্তরগুলি আপনাকে সহায়তা করতে পারে তবে আপনি কীভাবে ফাংশন পয়েন্টারগুলির অ্যারে ব্যবহার করবেন তাও জানতে চাইতে পারেন।

void fun1()
{

}

void fun2()
{

}

void fun3()
{

}

void (*func_ptr[3])() = {fun1, fun2, fun3};

main()
{
    int option;


    printf("\nEnter function number you want");
    printf("\nYou should not enter other than 0 , 1, 2"); /* because we have only 3 functions */
    scanf("%d",&option);

    if((option>=0)&&(option<=2))
    { 
        (*func_ptr[option])();
    }

    return 0;
}

আপনি কেবল একই ফিরতি টাইপ এবং একই আর্গুমেন্ট প্রকার এবং একটি একক ফাংশন পয়েন্টার অ্যারেতে কোনও আর্গুমেন্টের সাথে ফাংশনের ঠিকানাগুলি নির্ধারণ করতে পারেন।

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

  (*func_ptr[option])(argu1);

দ্রষ্টব্য: এখানে অ্যারেতে ফাংশন পয়েন্টারগুলির সংখ্যায়ন সাধারণ অ্যারে হিসাবে 0 থেকে শুরু হবে। সুতরাং উপরের উদাহরণে fun1অপশন = 0 fun2বলা যেতে পারে , বিকল্প = 1 fun3বলা যেতে পারে এবং অপশন = 2 বলা যেতে পারে।


এমনকি এই ছোট্ট ডেমোটির জন্যও আপনার ইনপুট মানটির জন্য একটি চেক যুক্ত করা উচিত, যেহেতু কোডটি কোনও
নবাগতকে

যদি ((বিকল্প <0) || (বিকল্প> 2)) {(* ফানক_পিটার [বিকল্প]) (); Ude ডুড মানে এর অর্থ কেবল তখনই বলা হয় যখন ব্যবহারকারী কোনও অবৈধ সূচীতে টাইপ করে!
ljs

6
এটি একটি ভাল উত্তর, তবে আপনার বৈধ কোড তৈরি করার জন্য (* func_ptr [3]) এর পরে প্রথম বন্ধনী যুক্ত করা উচিত।
অ্যালেক্স

এটি মারাত্মক খারাপ উত্তর is অনুপস্থিত বন্ধনীগুলির কারণে, এই কোডটি সংকলন করে না
সিএল

মত @Alex বললেন, শুধু থেকে এটি পরিবর্তন (*func_ptr[3])করতে (*func_ptr[3])()এবং এটি কম্পাইল হবে
dsaydon

9

আপনি এটি কীভাবে ব্যবহার করতে পারেন তা এখানে:

New_Fun.h

#ifndef NEW_FUN_H_
#define NEW_FUN_H_

#include <stdio.h>

typedef int speed;
speed fun(int x);

enum fp {
    f1, f2, f3, f4, f5
};

void F1();
void F2();
void F3();
void F4();
void F5();
#endif

New_Fun.c

#include "New_Fun.h"

speed fun(int x)
{
    int Vel;
    Vel = x;
    return Vel;
}

void F1()
{
    printf("From F1\n");
}

void F2()
{
    printf("From F2\n");
}

void F3()
{
    printf("From F3\n");
}

void F4()
{
    printf("From F4\n");
}

void F5()
{
    printf("From F5\n");
}

Main.c

#include <stdio.h>
#include "New_Fun.h"

int main()
{
    int (*F_P)(int y);
    void (*F_A[5])() = { F1, F2, F3, F4, F5 };    // if it is int the pointer incompatible is bound to happen
    int xyz, i;

    printf("Hello Function Pointer!\n");
    F_P = fun;
    xyz = F_P(5);
    printf("The Value is %d\n", xyz);
    //(*F_A[5]) = { F1, F2, F3, F4, F5 };
    for (i = 0; i < 5; i++)
    {
        F_A[i]();
    }
    printf("\n\n");
    F_A[f1]();
    F_A[f2]();
    F_A[f3]();
    F_A[f4]();
    return 0;
}

আমি আশা করি এটি বুঝতে সহায়তা করে Function Pointer.


মেইন.কমের 15 লাইনটি (i = 0; i <5; i ++) এর জন্য হওয়া উচিত, তাই না?
user3116936

আপনি এফপি গণক ঘোষণা করলেন কেন?
অ্যারো

@ অ্যারো: আমি মনে করি আমি উত্তরাধিকারের কোডটি দেখেছি যেখানে তারা সেভাবে তৈরি করেছে ... এবং এটি দেখতে খুব সুন্দর দেখাচ্ছে। কেবল সরিয়ে ফেলুন f1, f2 ...এবং তারপরে 'রাইটফিল, রিডফ্রোমফায়াল ...' এ প্রবেশ করুন ... এটি আরও পুনরায় পরিবর্তনযোগ্য হয়ে যায়
রাসমি রঞ্জন নায়ক

5

এই "উত্তর" ভনসির উত্তরের আরও সংযোজন; কেবলমাত্র লক্ষণীয় যে সিন্ডেক্সটি টাইপএফের মাধ্যমে সহজতর করা যায় এবং সামগ্রিক সূচনাটি ব্যবহার করা যেতে পারে:

typedef int FUNC(int, int);

FUNC sum, subtract, mul, div;
FUNC *p[4] = { sum, subtract, mul, div };

int main(void)
{
    int result;
    int i = 2, j = 3, op = 2;  // 2: mul

    result = p[op](i, j);   // = 6
}

// maybe even in another file
int sum(int a, int b) { return a+b; }
int subtract(int a, int b) { return a-b; }
int mul(int a, int b) { return a*b; }
int div(int a, int b) { return a/b; }

2

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

এখানে যেমন gtk_button স্টাফের সূচনা।


static void
gtk_button_class_init (GtkButtonClass *klass)
{
  GObjectClass *gobject_class;
  GtkObjectClass *object_class;
  GtkWidgetClass *widget_class;
  GtkContainerClass *container_class;

  gobject_class = G_OBJECT_CLASS (klass);
  object_class = (GtkObjectClass*) klass;
  widget_class = (GtkWidgetClass*) klass;
  container_class = (GtkContainerClass*) klass;

  gobject_class->constructor = gtk_button_constructor;
  gobject_class->set_property = gtk_button_set_property;
  gobject_class->get_property = gtk_button_get_property;

এবং gtkobject.h এ আপনি নিম্নলিখিত ঘোষণাগুলি খুঁজে পান:


struct _GtkObjectClass
{
  GInitiallyUnownedClass parent_class;

  /* Non overridable class methods to set and get per class arguments */
  void (*set_arg) (GtkObject *object,
           GtkArg    *arg,
           guint      arg_id);
  void (*get_arg) (GtkObject *object,
           GtkArg    *arg,
           guint      arg_id);

  /* Default signal handler for the ::destroy signal, which is
   *  invoked to request that references to the widget be dropped.
   *  If an object class overrides destroy() in order to perform class
   *  specific destruction then it must still invoke its superclass'
   *  implementation of the method after it is finished with its
   *  own cleanup. (See gtk_widget_real_destroy() for an example of
   *  how to do this).
   */
  void (*destroy)  (GtkObject *object);
};

(* সেট_আরগ) স্টাফটি কাজ করার জন্য একটি পয়েন্টার এবং এটি উদাহরণস্বরূপ কিছু উত্সযুক্ত শ্রেণিতে অন্য বাস্তবায়ন বরাদ্দ করা যেতে পারে।

প্রায়শই আপনি এরকম কিছু দেখতে পান

struct function_table {
   char *name;
   void (*some_fun)(int arg1, double arg2);
};

void function1(int  arg1, double arg2)....


struct function_table my_table [] = {
    {"function1", function1},
...

সুতরাং আপনি নাম অনুসারে সারণিতে পৌঁছাতে এবং "সম্পর্কিত" ফাংশনটি কল করতে পারেন।

অথবা হতে পারে আপনি একটি হ্যাশ টেবিল ব্যবহার করেছেন যাতে আপনি ফাংশনটি রেখেছেন এবং এটিকে "নাম দিয়ে" ডাকবেন।

শুভেচ্ছা
ফ্রিডরিচ


হ্যাশ টেবিল প্রয়োগের মধ্যেই হ্যাশিং ফাংশনগুলির জন্য এই জাতীয় ফাংশন_ টেবিলটি ব্যবহার করা প্রশ্রয়জনক হবে? (পড়ুন: বিজ্ঞপ্তি নির্ভরশীল জড়িত)।
ফ্ল্যাভিয়াস

2

এটি এইভাবে ব্যবহার করতে পারেন:

//! Define:
#define F_NUM 3
int (*pFunctions[F_NUM])(void * arg);

//! Initialise:
int someFunction(void * arg) {
    int a= *((int*)arg);
    return a*a;
}

pFunctions[0]= someFunction;

//! Use:
int someMethod(int idx, void * arg, int * result) {
    int done= 0;
    if (idx < F_NUM && pFunctions[idx] != NULL) {
        *result= pFunctions[idx](arg);
        done= 1;
    }
    return done;
}

int x= 2;
int z= 0;
someMethod(0, (void*)&x, &z);
assert(z == 4);

1

এটি উপরের প্রতিক্রিয়াগুলির কোড উদাহরণের একটি সংক্ষিপ্ত এবং সাধারণ অনুলিপি এবং পেস্ট হওয়া উচিত। আশা করি এটি সাহায্য করবে।

#include <iostream>
using namespace std;

#define DBG_PRINT(x) do { std::printf("Line:%-4d" "  %15s = %-10d\n", __LINE__, #x, x); } while(0);

void F0(){ printf("Print F%d\n", 0); }
void F1(){ printf("Print F%d\n", 1); }
void F2(){ printf("Print F%d\n", 2); }
void F3(){ printf("Print F%d\n", 3); }
void F4(){ printf("Print F%d\n", 4); }
void (*fArrVoid[N_FUNC])() = {F0, F1, F2, F3, F4};

int Sum(int a, int b){ return(a+b); }
int Sub(int a, int b){ return(a-b); }
int Mul(int a, int b){ return(a*b); }
int Div(int a, int b){ return(a/b); }
int (*fArrArgs[4])(int a, int b) = {Sum, Sub, Mul, Div};

int main(){
    for(int i = 0; i < 5; i++)  (*fArrVoid[i])();
    printf("\n");

    DBG_PRINT((*fArrArgs[0])(3,2))
    DBG_PRINT((*fArrArgs[1])(3,2))
    DBG_PRINT((*fArrArgs[2])(3,2))
    DBG_PRINT((*fArrArgs[3])(3,2))

    return(0);
}

যদি এটি অন্য অন্বরের কোনও অনুলিপি এবং আটকানো হয় তবে আমি নিশ্চিত নই যে এটির কোনও মূল্য যুক্ত হয়েছে ...
ফ্যাবিও মনিকা 22

হ্যাঁ আমি আপনার বক্তব্যটি দেখতে পাচ্ছি, আমি বর্তমানে রাতের কাজটিতে মানটি যুক্ত করব।
নিমিম 18

1

সবচেয়ে সহজ সমাধানটি হ'ল আপনি চান চূড়ান্ত ভেক্টরের ঠিকানা দেওয়া এবং এটি ফাংশনের অভ্যন্তরে সংশোধন করা।

void calculation(double result[] ){  //do the calculation on result

   result[0] = 10+5;
   result[1] = 10 +6;
   .....
}

int main(){

    double result[10] = {0}; //this is the vector of the results

    calculation(result);  //this will modify result
}

0

এই প্রশ্নের ইতিমধ্যে খুব ভাল উদাহরণ দিয়ে উত্তর দেওয়া হয়েছে। একমাত্র উদাহরণ যা অনুপস্থিত হতে পারে এটি হ'ল ফাংশনগুলি পয়েন্টারগুলি দেয়। আমি এটির সাথে আরও একটি উদাহরণ লিখেছি এবং প্রচুর মন্তব্য যুক্ত করেছি, যদি কেউ এটির সহায়ক মনে করে:

#include <stdio.h>

char * func1(char *a) {
    *a = 'b';
    return a;
}

char * func2(char *a) {
    *a = 'c';
    return a;
}

int main() {
    char a = 'a';
    /* declare array of function pointers
     * the function pointer types are char * name(char *)
     * A pointer to this type of function would be just
     * put * before name, and parenthesis around *name:
     *   char * (*name)(char *)
     * An array of these pointers is the same with [x]
     */
    char * (*functions[2])(char *) = {func1, func2};
    printf("%c, ", a);
    /* the functions return a pointer, so I need to deference pointer
     * Thats why the * in front of the parenthesis (in case it confused you)
     */
    printf("%c, ", *(*functions[0])(&a)); 
    printf("%c\n", *(*functions[1])(&a));

    a = 'a';
    /* creating 'name' for a function pointer type
     * funcp is equivalent to type char *(*funcname)(char *)
     */
    typedef char *(*funcp)(char *);
    /* Now the declaration of the array of function pointers
     * becomes easier
     */
    funcp functions2[2] = {func1, func2};

    printf("%c, ", a);
    printf("%c, ", *(*functions2[0])(&a));
    printf("%c\n", *(*functions2[1])(&a));

    return 0;
}

0

ফাংশন পয়েন্টার সহ বহুমাত্রিক অ্যারেটির এই সাধারণ উদাহরণ ":

void one( int a, int b){    printf(" \n[ ONE ]  a =  %d   b = %d",a,b);}
void two( int a, int b){    printf(" \n[ TWO ]  a =  %d   b = %d",a,b);}
void three( int a, int b){    printf("\n [ THREE ]  a =  %d   b = %d",a,b);}
void four( int a, int b){    printf(" \n[ FOUR ]  a =  %d   b = %d",a,b);}
void five( int a, int b){    printf(" \n [ FIVE ]  a =  %d   b = %d",a,b);}
void(*p[2][2])(int,int)   ;
int main()
{
    int i,j;
    printf("multidimensional array with function pointers\n");

    p[0][0] = one;    p[0][1] = two;    p[1][0] = three;    p[1][1] = four;
    for (  i  = 1 ; i >=0; i--)
        for (  j  = 0 ; j <2; j++)
            (*p[i][j])( (i, i*j);
    return 0;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.