为什么在将函数分配给函数指针时可以多次使用解引用运算符?

8
我想知道为什么可以在将函数分配给函数指针时多次使用解引用运算符*的具体原因。
例如,以下代码可以完美编译和运行:
#include <iostream>

void f() { std::cout << "Hello World!" << std::endl; }

int main() {
    void(*f_ptr)(void) = ***************************************f;
    f_ptr();
    return 0;
} 

3
您可能会发现此问题很有趣。 - WhozCraig
@WhozCraig 这个问题不是那个问题的重复吗? - BЈовић
3个回答

11

每当必要时,函数和对函数的引用会衰减为函数指针。没有为函数定义解引用运算符,但为函数指针定义了一个:函数或对函数的引用愉快地衰减为指针,以便再次进行解引用。


4
一方面,根据C标准(6.3.2.1左值、数组和函数设计者)
4.函数设计者是具有函数类型的表达式。除非它是sizeof运算符65)或一元&运算符的操作数,否则具有“返回类型的函数”的类型的函数设计者将转换为具有“指向返回类型的函数的指针”的类型的表达式
另一方面,根据C标准(6.5.3.2地址和间接运算符)
4.一元*运算符表示间接。如果操作数指向函数,则结果是函数设计者;
因此,存在递归转换。首先从函数设计者到指针,然后从指针到函数设计者(或如C++标准中所写的,引用函数的左值),再从函数设计者或左值到函数指针,依此类推。

-4

您正在初始化f_ptr,使其成为指向指向指针的指针...的指针。因此,您可以链接任意数量的指针,父指针的地址将仅保持其子指针的地址。双指针通常用于在函数中初始化变量。


一个 double**double* 不是同一种类型。但对于函数指针来说,这个区别并不适用。 - rubenvb
不是的,我说双指针是指double**,否则我会说一个指向double类型的指针。 - TomJ
1
我理解,但是只有在T是函数(指针/引用)类型的情况下,T **才与T *行为相同。因此,你的答案并没有解释这种现象。 - rubenvb
啊,好的,对不起,我明白了。 - TomJ
@TomJ 注意,这行代码:void(**f_ptr)(void) = **f;根本无法编译(如果将其剪切并粘贴到问题代码中)。 - FdeF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接