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

在以下代码中:

/* mylog.c */ #include  #include  /* 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)。 为什么? 这是编译器特定的问题,还是编译器可能接受两种不同的语言标准? 谢谢。

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

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

你是正确的&是可选的。 函数(如数组)可以自动转换为指针。 它既不是编译器特定的,也不是不同语言标准的结果。 根据标准, 第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运算符或一元&运算符的操作数,否则具有类型”函数返回类型”的函数指示符将转换为具有类型”指向函数返回类型’的指针的表达式

所以是的,省略&得到一个指向函数的指针。