我如何使用函数指针数组?

141 c initialization function-pointers

我应该如何在C中使用函数指针数组?

我该如何初始化它们?

Von*_*onC 184

你有一个很好的例子(函数指针数组),语法详细.

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() */
[...]
Run Code Online (Sandbox Code Playgroud)

要调用其中一个函数指针:

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

  • 我想补充一下你可以用`(*p [4])(int,int){sum,substract,mul,div}初始化p` (11认同)
  • 很好的答案 - 你应该扩展它以显示如何调用其中一个函数. (2认同)
  • @crucifiedsoul 由 Brian Kernighan 和 Dennis Ritchie 编写的“C 编程语言”?可能是,但我在三年半前写答案的时候没有它作为参考。所以我不知道。 (2认同)
  • @VonC:很好的答案。+1 为链接。 (2认同)

Man*_*bts 37

以上答案可能对您有所帮助,但您可能也想知道如何使用函数指针数组.

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;
}
Run Code Online (Sandbox Code Playgroud)

您只能将具有相同返回类型和相同参数类型且没有参数的函数的地址分配给单个函数指针数组.

如果所有上述函数具有相同数量的相同类型的参数,您也可以传递如下所示的参数.

  (*func_ptr[option])(argu1);
Run Code Online (Sandbox Code Playgroud)

注意:在数组中,函数指针的编号将从0开始,与一般数组相同.因此,fun1如果option = 0,fun2可以调用上面的示例,如果option = 1 fun3则可以调用,如果option = 2则可以调用.

  • 这是一个很好的答案,但是你应该在(*func_ptr [3])之后添加括号以使其成为有效的代码. (6认同)

Ras*_*yak 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
Run Code Online (Sandbox Code Playgroud)

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");
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

我希望这有助于理解 Function Pointer.


M.M*_*M.M 5

这个"答案"更像是VonC答案的附录; 只是注意到可以通过typedef简化语法,并且可以使用聚合初始化:

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; }
Run Code Online (Sandbox Code Playgroud)

  • 请保留预处理器宏的所有上限。许多人还提倡创建的类型以“_t”结尾,尽管这对于用户定义的类型似乎存在争议。 (2认同)

Ale*_*nal 5

下面是如何执行此操作的一个更简单的示例:

跳转表.c

int func1(int arg)  { return arg + 1; }
int func2(int arg)  { return arg + 2; }
int func3(int arg)  { return arg + 3; }
int func4(int arg)  { return arg + 4; }
int func5(int arg)  { return arg + 5; }
int func6(int arg)  { return arg + 6; }
int func7(int arg)  { return arg + 7; }
int func8(int arg)  { return arg + 8; }
int func9(int arg)  { return arg + 9; }
int func10(int arg) { return arg + 10; }

int (*jump_table[10])(int) = { func1, func2, func3, func4, func5, 
                               func6, func7, func8, func9, func10 };
    
int main(void) {
  int index = 2;
  int argument = 42;
  int result = (*jump_table[index])(argument);
  // result is 45
}
Run Code Online (Sandbox Code Playgroud)

存储在数组中的所有函数必须具有相同的签名。这仅仅意味着它们必须返回相同的类型(例如)并具有相同的参数(上面示例中的int单个参数)。int


在 C++ 中,您可以对静态类方法(但不能是实例方法)执行相同的操作。例如,您可以MyClass::myStaticMethod在上面的数组中使用,但不能MyClass::myInstanceMethod在nor中使用instance.myInstanceMethod

class MyClass {
public:
  static int myStaticMethod(int foo)   { return foo + 17; }
  int        myInstanceMethod(int bar) { return bar + 17; }
}

MyClass instance;
Run Code Online (Sandbox Code Playgroud)