&operator在函数指针赋值中可选

pr1*_*268 8 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;
}
Run Code Online (Sandbox Code Playgroud)

在线

logfunc = &mylog10;
Run Code Online (Sandbox Code Playgroud)

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

Car*_*rum 14

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

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


AnT*_*AnT 13

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

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


Arm*_*yan 7

用C++回答.对于C同样适用

引用C++标准(4.3.1):

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

数组相同.(4.2.1)

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

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


ice*_*ime 5

从标准(6.3.2.1/4):

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

所以是的,&无论如何都省略了指向函数的指针.