打印

【整理】C语言之Main函数返回值问题分析

[复制链接]
6078|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xnwxq|  楼主 | 2009-8-25 20:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
多人甚至市面上的一些书籍,都使用了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 函数的定义。
     “The C programming Language(《C 程序设计语言》)用的就是 main( )。”--- 这是因为第一版的C语言只有一种类型,那就是int,没有char,没有long,没有float,…………既然只有一种类型,那么就可以不写,后来的改进版为了兼容以前的代码于是规定:不明确标明返回值的,默认返回值为int,也就是说 main()等同于int main(),而不是等同于void main()。在C99中,标准要求编译器至少给 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 函数的定义方式: [Page]
                  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 .
总而言之:
void main 主函数没有返回值  
main 默认为int 型,即 int main(), 返回整数。
注意,新标准不允许使用默认返回值,即int不能省,而且对应main函数不再支持void型返回值,因此为了使程序有很好的移植性,强烈建议使用:  
int main()  
{  
return 0; /* 新标准主函数的返回值这条语句可以省略 */

相关下载

相关帖子

沙发
中航_夏工| | 2009-8-27 15:05 | 只看该作者
写了这么多,不容易,顶下!

使用特权

评论回复
板凳
haoyouxiaosa| | 2009-8-27 21:08 | 只看该作者
单片机好像都是在死循环中,还用返回吗  不过看你总结的,不错!赞
支持用INT型

使用特权

评论回复
地板
冷漠| | 2009-8-28 08:47 | 只看该作者
本帖最后由 冷漠 于 2009-8-28 09:17 编辑

呵呵,“多人甚至市面上的一些书籍,都使用了void main( ) ,其实这是错误的。C/C++ 中从来没有定义过void main( ) 。....”

真是又一个震撼世界的高手。把那么多中外教材内容一句话都否定了!

...“C/C++ 中从来没有定义过void main( ) 。....”

void main( )是用户定义的,如果是错误的,如何能通过编译并产生出正确的OBJ代码。
请再研究研究 char  main( )是正确的还是错误的?long  main( )呢?C/C++定义过吗?

在这个论坛上,有没有 main( ) 是被调函数的情况?有?请举个例子;如果没有,那么下面:

char  main (  )  {    retern  ....;   }     
long  main (  )  {    retern  ....;  }
......

都是正确的,编译器都接受的。
什么概念用在什么地方,请讲清楚。C51不是C99。

使用特权

评论回复
5
xiezhaoyan| | 2009-8-28 09:12 | 只看该作者
既然是错误的,为什么还可以用呢?

使用特权

评论回复
6
HWM| | 2009-8-28 09:16 | 只看该作者
这只是C主程序和系统(操作系统)的一个接口,没有强制性规定。

使用特权

评论回复
7
McuPlayer| | 2009-8-28 10:05 | 只看该作者
基于windows的程序的主含函数是WinMain
主函数除了返回值外,另一个作用是OS要传递参数给用户程序,比如环境变量等。

所以说,跟这东西有关系的有:
1、C99标准
2、OS接口

使用特权

评论回复
8
yewuyi| | 2009-8-28 11:29 | 只看该作者
又不知道从那抄过来的,LZ最近发的帖子基本全是抄过来的,抄就抄把,但你至少应该写清楚原来的出处,这种没头没脑的文字有什么意义呢?

抄也没抄全,
int main()  
{  
return 0; /* 新标准主函数的返回值这条语句可以省略 */
???小朋友,这儿掉钱包了。。。

使用特权

评论回复
9
makesoft| | 2009-8-28 17:10 | 只看该作者
呵呵,没有操作系统,返回的参数给谁使用?

使用特权

评论回复
10
linqing171| | 2011-3-18 12:34 | 只看该作者
挖坟,挖坟。
返回的参数给汇编用。
CRT是用汇编做的。

使用特权

评论回复
11
sdpz| | 2011-3-18 14:13 | 只看该作者
回4楼,即使写成 char main(int fuck) 也是能运行的。
用函数指针来举例。
神马屁main只不过是个入口地址。
void *pMain;
有两个不同的main:
void foo1() {}
int foo2(int argc, char*argv[]) {}

pMain = foo1或foo2 ;
return (*(int (*)(int argc, char *argv[]))pMain)(param1, param2);

参数和返回值存放在寄存器或RAM里,想用就用,不想用就不用,这两个foo同样可以执行。

在单片机,启动代码可以这样调用main:
(*(void (*)))pMain)();

于是在C51里写:
int main(int fuck)
也没错。

而且它不一定要CALL, 只要JMP进main就可以,它对你要返回什么不感兴趣。

使用特权

评论回复
12
CC2530| | 2011-3-18 21:31 | 只看该作者
本帖最后由 CC2530 于 2011-3-18 21:32 编辑

两种观点:
1.写程序应该符合标准,一些书上的void main( ) ,还有编译器可以编译通过的,真是害人不浅,让人产生了一种错觉,以为void main( ) 这种写法是正确,其实是错误的。

2.我们只是打工者,不是科学家。void main( )服不符合标准没有什么意义。能够正确运行才最重要。void main( )以前一直这样用,从来就没出现问题。今后还这么用。

使用特权

评论回复
13
CC2530| | 2011-3-18 21:42 | 只看该作者
回4楼,即使写成 char main(int fuck) 也是能运行的。
用函数指针来举例。
神马屁main只不过是个入口地址。
void *pMain;
有两个不同的main:
void foo1() {}
int foo2(int argc, char*argv[]) {}

pMain = foo1或fo ...
sdpz 发表于 2011-3-18 14:13


也说几句。

举例这么多,只说明了一般函数可以这样处理。

在C标准里mian函数是单独拿出来的,与一般函数不一样。

C标准只规定了main的只有两种写法,再没第三种。

任何不符合这两种写法的main都是错误的。

当然,编译器尊不遵守这个标准,是另一回事。

使用特权

评论回复
14
y651503148| | 2013-4-25 11:38 | 只看该作者
刚看了一篇**也说不能使用void  我就纳闷了,我也还一直用呢,不止main  其他没有返回值的函数也是void xxx()  没发现问题,

使用特权

评论回复
15
渤海三叠浪| | 2013-4-25 12:08 | 只看该作者
51,应该用void。
不用void是错误的。
楼主强调标准。那是错误的。
比如美国人的标准时可以干涉内政。
所以所谓C啥标准编译器没有必要完全遵守

使用特权

评论回复
16
994920256| | 2013-4-25 12:23 | 只看该作者
每个C函数都必须有一个叫main()的函数,因为启动代码最终会跳转到这里执行程序,最具有可移植性的是int main( )          int main( int argc, char *argv[] ) 这两个,但现在好多编译器允许main()函数的返回值为void型,是编译器实现的特定扩展形式,返回值为int型,是为了将其返回值传递给exit(),让我们的代码运行结束后,可以将控制权交还给操作系统,具体应该看编译器具体支持什么样的扩展类型,平台不一样,结果也不同

使用特权

评论回复
17
chunk| | 2013-4-25 13:08 | 只看该作者
cstartup是我自己写的,我不需要main()。

使用特权

评论回复
18
huangxz| | 2013-4-25 14:20 | 只看该作者
chunk 发表于 2013-4-25 13:08
cstartup是我自己写的,我不需要main()。

很多c编译器需要main函数,如果没有定义就无法链接。

使用特权

评论回复
19
ayb_ice| | 2013-4-25 16:10 | 只看该作者
什么错的,C以前就是这么定义的

使用特权

评论回复
20
zhangli019| | 2013-4-27 14:17 | 只看该作者
冷漠 发表于 2009-8-28 08:47
呵呵,“多人甚至市面上的一些书籍,都使用了void main( ) ,其实这是错误的。C/C++ 中从来没有定义过void  ...

确实,在有操作系统的时候;main的返回值是返回给调用者的,在C51里面main函数是不被调用的,自然就没有返回值。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:我们都是风雨中的孩子,手牵着手才不会跌倒

162

主题

294

帖子

1

粉丝