8

我有这两个测试功能:

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

我会假设其中一个会返回指针地址或指针本身;而不是存储在指针上的值...

那么它为什么要这样做呢?

4

4 回答 4

7

因为在处理非成员函数的地址和使用指向它们的指针时,C++ 提供了语法糖。

可以得到这样的功能的地址:

int someFunc(int);

与:

int (* someFuncPtr)(int) = someFunc;

或者:

int (* someFuncPtr)(int) = &someFunc;

还有使用这种指针的语法糖,或者调用指向函数:

(*someFuncPtr)(5);

或使用简化的语法:

someFuncPtr(5);
于 2013-10-27T11:29:03.427 回答
6

(*fun)(m,n)fun(m,n)与C 和 C++ 中将函数转换为函数指针的规则相同。

在 C 2011 中,规则是第 6.3.2.1 4 条:“函数指示符是具有函数类型的表达式。除非它是sizeof运算符、_Alignof 运算符或一元&运算符的操作数,否则“函数返回类型”类型的函数指示符将转换为“指向函数返回类型的指针”类型的表达式。在 C++ 中,规则是第 4.3 条。

请注意,函数指示符不仅仅是命名函数的标识符。它可以是一个标识符,也可以是另一个表达式。例如,如果foo是函数名,则通过上述自动转换为指向函数的指针。那么,sincefoo是指向函数的指针,*foo就是函数。这意味着您可以编写:

(*fun)(m,n)

结果是fun自动转换为指针,然后*计算为函数,然后*fun转换回指针,然后调用函数。您可以继续执行此操作并编写:

(**************fun)(m,n)

这与fun(m,n). 每个都*再次生成函数,但编译器会自动将其转换回指针。您可以永远继续这场战斗,但编译器将永远获胜。

事实上,这些都具有相同的效果:

(&fun)(m,n)
( fun)(m,n)
(*fun)(m,n)
于 2013-10-27T11:46:16.077 回答
1

这是因为您没有返回这些值的内存地址。用指针调用函数不会改变它的值,它仍然在调用函数。您可以做的是将一个值返回给一个变量,然后获取它的内存地址,例如:

int result = fun(m,n);
cout << "the result " << result << " pointing at " << &result << endl;
于 2013-10-27T11:38:27.587 回答
0

在 C 和 C++ 中,函数的名称也是指向函数代码的指针。作为任何指针,您可以使用 取消引用它们*,这在函数指针的情况下意味着调用函数,除了取消引用之外,您还可以在它们之后使用括号,就像在您的apply_a情况下一样。但对 C 和 C++ 函数的有效调用也只是通过它们的名称来调用它们,这是apply_b大小写。

于 2013-10-27T11:30:40.740 回答