打印函数指针时出现不兼容的指针类型警告

laf*_*ffy 2 c arrays function-pointers declaration function-call

我正在尝试创建一个函数指针数组,以便我可以使用指针打印函数的输出。(来自《Effective C》一书的练习。)

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

int a(void) { return 1; }
int b(void) { return 2; }
int c(void) { return 3; }

int main(void)
{

    int(*func_arr)[3] = {&a, &b, &c};
    printf("%d\n", (*func_arr)[0]);
}
Run Code Online (Sandbox Code Playgroud)

但是,当我编译它时,我收到警告

starting.c:10:26: warning: incompatible pointer types initializing 'int (*)[3]' with an expression of type
      'int (*)(void)' [-Wincompatible-pointer-types]
    int(*func_arr)[3] = {&a, &b, &c};
                         ^~
starting.c:10:30: warning: excess elements in scalar initializer
    int(*func_arr)[3] = {&a, &b, &c};
                             ^~
Run Code Online (Sandbox Code Playgroud)

而且,当我运行该程序时,我得到的输出为 -443987883,而它应该只是 1。

有谁知道这个问题的解决方案?谢谢你!

Vla*_*cow 6

本声明

int(*func_arr)[3] = {&a, &b, &c};
Run Code Online (Sandbox Code Playgroud)

声明一个指向数组类型的指针int[3]

因此,声明了一个指针类型的标量对象,您尝试使用大括号括起来的初始值设定项列表来初始化该对象,其中包含多个不兼容指针类型的初始值设定项。

相反,你需要写

int ( *func_arr[3] )( void ) = { a, b, c };
Run Code Online (Sandbox Code Playgroud)

用作初始值设定项的函数指示符会隐式转换为指向函数的指针。&a因此,尽管这样的表达式也可以有效地用作初始值设定项,但无需编写为 example 。

为了简化数组声明,您可以为函数指针类型引入一个类型化名称。

例如

typedef int ( *FnPtr )( void );
Run Code Online (Sandbox Code Playgroud)

现在数组声明可以如下所示

FnPtr func_arr[3] = { a, b, c };
Run Code Online (Sandbox Code Playgroud)

要输出函数调用的结果,您需要编写printf类似的调用

printf("%d\n", func_arr[0]() );
Run Code Online (Sandbox Code Playgroud)