【问题标题】:value of function in c/C++ [duplicate]c / C ++中的函数值[重复]
【发布时间】:2011-08-16 04:55:01
【问题描述】:

可能重复:
How does dereferencing of a function pointer happen?

如果我们有

void f() {
    printf("called");
}

那么下面的代码会输出“被调用”:

f();
(*f)();

我不太明白这是怎么工作的……*ff 有什么区别?为什么要使用后一种语法调用函数?

【问题讨论】:

  • 这需要两个问题,一个是关于C的,一个是关于C++的,因为它们有微妙的不同规则(虽然最终的行为相同)。

标签: c++ c


【解决方案1】:

C++中有两种调用函数的方式:

按名称:

f();

通过函数指针:

typedef void (*fptr_t)();
fptr_t fptr = &f;
(*fptr)();

现在,在函数名 (&f) 上使用地址运算符显然会创建一个函数指针。但是当满足某些条件时,函数名可以隐式转换为函数指针。所以上面的代码可以写成:

typedef void (*fptr_t)();
fptr_t fptr = f; // no address-of operator, implicit conversion
(*fptr)();

您的第二个示例正是这样做的,但使用临时变量而不是命名局部变量来保存函数指针。

我更喜欢在创建函数指针的时候使用address-of,意思更清楚。

相关说明:如果提供了函数指针,函数调用运算符将​​自动取消对函数指针的引用。所以这也是合法的:

typedef void (*fptr_t)();
fptr_t fptr = &f;
fptr();

这对模板非常有用,因为无论您传入的是函数指针还是函子(实现operator() 的对象),相同的语法都适用。

这两种快捷方式都不适用于指向成员的指针,因此您需要显式的地址和取消引用运算符。


在 C 中,@Mehrdad explains that all function calls use a function pointer.

【讨论】:

  • 我希望我们会在 C++0x 中看到更微妙的问题,包括 lambdas 和所有...
【解决方案2】:

第一个在某种程度上是第二个的语法糖。第二个很明显您是通过指针进行调用的,它主要用于函数指针而不是常规函数,以使区别更加明显。

【讨论】:

  • 那么第二个是隐含地把指针指向f,然后通过它调用函数吗?
  • @Matti:不,第二个是取消引用指针并调用函数,这是第一个隐式所做的。 (* 符号有多种含义——它既可以是解引用 operator,也可以是指针 declaration,除了乘法。不要混淆它们。)
  • f 是一个地址。 (*f)() 是对该地址的函数调用。
  • 其实,是的:第二个被隐式解释为(*&f)();,但这只是由于C的继承。在 C++ 中,您“应该”显式获取地址。
  • 伙计们,f*f 是同一个东西,因为间接运算符在应用于函数时,返回一个与函数本身相同的函数指示符。对此进行了详细讨论here
【解决方案3】:

就像数组类型几乎完全等价于对应的指向元素类型一样,函数类型也完全等价于对应的指向函数类型:

void (*func1)() = f;  // function type -> pointer-to-function type
void (*func2)() = &f; // pointer-to-function type -> pointer-to-function type

还有

void (*func)() = ...;
func();               // pointer-to-function type + function-call operator
(*func)();            // function type + function-call operator

所以,在

(*f)();

您正在取消引用 f(隐式转换为 &f),然后应用函数调用运算符。

【讨论】:

    猜你喜欢
    • 2023-02-26
    • 2011-12-31
    • 2022-12-22
    • 2023-04-11
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多