我有这两个测试功能:
int apply_a(int (*fun)(int, int), int m, int n) {
return (*fun)(m,n);
}
int apply_b(int (*fun)(int, int), int m, int n) {
return fun(m,n);
}
它们似乎会返回不同的东西,那么为什么它们会产生相同的结果呢?
int add(int a, int b) {return a + b;}
int res_a = apply_a(add, 2, 3); // returns 5
int res_b = apply_b(add, 2, 3); // returns 5
我会假设其中一个会返回指针地址或指针本身;而不是存储在指针上的值......
那为什么要这样做?
答案 0 :(得分:7)
因为C ++在处理非成员函数的地址并使用指向它们的指针时提供语法糖。
可以获得此类功能的地址:
int someFunc(int);
使用:
int (* someFuncPtr)(int) = someFunc;
或:
int (* someFuncPtr)(int) = &someFunc;
使用这样的指针也有语法糖,要么调用指向函数:
(*someFuncPtr)(5);
或使用简化语法:
someFuncPtr(5);
答案 1 :(得分:6)
(*fun)(m,n)
与fun(m,n)
相同。
在C 2011中,规则是条款6.3.2.1 4:“函数指示符是具有函数类型的表达式。除非是 sizeof 运算符, _Alignof运算符或一元& 运算符的操作数,否则函数指示符的类型为“function”返回 type “将转换为具有”指向函数返回 type “的类型的表达式。在C ++中,规则是第4.3节。
请注意,函数指示符不仅仅是命名函数的标识符。它可以是标识符,也可以是另一个表达式。例如,如果foo
是函数的名称,它将自动转换为上述函数的指针。然后,由于foo
是指向函数的指针,因此*foo
是函数。这意味着你可以写:
(*fun)(m,n)
结果是fun
自动转换为指针,然后*
计算到函数,然后*fun
转换回指针,然后调用函数。您可以继续并写下:
(**************fun)(m,n)
这与fun(m,n)
相同。每个*
再次生成函数,但编译器会自动将其转换回指针。你可以永远地继续这场战斗,但编译器总会赢。
事实上,这些都具有相同的效果:
(&fun)(m,n)
( fun)(m,n)
(*fun)(m,n)
答案 2 :(得分:1)
这是因为您没有返回这些值的内存地址。 用指针调用函数不会改变它的值,它仍在调用函数。你可以做的是将一个值返回给变量,然后获取它的内存地址,例如:
int result = fun(m,n);
cout << "the result " << result << " pointing at " << &result << endl;
答案 3 :(得分:0)
在C和C ++中,函数名称也是函数代码的指针。作为任何指针,您可以使用*
取消引用它们,在函数指针的情况下,除了解除引用之外还意味着调用函数,在它们之后也使用paranthesis,就像在apply_a
情况下一样。但是,有效的C和C ++函数调用只是通过它们的名称来调用它们,apply_b
case。