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

时间:2010-11-28 19:42:37

标签: 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;
    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;
}

logfunc = &mylog10;

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

4 个答案:

答案 0 :(得分:14)

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

  

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

答案 1 :(得分:13)

在您的上下文中获取函数的地址(将其指定给某些内容)时,运算符&确实是可选的。它不是特定于编译器的,它来自语言的正式定义。

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

答案 2 :(得分:7)

在C ++中回答。对于C,同样适用

引用C ++标准(4.3.1):

  

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

数组相同。 (4.2.1)

  

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

但请注意,这些是转换,绝不是函数指针或数组指针。 HTH

答案 3 :(得分:5)

从标准(6.3.2.1/4):

  

函数指示符是一个表达式   有功能类型。除非它   是sizeof的操作数   操作员或一元&amp;操作员,a   功能指示符与类型   ''返回类型''是   转换为具有的表达式   键入''返回函数的指针   类型””

所以是的,省略&会产生一个指向函数的指针。