c语言声明函数位置 c语言声明函数和定义函数( 五 )


但是有时这样写并没有产生错误?。渴紫龋?C语言的错误不一定反应在编译、链接或运行过程中 。你输出一个垃圾值也可能一路通过编译、链接或运行 , 但这不说明你的代码没有错误,更不能说明这样的代码正确、有意义 。其次,这样的写法在有些编译器下程序会产生崩溃或得到警告 。这说明这种写法至少不普遍性适用的 。可以说 , 如果不是C99标准,这种写法根本没有立锥之地 。
C99给了这种写法以立足之地么?从某种意义上也许可以这样理解 。因为KR没承认过这种写法,C90根本不承认这种写法,C99虽然没有正式承认这种写法,但为这种写法留了一个后门:“It shall be defined ……or in some other implementation-defined manner” 。这意思就是说,如果编译器明确声称允许void main()这种写法的话 , 那么C99不再象C90那样简单认为这种写法违背C标准 。
但是不管怎么说,这种写法最多是某些编译器的一种“方言土语” , 如果没有特殊理由 , 比如仅仅是工作在某个特殊环境,且仅仅使用特定的编译器而根本不考虑程序的可移植性,为什么不写普遍适用的形式呢?
既然很多C语言专家都认为“void main()”非常邪恶 , C99为什么包容这种写法呢?很难确定C99是否就是打算专门想把这种写法也“收容”在标准之列 。因为除了void main(),还有另外一些main()函数的写法被C90排除在标准之外了 。而现在 , 这些写法在理论上也具备了符合C99标准的可能性 。
还有什么样的main()函数?很多编译器都支持下面的main()的写法:
?
12345
int main(int argc, char *argv[], char *env[]){ /* */ return 0;}
居然有3个形参,那个env是做什么用的?那个参数可以使程序获得环境变量 。
什么叫环境变量?简单地讲可以理解为操作系统记录的一些数据 , 比如计算机的名字 , 操作系统放在哪里等等 。应用程序在运行时可能要用到这些信息 , 这时可以通过env这个参数来获得 。
如果编译器不支持main()的第三个参数怎么办?标准库函数也可以达到同样的目的 。
?
12
#include stdlib.hchar *getenv(const char *name);
是否可以说void main()和int main(int argc, char *argv[], char *env[])也符合C99标准呢?恐怕还不能这么说,现在只是不能说这两种写法一定不符合C99标准 。但这两种写法不符合C90标准是确定的,这两种写法的可移植性很差也是确定无疑的 。C99标准在这里写的很模糊,没有进一步界定“implementation-defined manner”的含义 。除非编译器声明遵守C99标准,且容许这两种写法,否则断言这两种写法符合C99标准属于空穴来风 。
有人说“C99建议把main函数指定为int型”,这种说法对吗?显然不对 。因为C99并非绝对不包容返回值非int类型的main() 。正确的说法是,C90要求main()函数的返回值一定得是int型 。但C90容许不写那个int , 而C99则要求必须写上这个“int” 。
下面这种风格如何?
?
123456
#include stdio.hint main(){ printf("This is a C program.\n"); return 0;}
这个写法有点不伦不类 。返回值的类型int写了,这个和C89的倡导或C99的要求一致,但是()里面什么都不写 , 又与标准的所倡导的风格不符,所以说不伦不类 。这种写法目前的标准依然容许,但属于标准目前尚能容忍的但即将过时的(obsolescent)写法,被抛弃只是早晚的问题 。这种写法就如同古代的函数形参的写法一样:
?
123456
main(argc,argv)int argc;char *argv[];{ /*…… */ return 0;}
都属于历史的垃圾 。

推荐阅读