c - C 中的函数指针、数组和左值

标签 c arrays pointers

假设我们有以下函数(在 C 中):

int sum(int a, int b){  
   return a+b;
}
int diff(int a, int b){
    return a-b;
}

所以我们知道我们可以通过以下方式声明一个函数指针数组:

int (*test[2]) (int a, int b);
test[0] = sum;
test[1] = diff;

但以下也是有效的(但我们使用堆分配):

int (**test) (int a, int b) = malloc( 2*sizeof(*test));
test[0] = sum;
test[1] = diff;

到目前为止一切顺利。现在让我们记住要声明一个由两个整数组成的(动态分配的)数组,我们可以这样做:

 int* test  = malloc( 2*sizeof(int));

那么为什么我们不能将函数指针数组声明为

int (*test) (int a, int b) = malloc( 2*sizeof(*test)); ?

是因为 test 与 *test**test (等等)相同,malloc( 2*sizeof (*test)) 正在返回指向函数指针的指针,因此不能将其分配给 (*test) ?

如果这个假设是正确的,你能详细解释一下编译错误的原因吗

error: lvalue required as left operand of assignment

当我们尝试做的时候

int (*test) (int a, int b) = malloc( 2*sizeof(*test));
test=diff; //<--- This is ok.
test+1 = sum; //<--- This is what gives the error!

免责声明:我想这是一个基本问题,假设是正确的,但我想要一个更好的解释,让这种事情一劳永逸。


编辑:

注意这等同于

int (*test) (int a, int b) = malloc( 2*sizeof(*test));
*test=*diff; //<--- This is ok.
*(test+1) = *sum; //<--- This is what gives the error!

因为这更类似于这种情况:

int *test = malloc(2*sizeof(*test));
*test = 0;
*(test+1) = 1;

最佳答案

So why we cannot declare an array of function pointers as

int (*test) (int a, int b) = malloc( 2*sizeof(*test));

因为test没有指向一个函数指针;它一个函数指针。因此它不能指向函数指针数组的第一个元素。

如果你想要一个函数指针数组,使用之前的形式:

int (**test) (int a, int b) = malloc( 2*sizeof(*test));

这里,*test 具有函数指针类型,因此 test 可以(并且确实)指向函数指针数组的第一个元素。进一步:

error: lvalue required as left operand of assignment

when we try to do

 int (*test) (int a, int b) = malloc( 2*sizeof(*test));
 test=diff; //<--- This is ok.
 test+1 = sum; //<--- This is what gives the error!

无论 test 是什么类型,test+1=anything 总是无效的 C。test+1 永远不可能是左值。我不明白为什么你会期望它起作用。

GCC 还掩盖了您程序中的另一个错误,sizeof(*test)。因为 *test 有函数类型,所以 sizeof(*test) 是无效的,但是 GCC 默默地给它赋值 1。这导致为函数指针分配的内存太少,但这并不重要,因为在下一行中,您丢弃了从 malloc 获得的内存,并将其他内容分配给 test

关于c - C 中的函数指针、数组和左值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33762275/

相关文章:

arrays - 用于查找自定义类型索引的数组扩展

c - 访问结构内数组中的数据时出错

c - 在 C/C++ 中使用计数器变量访问字符串

c++ - 当从父类(super class)的指针调用时,基类函数不会覆盖父类(super class)函数

c - 如何对我的数据进行排序?

CS50 恢复段错误问题

c - 在 C 程序和 shell 脚本之间共享头文件

c - 我想了解 C 中的 malloc() 和 realloc()

c - B 和 *B 如何在 C 中返回相同的地址?

c - GCC 错误、错误代码或 gcc 是好的编译器