我有以下代码,我得到分段错误,因为我的函数指针指向一个函数指针数组,并且在函数指针的增量没有指向函数指针数组中的下一个元素之后。
int f2(int);
int f1(int);
int(*fp[2])(int) = {f1,f2};
int f1(int x)
{
return (x+10);
}
int f2(int y)
{
return (y+20);
}
int main() {
int sum = 0;
int (*fp1) (int);
fp1 = fp;
printf("addr of fp1 is %x\n",fp1);
++(fp1);
printf("after increment addr of fp1 is %x\n",fp1);
sum = (*fp1)(sum);
printf("%d \n",sum);
return 0;
}
但是当我使用指向函数指针的指针时:
int(** fp1)(int); 然后代码工作正常。 请告诉:
1-为什么只是函数指针不起作用。
2指向函数的指针,即fp1仅在执行++ fp1时将地址递增1。
3-当我通过fp1 = fp [0];那么它也不能同时使用指向函数的指针...以及指向函数的指针。 fp和fp [0]是否指向不同的地址?
答案 0 :(得分:5)
功能指针
递增和递减运算符对函数指针无效。
以下是C ++标准草案(N3337)中的相关文字:
5.3.2递增和递减
1前缀
++
的操作数通过添加1
进行修改,如果是true
则设置为bool
(不推荐使用此用法)。操作数应是可修改的左值。操作数的类型应为算术类型或指向完全定义的对象类型的指针。该值是操作数的新值;这是一个左值。如果x
不属于bool
类型,则表达式++x
等同于x+=1
。
指向函数的指针的类型既不是算术类型,也不是指向完全定义的对象类型的指针。因此,++
不能应用于指向函数的指针。
就C而言,C99标准(n1256)说:
6.5.3.1前缀增量和减量运算符
1前缀增量或减量运算符的操作数应具有限定或不合格的实数或指针类型,并且应为可修改的左值。
2前缀++运算符的操作数的值递增。结果是增量后操作数的新值。表达式++ E等价于(E + = 1)。有关约束,类型,副作用和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论。
和
6.5.6加法运算符
2另外,两个操作数都应具有算术类型,或者一个操作数应是指向对象类型的指针,另一个操作数应具有整数类型。 (递增相当于添加1.)
同样,由于同样的原因,指向函数的指针不能递增。
指向函数的指针数组/指向函数指针的指针
该行
int(*fp[2])(int) = {f1,f2};
声明一系列指向函数的指针。因此,表达式fp[0]
和fp[1]
是有效的表达式。您可以指向指向函数对象的指针,该指针与增量运算符一起使用。
int (**fpp)(int) = fp;
(*fpp)(10); // Calls f1(10)
fpp[0](10); // Calls f1(10)
fpp[1](10); // Calls f2(10)
++fpp;
(*fpp)(20); // Calls f2(20)
fpp[0](20); // Calls f2(20)
不幸的是,gcc 4.7.3允许编译以下语句,而g ++则没有。
int(*fp[2])(int) = {f1,f2};
int (*fpp)(int) = fp;
致电
fpp(10);
在这种情况下,会导致未定义的行为。
答案 1 :(得分:3)
fp1
定义为int (*fp1) (int);
这是 NOT 指向函数指针数组的指针。它是指向函数的指针。你无法>增加它。
但是你可以/应该增加指向数组元素的指针:
int (**fp_array)(int) = fp;
fp1 = *fp_array;
printf("addr of fp1 is %x\n",fp1);
fp1 = *(++fp_array);
printf("after increment addr of fp1 is %x\n",fp1);
但在这种情况下,这是胡说八道,为什么不简单写一下:
fp1 = fp[0];
printf("addr of fp1 is %x\n",fp1);
fp1 = fp[1];
printf("after `increment` addr of fp1 is %x\n",fp1);
答案 2 :(得分:2)
只是为了添加已经回答了问题的给定回复,我建议您输入定义函数类型:
typedef int function(int);
function* fp[] = { &f1, &f2};
function** f = fp; // array-to-pointer decay
f
现在可以按照预期的方式递增。
答案 3 :(得分:1)
您尝试做的是可能的。但是,这显然很棘手,或者你不会在这里发帖。
在数组fp中使用索引要简单得多。
int i = 0;
printf ("First result = %d\n", (* (fp [i++])) (10));
printf ("Second result = %d\n", (* (fp [i++])) (10));
这样,读取代码的人就有机会弄清楚它的作用。