为什么函数指针定义与任何数字的&符号或星号“*”一起工作?

为什么下面的工作?

void foo() { cout << "Foo to you too!\n"; }; int main() { void (*p1_foo)() = foo; void (*p2_foo)() = *foo; void (*p3_foo)() = &foo; void (*p4_foo)() = *&foo; void (*p5_foo)() = &*foo; void (*p6_foo)() = **foo; void (*p7_foo)() = **********************foo; (*p1_foo)(); (*p2_foo)(); (*p3_foo)(); (*p4_foo)(); (*p5_foo)(); (*p6_foo)(); (*p7_foo)(); } 

有几件事情可以让所有这些操作符的组合以相同的方式工作。

所有这些工作的根本原因是一个函数(如foo )可以隐式转换为函数的指针。 这就是为什么void (*p1_foo)() = foo; 作品: foo隐式转换为指向自身的指针,并将指针分配给p1_foo

当应用于一个函数时,一元&产生一个指向该函数的指针,就像当它应用到一个对象时产生一个对象的地址一样。 对于指向普通函数的指针,由于隐式函数到函数指针的转换,它总是冗余的。 无论如何,这就是为什么void (*p3_foo)() = &foo; 作品。

一元*应用于一个函数指针时,会产生指向函数,就像当它被应用到一个普通指针指向一个对象时,它产生指向的对象。

这些规则可以结合使用。 考虑你的倒数第二个例子, **foo

  • 首先,将foo隐式转换为自己的指针,并将第一个*应用于该函数指针,再次产生函数foo
  • 然后,结果又隐式地转换为一个指向它自己的指针,第二个*被应用,再次产生函数foo
  • 然后它又被隐式地转换成一个函数指针并被分配给该variables。

您可以添加尽可能多的* s,结果总是相同的。 越多越好。

我们也可以考虑你的第五个例子, &*foo

  • 首先, foo隐式转换为一个指向它自己的指针; 一元*被应用,再次产生foo
  • 然后,将&应用于foo ,产生一个指向foo的指针,该指针指定给variables。

&只能应用于一个函数,而不是被转换为函数指针的函数(当然,除非函数指针是一个variables,在这种情况下,结果是一个指针指针例如,你可以添加到你的列表void (**pp_foo)() = &p7_foo; )。

这就是为什么&&foo不起作用: &foo不是函数; 它是一个右值的函数指针。 然而, &*&*&*&*&*&*foo会像&******&foo ,因为在这两个expression式中, &始终应用于一个函数而不是一个右值函数指针。

另请注意,您不需要使用一元*来通过函数指针进行调用; both (*p1_foo)();(p1_foo)(); 具有相同的结果,同样是因为函数到函数指针的转换。

我认为记住C是底层机器的抽象也是有帮助的,这是抽象漏洞的地方之一。

从计算机的angular度来看,函数只是一个内存地址,如果执行的话,执行其他指令。 所以C中的一个函数本身就是一个地址模型,这可能会导致函数与它指向的地址“相同”的devise。