Laz*_*zer 66 c c++ pointers function-pointers
为什么以及如何解除引用函数指针只是"什么都不做"?
这就是我所说的:
#include<stdio.h>
void hello() { printf("hello"); }
int main(void) {
(*****hello)();
}
Run Code Online (Sandbox Code Playgroud)
来自这里的评论:
函数指针解除引用就好了,但生成的函数指示符会立即转换回函数指针
从这里的答案:
解除引用(以你认为的方式)函数的指针意味着:访问CODE内存,因为它将是一个DATA内存.
不应该以这种方式取消引用函数指针.相反,它被称为.
我会使用"dereference"这个名字与"call"并排使用.没关系.
无论如何:C的设计方式是函数名称标识符和变量保持函数的指针都是相同的:地址到CODE内存.它允许通过在标识符或变量上使用call()语法来跳转到该内存.
如何准确地不提领一个函数指针的工作?
Nor*_*sey 51
这不是一个正确的问题.对于C,至少,正确的问题是
rvalue上下文中的函数值会发生什么?
(rvalue上下文是名称或其他引用出现在应该用作值的位置,而不是位置 - 基本上除了在赋值的左侧之外的任何位置.名称本身来自右侧的作业.)
好的,那么rvalue上下文中的函数值会发生什么?它立即并隐式转换为指向原始函数值的指针.如果取消引用该指针*
,则会再次返回相同的函数值,该函数值会立即被隐式转换为指针.你可以随心所欲地多次这样做.
您可以尝试两个类似的实验:
如果取消引用左值上下文中的函数指针(赋值的左侧)会发生什么.(答案将是关于你期望的,如果你记住功能是不可变的.)
数组值也会转换为左值上下文中的指针,但它会转换为指向元素类型的指针,而不是指向数组的指针.因此,取消引用它将为您提供一个元素,而不是一个数组,并且您显示的疯狂不会发生.
希望这可以帮助.
PS至于为什么函数值被隐式转换为指针,答案是对于那些使用函数指针的人来说,不必在&
任何地方使用它是一个很大的方便.还有一个双重的便利:调用位置的函数指针自动转换为函数值,因此您不必*
通过函数指针进行调用.
PPS与C函数不同,C++函数可以重载,我没有资格评论语义在C++中是如何工作的.
C++03§4.3/ 1:
函数类型T的左值可以转换为"指向T的指针"的右值.结果是指向函数的指针.
如果对函数引用(例如一元运算*
符)尝试无效操作,则语言尝试的第一件事是标准转换.这就像转换为何int
时添加它一样float
.使用*
上的功能引用导致把它的指针代替,这在你的榜样,是方1的语言.
另一种情况适用于分配函数指针.
void f() {
void (*recurse)() = f; // "f" is a reference; implicitly convert to ptr.
recurse(); // call operator is defined for pointers
}
Run Code Online (Sandbox Code Playgroud)
请注意,这不起作用.
void f() {
void (&recurse)() = &f; // "&f" is a pointer; ERROR can't convert to ref.
recurse(); // OK - call operator is *separately* defined for references
}
Run Code Online (Sandbox Code Playgroud)
函数引用变量很好,因为它们(理论上,我从未测试过)提示编译器,如果在封闭范围内初始化,间接分支可能是不必要的.
在C99中,取消引用函数指针会产生函数指示符.§6.3.2.1/ 4:
函数指示符是具有函数类型的表达式.除非它是sizeof运算符或一元&运算符的操作数,否则具有类型''函数返回类型''的函数指示符将转换为具有类型''指向函数返回类型'的指针的表达式.
这更像是诺曼的答案,但值得注意的是C99没有左撇子的概念.