回 帖 发 新 帖 刷新版面

主题:[转帖]C/C++ 误区一:void main()

C/C++语言误区一:void main( )

作者:antigloss 

        很多人甚至市面上的一些书籍,都使用了void main( ) ,其实这是错误的。C/C++ 中从来没有定义过void main( ) 。C++ 之父 Bjarne Stroustrup 在他的主页上的 FAQ 中明确地写着 The definition void main( ) { /* ... */ } is not and never has been C++, nor has it even been C.( void main( ) 从来就不存在于 C++ 或者 C )。下面我分别说一下 C 和 C++ 标准中对 main 函数的定义。

 

1. C

        在 C89 中,main( ) 是可以接受的。Brian W. Kernighan 和 Dennis M. Ritchie 的经典巨著 The C programming Language 2e(《C 程序设计语言第二版》)用的就是 main( )。不过在最新的 C99 标准中,只有以下两种定义方式是正确的:

           int main( void )

           int main( int argc, char *argv[] )

(参考资料:ISO/IEC 9899:1999 (E) Programming languages — C 5.1.2.2.1 Program startup)

        当然,我们也可以做一点小小的改动。例如:char *argv[] 可以写成 char **argv;argv 和 argc 可以改成别的变量名(如 intval 和 charval),不过一定要符合变量的命名规则。

        如果不需要从命令行中获取参数,请用int main(void) ;否则请用int main( int argc, char *argv[] ) 。

        main 函数的返回值类型必须是 int ,这样返回值才能传递给程序的激活者(如操作系统)。

        如果 main 函数的最后没有写 return 语句的话,C99 规定编译器要自动在生成的目标文件中(如 exe 文件)加入return 0; ,表示程序正常退出。不过,我还是建议你最好在main函数的最后加上return 语句,虽然没有这个必要,但这是一个好的习惯。注意,vc6不会在目标文件中加入return 0; ,大概是因为 vc6 是 98 年的产品,所以才不支持这个特性。现在明白我为什么建议你最好加上 return 语句了吧!不过,gcc3.2(Linux 下的 C 编译器)会在生成的目标文件中加入 return 0; 。

 

2. C++

        C++98 中定义了如下两种 main 函数的定义方式:

                  int main( )

                  int main( int argc, char *argv[] )

(参考资料:ISO/IEC 14882(1998-9-01)Programming languages — C++ 3.6 Start and termination)

        int main( ) 等同于 C99 中的 int main( void ) ;int main( int argc, char *argv[] ) 的用法也和 C99 中定义的一样。同样,main 函数的返回值类型也必须是int。如果main函数的末尾没写return语句,C++98 规定编译器要自动在生成的目标文件中加入 return 0; 。同样,vc6 也不支持这个特性,但是 g++3.2(Linux 下的 C++ 编译器)支持。

 

3. 关于 void main

        在 C 和 C++ 中,不接收任何参数也不返回任何信息的函数原型为“void foo(void);”。可能正是因为这个,所以很多人都误认为如果不需要程序返回值时可以把main函数定义成void main(void) 。然而这是错误的!main 函数的返回值应该定义为 int 类型,C 和 C++ 标准中都是这样规定的。虽然在一些编译器中,void main 可以通过编译(如 vc6),但并非所有编译器都支持 void main ,因为标准中从来没有定义过 void main 。g++3.2 中如果 main 函数的返回值不是 int 类型,就根本通不过编译。而 gcc3.2 则会发出警告。所以,如果你想你的程序拥有很好的可移植性,请一定要用 int main 。

 

4. 返回值的作用

        main 函数的返回值用于说明程序的退出状态。如果返回 0,则代表程序正常退出,否则代表程序异常退出。下面我们在 winxp 环境下做一个小实验。首先编译下面的程序:

           int main( void )

           {

                  return 0;

           }

然后打开附件里的“命令提示符”,在命令行里运行刚才编译好的可执行文件,然后输入“echo %ERRORLEVEL%”,回车,就可以看到程序的返回值为 0 。假设刚才编译好的文件是 a.exe ,如果输入“a && dir”,则会列出当前目录下的文件夹和文件。但是如果改成“return -1”,或者别的非 0 值,重新编译后输入“a && dir”,则 dir 不会执行。因为 && 的含义是:如果 && 前面的程序正常退出,则继续执行 && 后面的程序,否则不执行。也就是说,利用程序的返回值,我们可以控制要不要执行下一个程序。这就是 int main 的好处。如果你有兴趣,也可以把 main 函数的返回值类型改成非 int 类型(如 float),重新编译后执行“a && dir”,看看会出现什么情况,想想为什么会出现那样的情况。顺便提一下,如果输入 a || dir 的话,则表示如果 a 异常退出,则执行 dir 。

 

5. 那么 int main( int argc, char *argv[], char *envp[] ) 呢?

    这当然也不是标准 C 里面定义的东西!char *envp[] 是某些编译器提供的扩展功能,用于获取系统的环境变量。因为不是标准,所以并非所有编译器都支持,故而移植性差,不推荐使用。

欲了解更多,请点击:[url=http://users.aber.ac.uk/auj/voidmain.shtml]http://users.aber.ac.uk/auj/voidmain.shtml[/url]


本人初学C,总是看到“void main()”这种用法,想知道上面说的是否是对的[em18]

回复列表 (共27个回复)

11 楼

mark,但不参加讨论,只说明一下为什么“在 C89 中,main( ) 是可以接受的”?

最初的C语言中,只有一种变量类型,那就是int,因为只有一种类型,所以这种类型的标识 --- int --- 可以被省略,后来的C语言版本为了兼容以前的代码,所以规定没有显式指明函数返回类型的函数,其返回类型默认为int。而到C99时,要求编译器对未显式指明函数返回类型的行为起码给出一个警告。

12 楼

还是感谢搂主,我一直都用int main()和return语句,这是个好习惯,
根本不需要voi main(),多余!

13 楼

可是有很多书上都是在写用 void main( )的,这是为什么?而且还把它归为了C++程序的基本结构之中,我晕,我是新手,有很多不明白请指教.

14 楼

以前学c语言就是这样的,呵呵!c++也就习惯成自然了。

15 楼

我测试过了,不管函数的返回值是return 0或者return 1,在DOS下,运行a.exe之后,再键入echo %errorlevel% 现实结果都是0;而且键入a&&dir后,dir 都可以运行,请问这是为什么???

16 楼


你的谬论是是不对的   
你看的书很多
但不要认为所有书记载的都是真理

17 楼

我还是个初学者 相信自己 不要在这些细节上纠缠不清 因为你学习的是一种思想. 当你什么都忘记的时候 你不会忘记的东西才是你真正学到的 我认为

18 楼

[quote]To tell you the truth:

Please don't read some series such as "C/C++ 误区二" "C/C++ 误区三" etc

Those people think he/she knows a lot and start to write series to teach others, most of them (not all of them) are misleading!!!!

The samething happens in other Java forums too, someone almost know nothing about Java, started to write "classic 误区 in Java..."

I decided not to read those garbage, just in case I want to criticize again...

But I found C语言爱好者 started to comment, that made me come here...
[/quote]哇,很有见解

19 楼

[code]

不过不管怎样!
我想我们还是用:
(1) int main(void)
(2) int main(int argc, char *argv[])
(3) main()

千万不要用:
void main()
因为这在GCC (ANSI C)下是不允许的!
============================================
error: the main is not int !
[/code]

20 楼

也不用太扣,这个不是很重要,换个环境编译不了,也不就一分钟的事情,改改就行了

用一些IDE的模板自动生成代码,这些懒得去管了~

我来回复

您尚未登录,请登录后再回复。点此登录或注册