首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >c/C++中的函数值

c/C++中的函数值
EN

Stack Overflow用户
提问于 2011-04-30 20:10:52
回答 3查看 388关注 0票数 6

可能重复:

How does dereferencing of a function pointer happen?

如果我们有

代码语言:javascript
运行
复制
void f() {
    printf("called");
}

然后,以下代码将产生“被调用”的输出:

代码语言:javascript
运行
复制
f();
(*f)();

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-30 20:33:50

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

按姓名:

代码语言:javascript
运行
复制
f();

通过函数指针:

代码语言:javascript
运行
复制
typedef void (*fptr_t)();
fptr_t fptr = &f;
(*fptr)();

现在,在函数名(&f)上使用address-of操作符显然会创建一个函数指针.但是,当满足某些条件时,函数名可以隐式转换为函数指针。因此,上面的代码可以写成:

代码语言:javascript
运行
复制
typedef void (*fptr_t)();
fptr_t fptr = f; // no address-of operator, implicit conversion
(*fptr)();

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

我更喜欢使用address-of,在创建函数指针时,含义更加清晰。

相关注意:如果提供函数指针,函数调用操作符将自动取消对函数指针的引用。所以这也是合法的:

代码语言:javascript
运行
复制
typedef void (*fptr_t)();
fptr_t fptr = &f;
fptr();

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

而且两种快捷方式都不适用于指针到成员,在那里您需要显式的地址和取消引用操作符。

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

票数 6
EN

Stack Overflow用户

发布于 2011-04-30 20:12:25

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

票数 6
EN

Stack Overflow用户

发布于 2011-04-30 20:23:19

就像数组类型几乎完全等效于对应的指针到元素类型一样,函数类型完全等效于对应的指针到函数类型:

代码语言:javascript
运行
复制
void (*func1)() = f;  // function type -> pointer-to-function type
void (*func2)() = &f; // pointer-to-function type -> pointer-to-function type

而且还

代码语言:javascript
运行
复制
void (*func)() = ...;
func();               // pointer-to-function type + function-call operator
(*func)();            // function type + function-call operator

所以,在

代码语言:javascript
运行
复制
(*f)();

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5844332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档