假设我们有以下函数(在 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/