以下列方式调用函数有什么区别?

时间:2012-08-20 13:35:41

标签: c++ c

foo();

(*foo)();

(&foo)();

这些函数调用之间究竟有什么区别(假设某处定义了foo())?有没有人可以使用另一种情况?

另外,为什么&foo()*foo()无效?

6 个答案:

答案 0 :(得分:25)

实际调用之间没有区别(相反,根据foo()的声明方式,它们都会做同样的事情)

C和C ++中的所有函数调用都是通过在函数调用括号之前出现的函数指针表达式进行的。如有必要,会发生非指针类型的隐式地址。

Here's an ideone demonstrating the behavior in C++.

&foo()*foo()不起作用的原因是函数调用运算符()优先于*&。所以他们可能会工作,这取决于你对返回值做了什么。 &foo()将获取返回值的地址,*foo()将取消引用它。在某些情况下,这些操作中的任何一个或两者都可能是合法的。考虑一个返回引用指针类型的函数。

这个答案的一部分取自R ..的评论。

答案 1 :(得分:10)

你没有确切地说foo是什么,但我认为这是一个功能。

  

这些函数调用之间究竟有什么区别?

显然,第一个使用通常的语法调用函数。

第三个获取函数的地址并尝试调用它;该语言允许调用函数指针,就好像它们是它们指向的函数一样,因此这相当于foo()

第二个尝试取消引用该功能。解除引用需要一个指针,该语言允许从函数隐式转换为指向该函数的指针,因此这相当于(*(&foo))(),而foo()相当于&foo()

总结一下:这三个人做同样的事情。

  

是否有任何情况可能会使用另一种情况?

除非你喜欢用不必要的heiroglyphics来装饰你的代码,否则没有理由使用除第一种形式之外的任何函数或函数指针。

  

另外,为什么*foo()&(foo())无效?

优先规则意味着这些规则等同于*(foo())operator*();即他们调用该函数并尝试取结果的地址和取消引用。如果函数具有返回类型,则第一个表单将“起作用”;第二个将“工作”,如果它返回指针或(在C ++中)带有重载的一元{{1}}的东西。

答案 2 :(得分:0)

foo()调用函数foo。

void foo() {return;}
foo();

(* foo)()取消引用名为foo的(函数)指针,并使用零参数调用它。

void bar() {return;}

int main(int argc, char** argv){
    void(*foo)() = &bar;
    (*foo)(); // works
    (*bar)(); // also works
    return 0;
}

(& foo)()接受函数foo的引用,并使用零参数调用它。

void bar() {return;}

int main(int argc, char** argv){
    (&bar)();
    return 0;
}

希望有所帮助。

答案 3 :(得分:0)

如果foo是函数指示符,则它们在C:

中都是等价的
foo();
(foo)();
(*foo)();
(***foo)();
(*&foo)();

答案 4 :(得分:0)

foo();

调用名为foo的函数。

(*foo)();

通过指向名为foo的函数的函数调用函数;通常在调用已作为参数传递给另一个函数的函数(也称为回调)时会看到这一点:

/**
 * Execute the function pointed to by "foo" for each element
 * in the array.
 */
void map(int *arr, size_t arrsize, void (*foo)(int))
{
  size_t i;
  for (i = 0; i < arrsize; i++)
    (*foo)(arr[i]); // can also be called as foo(arr[i]);
}

void bar(int i)
{
  printf("i = %d\n", i);
}

int main(void)
{
  int arr[] = {1, 2, 3, 4, 5};
  /**
   * Call the function "bar" for each member
   * of "arr".
   */
  map(arr, sizeof arr / sizeof *arr, bar);
}

这个例子中的映射有点愚蠢,但它说明了这个概念。就像您可以指向不同的数据类型一样,您可以指向不同的函数类型。我们正在执行foo指向的函数,而不是执行名为foo的函数。

请注意,括号很重要:函数调用运算符()的优先级高于一元*,因此表达式*foo()将被解释为“call foo和dereference结果“,而(*foo)()被解释为”取消引用foo并调用结果“。

(&foo)();

(*foo)();做同样的事情,除了它通过引用而不是指针(仅限C ++)。括号再次重要; &foo()被解释为“调用foo并获取结果的地址”,这是不合法的。

答案 5 :(得分:0)

由于标记为c++,因此函数可以返回该语言的引用,并且可以将此类函数称为&foo()

#include <iostream>

using std::cout;
using std::endl;

int & foo() {
    static int f = 5;
    return f;
}

int main() {
    cout << foo() << endl;
    *(&foo()) = 7;
    cout << foo() << endl;
    return 0;
}