知道这个调用:
pow(4);
将生成此错误消息:
error: too few arguments to function ‘pow’
我正在学习指向函数的指针,当看到下面这段代码工作时我感到很惊讶。但是为什么?
#include<stdio.h>
#include<math.h>
void aux(double (*function)(), double n, double x);
int main(void)
{
aux(pow, 4, 2);
aux(sqrt, 4, 0);
return 0;
}
void aux(double (*function)(double), double n, double x)
{
if(x == 0)
printf("\nsqrt(%.2f, %.2f): %f\n", n, x, (*function)(n));
else
printf("\npow(%.2f, %.2f): %f\n", n, x, (*function)(n));
}
我编译使用:
gcc -Wall -Wextra -pedantic -Wconversion -o test test.c -lm
结果是:
pow(4.00, 2.00): 16.000000
sqrt(4.00, 0.00): 2.000000
如果我把第一次调用aux
的第三个参数改成3,结果就变成了:
pow(4.00, 3.00): 64.000000
sqrt(4.00, 0.00): 2.000000
还有一个问题。在这种情况下,声明和使用函数指针的正确方法是什么?
最佳答案
这个:
void aux(double (*function)(), double n, double x);
对函数
使用旧式非原型(prototype)声明。空括号 ()
表示该函数采用固定但未指定数量和类型的参数。
C 仍然允许这种向后兼容的声明。原型(prototype)(指定参数类型的函数声明)于 1989 年由 ANSI C 引入。在此之前,无法在函数声明中指定参数类型,并且编译器无法检查调用是否传递了正确的数字和参数类型。
这样的声明是“过时的”,这意味着可以从 future 的 C 标准中删除对它们的支持(但在 20 多年的时间里,委员会一直没有考虑删除它们)。使用错误数量的参数类型调用函数不一定会被编译器诊断出来,并且行为是未定义的。
当一个函数类型有原型(prototype)而另一个没有时,函数类型的兼容性规则有点复杂。这些类型:
double(double) /* function with one double parameter
returning double */
double(double, double) /* function with two double parameters
returning double */
彼此不兼容,但它们都与此类型兼容:
double() /* function with a fixed but unspecified number of parameters
returning double */
这使得在没有来自编译器的诊断的情况下进行错误调用成为可能。
为避免此问题,始终使用原型(prototype):
void aux(double (*function)(double, double), double n, double x);
您不仅可以从编译器获得更好的诊断,而且不必担心非原型(prototype)函数的复杂兼容性规则(如果您好奇的话,在 N1570 6.7.6.3 段落中指定) 16).
关于c - 为什么这个指向函数的指针可以在没有警告或错误的情况下工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28282577/