C中的函数指针,数组和左值

时间:2015-11-17 16:34:51

标签: 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相同(等等),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;

1 个答案:

答案 0 :(得分:11)

  

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

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
     

当我们尝试做的时候

 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