C &;函数指针赋值中的运算符可选

C &;函数指针赋值中的运算符可选,c,gcc,function-pointers,C,Gcc,Function Pointers,在以下代码中: /* mylog.c */ #include <stdio.h> #include <stdlib.h> /* for atoi(3) */ int mylog10(int n) { int log = 0; while (n > 0) { log++; n /= 10; } return log; } int mylog2(int n) { int log = 0;

在以下代码中:

/* mylog.c */
#include <stdio.h>
#include <stdlib.h> /* for atoi(3) */

int mylog10(int n)
{
    int log = 0;
    while (n > 0)
    {
        log++;
        n /= 10;
    }
    return log;
}

int mylog2(int n)
{
    int log = 0;
    while (n > 0)
    {
        log++;
        n >>= 1;
    }
    return log;
}

int main(int argc, const char* argv[])
{
    int (*logfunc)(int); /* function pointer */
    int n = 0, log;

    if (argc > 1)
    {
        n = atoi(argv[1]);
    }

    logfunc = &mylog10; /* is unary '&' operator needed? */

    log = logfunc(n);
    printf("%d\n", log);
    return 0;
}

我注意到一元
&
(address of)操作符是可选的,程序编译和运行的方式与使用或不使用它的方式相同(在使用GCC 4.2.4的Linux中)。为什么?这是编译器特有的问题,还是编译器接受两种不同的语言标准?谢谢。

您正确地认为
&
是可选的。函数(如数组)可以自动转换为指针。它既不是特定于编译器的,也不是不同语言标准的结果。根据标准第6.3.2.1节第4段:

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

< > > C++中的强回答。对于C,同样适用

引用C++标准(4.3.1):

函数类型T的左值可以是 已转换为类型为的右值 “指向T的指针。”结果是 指向函数的指针。50)

数组也是如此。(4.2.1)

类型为“n的数组”的左值或右值 “T”或“T的未知界数组” 可以转换为类型为的右值 “指向T的指针。”结果是 指向元素的第一个元素的指针 数组

但请注意,这些都是转换,决不是函数指针,也不是数组指针。HTH来自标准(6.3.2.1/4):

函数指示符是一个表达式 具有函数类型的。除非 是sizeof的操作数 运算符或一元运算符(&a) 带类型的函数指示符 “函数返回类型”为 转换为具有 类型“”指向返回函数的指针 键入“”


因此,是的,省略
&
会产生指向函数的指针。

运算符
&
在上下文中获取函数地址(将其分配给某个对象)时确实是可选的。它不是特定于编译器的,它遵循语言的正式定义


对称地,当通过指针调用函数时,运算符
*
是可选的。在您的示例中,可以调用函数作为
(*logfunc)(n)
logfunc(n)
。你用的是后者,但前者也行。

我也被否决了,我强烈怀疑这些是对手的否决票。。。这是一个从me@Armen齐鲁尼亚:一个“对手”的统计数据没有显示出足够的反对票,使他成为罪魁祸首。这显然使我受到怀疑:)但我没有这么做!一定是某个巨魔投了反对票。@AndreyT:我很抱歉匆忙地假设对手投了反对票。我显然错了。这一定是我的挫败感:)@AndreyT,@Armen:我没有被否决,但正如你所注意到的,我的否决票太少了,不可能有罪。这是个圈套!我可以证明我的清白!顺便说一句——这是否意味着函数指针的“行为方式”与函数引用的行为方式相同?@Kos:它在源代码级别上的行为方式可能相同,尽管这种相似性纯粹是表面的:底层的抽象语言机制大不相同。然而,如果你更深入地挖掘,看看机器级的机制,你会发现它们看起来又是一样的。
logfunc = &mylog10;