在以下代码中:
/* 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)。为什么?这是编译器特定的问题,还是编译器可能接受两种不同的语言标准?感谢。
答案 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 功能指示符与类型 ''返回类型''是 转换为具有的表达式 键入''返回函数的指针 类型”” 强>
所以是的,省略&
会产生一个指向函数的指针。