我只是在学习C ++中的函数指针。以下示例都编译并返回预期结果,但我被告知示例3是要走的路。为什么其他例子仍然有效?
还有另一件似乎很奇怪的例子是f,g,h,i
,与上面的例子形成对比并不全都有效。与示例1-8相比,它们为什么不起作用?
int executeOperator1(int a, int b, int f(int,int)){
return f(a,b);
}
int executeOperator2(int a, int b, int f(int,int)){
return (*f)(a,b);
}
int executeOperator3(int a, int b, int (*f)(int,int)){
return f(a,b);
}
int executeOperator4(int a, int b, int (*f)(int,int)){
return (*f)(a,b);
}
int op(int x, int y){
return x+y;
}
int main(int argc, char *argv[])
{
int a = 2, b=3;
//the following 8 examples compile nicely:
cout << "a=" << a << " b=" << b << " res=" << executeOperator1(a,b,op) <<endl; //1
cout << "a=" << a << " b=" << b << " res=" << executeOperator2(a,b,op) <<endl; //2
cout << "a=" << a << " b=" << b << " res=" << executeOperator3(a,b,op) <<endl; //3
cout << "a=" << a << " b=" << b << " res=" << executeOperator4(a,b,op) <<endl; //4
cout << "a=" << a << " b=" << b << " res=" << executeOperator1(a,b,&op) <<endl; //5
cout << "a=" << a << " b=" << b << " res=" << executeOperator2(a,b,&op) <<endl; //6
cout << "a=" << a << " b=" << b << " res=" << executeOperator3(a,b,&op) <<endl; //7
cout << "a=" << a << " b=" << b << " res=" << executeOperator4(a,b,&op) <<endl; //8
//int f(int,int) = op; //does not compile
int (*g)(int,int) = op; //does compile
//int h(int,int) = &op; //does not compile
int (*i)(int,int) = &op;//does compile
return 0;
}
答案 0 :(得分:2)
所有示例的工作都是因为所谓的指针衰减规则。函数名衰减到指向几乎所有上下文中的函数的指针。 ( Decay 这里意味着原始类型信息丢失了,剩下的就是指针。在某些上下文中,数组也会衰减到指针。)
所以你的所有例子在语义上都是一样的,我不会把它们中的任何一个称为首选。
只是为了它的乐趣,这也会编译:
int executeOperator_insane(int a, int b, int f(int,int)){
return (***************f)(a,b);
}
答案 1 :(得分:1)
函数,就像数组作为参数传递给函数一样,会衰减成指针。例如:获取两个int
参数并返回int
的函数的类型为int (*) (int, int)
。
但是您也可以将该函数作为参考传递,在这种情况下,您将使用int (&) (int, int)
类型。
要声明上面函数指针的类型值,您只需编写:
typedef int (*FuncType) (int, int);
FuncType myFunc = op;
// OR
FuncType myFunc = &op;
第二种方式通常是优先的,因为它更清晰,但大多数编译器让用户放弃第一种风格。
建议通过以下链接: http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions
答案 2 :(得分:0)
使用时:
int f(int,int);
在main
(或任何不是函数参数的地方)中,它声明f
是一个函数,而不是函数的指针。因此,你不能使用
int f(int,int) = op;
另一方面,
int (*g)(int,int) = op;
声明g
是指向函数的指针。因此,它有效。
当int f(int,int)
用作函数的参数时,它等同于唱int (*f)(int, int)
。