C 分配函数指针的正确方法

C 分配函数指针的正确方法,c,function-pointers,C,Function Pointers,我对将函数指针分配给 变量如果我有一个函数foo int foo(); 我将一个指向foo的指针分配给变量bar void * bar; 如果我使用 bar = foo; // or bar = &foo; 在我看来,这些值中只有一个是正确的,或者我遗漏了什么?foo和&foo值在C中是等价的,并且具有相同的类型 此处的&运算符正确但冗余 请注意,将函数指针指定给void*在C中无效 void *fp1 = foo; // invalid int (*fp2)() = f

我对将函数指针分配给 变量如果我有一个函数foo

int foo();
我将一个指向foo的指针分配给变量bar

void * bar;
如果我使用

bar = foo; 
// or 
bar = &foo; 

在我看来,这些值中只有一个是正确的,或者我遗漏了什么?

foo
&foo
值在C中是等价的,并且具有相同的类型

此处的
&
运算符正确但冗余

请注意,将函数指针指定给
void*
在C中无效

void *fp1 = foo;   // invalid
int (*fp2)() = foo;  // valid
int (*fp3)() = &foo; // valid

(这些实际上是声明,但赋值运算符的约束适用。)

让我再解释一下

foo和&foo值在C中是等效的,并且具有相同的类型

正如@ouah对答案的评论所指出的,这并不完全正确。特别是:

  • sizeof(foo)
    无效,
    sizeof(&foo)
    是指针的大小
  • &foo
    是指向foo的指针,而
    和(&foo)
    无效
  • 然而,在所有其他情况下,它们实际上是相同的,正如C标准所提到的(参考,例如:

    6.3.2.1.4:函数指示符是具有函数类型的表达式。除非它是sizeof运算符或一元&运算符的操作数,否则类型为“函数返回类型”的函数指示符将转换为类型为“指向函数返回类型的指针”的表达式

    当函数指示符未转换为指针时,
    sizeof
    和一元
    &
    运算符是仅有的两个例外

    另外,您还可以找到
    sizeof(foo)
    &(&foo)
    无效的原因:

    6.5.3.2.1:一元
    &
    运算符的操作数应为函数指示符、一元
    []
    或一元
    *
    运算符的结果,或指定非位字段且未使用寄存器存储类规范声明的对象的左值

    6.5.3.4.1
    sizeof
    运算符不得应用于具有函数类型的表达式或不完整类型、此类类型的括号名称或指定位域成员的表达式


    好的,函数指针是&运算符的一个特例。这很有趣:这很有趣。谢谢你们的帮助,伙计们。
    int(*fp2)=foo甚至可以编译..没问题:)\@GrijeshChauhan不使用
    -Werror
    <代码>整数(*fp2)=foo实际上是无效的C.OK!。。在那5分钟里我以为你犯了错误。。但人们对你的答案投了赞成票,我知道你不会犯错,所以我只是发布了我的答案,而不是评论你。:)
    foo
    &foo
    不是等价的,通常不具有相同的类型。虽然
    sizeof(&foo)
    是完全有效的,但
    sizeof(foo)
    不是。您可能会认为函数和指向它们的指针与处理某个数组和指向同一个数组的指针的方式类似。在大多数表达式上下文中,数组和函数“衰减”到指针,两个例外是当一元运算符
    &
    sizeof
    应用于它们时。不过,该语句可能会产生误导
    &(foo)
    &(&foo)
    不同,因此这是另一个两者不等价的上下文。我认为,技术上的代码>和代码>不能完全评估它的操作数,因为它不做C++中的被称为LValueRValf转换的事情,而C中被称为找到表达式的值,所以我认为在C语言中,技术上从来没有“评估”,因为它们不是真值。这是一个很好的解决方法,而不是用另一种方式来表达关于表达式
    foo
    的需要。