使用函数或函数符号指针之间是否有区别?

时间:2018-07-16 22:51:52

标签: c function-pointers c11 function-prototypes function-parameter

考虑以下程序:

#include <stdio.h>

void f() {}
void g1(void fun(void)) { printf("%p\n", &fun); }
void g2(void (*fun)(void)) { printf("%p\n", fun); }

int main(void) {
    g1(f);
    g2(&f);
    printf("%p\n", &f);
    return 0;
}

由于C11没有lambda表达式,因此无法将文字函数作为参数传递给g1g2,因此,从某种意义上讲,这两个函数具有相同的作用(您必须先定义参数);我正在读一本书,上面写着

  

从技术上讲,此函数(f)作为函数传递   指向g1的指针通常没有什么用,[...]

所以,我的理解是作者说这两个词在语义上是等效的。

但是调用g1g2时打印的地址不同,其中g2输出f的实际地址。这意味着g1复制了f,这意味着f是按值传递的。这本书是错的还是我?我认为这本书没有错,但是地址不同,当然,选择哪一个很重要。而且,如果有任何区别,在哪种情况下应首选哪一个?

2 个答案:

答案 0 :(得分:3)

你错了。

每当您认为将一个函数传递给一个函数时,实际上就是在将指针传递给该函数。
每当函数看起来像具有函数参数时,实际上就具有函数指针参数。

现在,在您的一个函数中,您将打印指向该参数的指针的值,在另一个函数中,您将打印该参数的指针。除了%p不适合void*而不适用于其他数据指针,尤其不适合函数指针这一事实之外,这意味着您具有未定义的行为,我们有充分的理由期望它们会有所不同,尤其是在具有用于数据和指令的共享地址空间的体系结构上。

答案 1 :(得分:3)

  

但是调用g1g2时打印的地址不同,其中g2输出f的实际地址。这意味着g1复制了f,这意味着f是按值传递的。

您不正确。在g1g2中,变量fun是一个函数指针,而不是一个函数。在&fun中使用g1会给出函数指针存储的地址(在堆栈上),而不是函数的实际地址。

函数不是C或C ++中的值。它们不能被复制,也不能按值传递。