请考虑Dennis ritchie的C书中的以下引用
所有变量必须在使用前声明,尽管某些声明可以由内容隐式进行。
众所周知,任何类型的所有变量必须在进一步使用之前声明。我不知道声明的后半部分,某些声明可以由内容隐含地进行。
在C中,通常,变量属于char,int,float,double四种基本数据类型。如何在没有任何声明之前使用这些数据类型的变量。请提供一个示例,显示基于变量保存的内容的隐式声明。
通过“某些声明”,作者意味着声明不是变量的事物。在编写本书时,C允许隐式声明函数:编译器只是假设函数返回整数。现代C标准使这种声明非法。
当编写第一版K&R时,没有C标准。在编写第二版K&R时,C89 / C90标准即将完成。由于C89最终确定之前编写的代码遗留问题,标准必须允许:
#include <stdio.h>
double sqrt();
main(argc, argv)
char **argv;
{
if (argc > 1)
printf("sqrt(%s) = %f\n", argv[1], sqrt((double)atoi(argv[1])));
else
printf("sqrt(%.0f) = %f\n", 2.0, sqrt(2.0));
return 0;
}
请注意,main()
的返回类型是隐含的int
;函数参数argc
隐式为int
;函数atoi()
具有隐式返回类型int
。另请注意,sqrt()
的参数必须明确为double值;编译器无法自动转换参数类型,因为原型在C89标准之前不是C的一部分。
C99或C11编译器不再接受此类代码。你可以使用:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc > 1)
printf("sqrt(%s) = %f\n", argv[1], sqrt(atoi(argv[1])));
else
printf("sqrt(%.0f) = %f\n", 2.0, sqrt(2));
return 0;
}
这使用标准头来声明具有完整原型的函数,因此不再需要将参数强制转换为sqrt()
。在C99或C11中,你可以省略return 0;
,效果也一样。就个人而言,我不喜欢允许这样做的漏洞并继续明确地写回报。在C90中返回是必要的,以向环境发送确定状态(例如,调用程序的shell)。