/----------------------------------------------------------------------/
二。main的声明
其实如果只是算潭书的第二版,这个无类型的main声明没有问题,只是直到C99标准
的出现,这个声明才彻底废除。其实也是同样一个问题,允许你不写,但这不是说你
这样用就是好事。不过,这个的后果有点不一样的就是,你忽略不写,很可能以为是
不需要返回的,或者是以为返回一个无类型的(void),接着就出现了main函数里不
写return 0;的问题。那本书就是从头到尾所有main函数一律没有return 0; 。好了,
等到学了函数那章,书上说,没有返回值的函数应该要用void来声明,好了,
void main就这样诞生了。不信就看看谭书的第三版,变成从头到尾的void main()。
不过话说回头,这样的问题对于初学者学习基本语法和结构方面和写写小程序的都不会
出现任何影响。在编译器上来说,这只是一个标准的问题,但对于你来说别小看了这么
一点点的变化。因为你习惯了main这种写法的话,必然会把这个习惯带到编写其它函数里
(这里暂且不讲main本身返回值的问题)。
举个简单例子,写以下代码:
#include <stdio.h>
factorial(int n)
{
if(n==1)return 1;
else if(n>1)return n * factorial(n-1);
}
int main(void)
{
int n;
while(scanf("%d", &n),n>=0)
{
printf("%d\n", factorial(n));
}
return 0;
}
看得出来是计算阶乘的(主要看那个子函数,main函数用回标准写法),
只不过少了int声明和最后一个必然的return而已,
看看输入一个0进去会发生什么事吧:
TC2: 1 (结果居然是碰对了)
VC6: -858993460 (不确定的随机结果)
GCC: 0 (C99标准)
如果你用TC,那你还可能以为这份代码是正确的,
于是你就以为递归算阶乘就是这么写的。
于是还反过来问我:“喂,雨中飞燕,这个结果不就是正确的吗,还错什么啊?”
于是我无语了。。。然后你也就留下了一个你可能以后都不打算去检查的Bug。。。
现在我们再来看一个:
#include <stdio.h>
long Factorial(int n)
{
if(n==1)return 1;
else if(n>1)return n * Factorial(n-1);
return 1;
}
FactorialSum(int n)
{
float f = 0;
for(;n>0;--n)
{
f += 1.0/Factorial(n);
}
return f;
}
int main(void)
{
int n;
while(scanf("%d", &n),n>=0)
{
printf("%f\n", FactorialSum(n));
}
return 0;
}
这个是计算1/1! + 1/2! + 1/3! +...+ 1/n!的代码,Factorial的改好了,
然后加一个FactorialSum函数计算和。里面的变量f就是用来累加(喜欢用float来
保存浮点也是书上的一大不良特色),1写成1.0保证结果不是整数。似乎没错吧?
运行一下不就知道了嘛,输入1,输出0;输入2,输出0;输入5,输出0,
结果是输出全部是0。原因就是你省略类型埋的祸根,只需要在那个函数前面补上
一个float那结果就正确了。
这个危害有多严重吗?在这里不算严重,因为在这里代码很短,相当容易看得出来。
要是换成大程序呢?上千代码甚至上万的代码,要是最后都懒得写一下return,
或者一个返回类型,那么错误还怎么找?你要是这个也省略那个也省略,
写了N多行代码的时候,一运行,这个结果也错那个输入也不行的时候,
你再看看你是不是被你自己的“习惯”给难住你自己吧。
其实说实在的,WIN-TC自带的一个tcsearch.exe文件,那个可以查函数用法和示例,
上面的示例代码全部都是一样的风格: int main(void)
非常规范标准的写法,可是有多少人看了这个了呢?
本文导航
- 第1页: 首页
- 第2页: 头文件的问题
- 第3页: main的声明
- 第4页: 函数声明与返回值
- 第5页: 代码风格
- 第6页: TC图形库
- 第7页: 越界检查
- 第8页: 结束语