问题的起因:
最近在自学C++,照着MOOC上东北大学的面向对象程序设计课上的代码敲,可是不能在我的Xcode上运行,提示error。
如上图所示,当然这个主函数我没写完。于是我开始发自内心拷问自己,为什么连这个都会敲错,写了一年C代码了连个开头的int main(void)
都会搞错吗?越想越怪,再去看一下MOOC上董晓梅老师的写法,确实是void main()
!
思维再发散些,回想起了大一学C的时候,当时我是跟着翁恺老师学的,再加上平时用macOS系统Xcode写代码,格式相对比较统一,对于主函数都是标标准准的int main(void)
。而学校里相对于代码编写方面却没有相关的教育,很多同学都随心所欲,具体我也不举例了。回归正传,有一次室友请教我一个问题,我在看他代码的时候发现了void main()
这种写法,当时马上就提出了这个错误,但是他反驳了我说老师上课就是这么写的,而且这样写可以少打三个字母。emmm,我并没有在自己电脑上尝试,我只知道很多人都这么用,直到今天在Xcode上找到的error引发了我的思考。
C规则发展史
查阅了相关资料,我发现void main()
这个用法并没有一个明确的规定,main()
可以接受void返回值,并且 Dennis M. Ritchie 的经典巨著 The C programming Language 中就是这么写的,也难怪很多人会受其影响。不过这都是上古年代的法则了啊,我们先来看看 C 标准的发展历史吧。
规则 | 年份 |
---|---|
K&R C or 经典C | 1987 |
C89 or ANSI C | 1989 |
C90 or ISO C | 1990 |
C95 | 1995 |
C99 | 1999 |
C11 | 2011 |
随着时代的进步,C规则也在不断完善和进步,许多老的写法不再适用,说起这个我就想起了 Python2 和 Python3,新规则的发布导致大部分程序需要重新编写。还有 Swift 语言,作为苹果自家的儿子成长也是特别的快,但就是因为怕规则发布太快远远超过我的学习进度而放弃了学习。
如果你还在使用那些采用老规则的编译器的话,会发现写法真的是不一样。例如“//”注释是在C99标准中才新引入的,如果你的编译器用的C89/C90标准来编译C程序。你的程序中使用了“//”注释,很显然编译器会报错。而我的Xcode也是一样,在遇到了 C89 对主函数返回值定义的规则时出现了报错。
最新准则
在 C99 标准中,只有以下两种定义方式是正确的:
int main( void )
int main( int argc, char *argv[] )
那就更不用说 C11 啦。之后我在我买的 C++ Primer 中也找到了作者说main()
函数的返回类型必须是 int
类型,即整数类型。main()
函数的返回值应该定义为 int 类型,C 和 C++ 标准中都是这样规定的。这样程序才能告诉操作系统是否成功执行完毕。所以我们的程序也总是以 return 0;
结尾,0表示程序正常结束。很多同学都会使用不对的形式写main
函数,并且省略末尾的 return 0;
对于他来说确实省了不少事,但是作为一个阅读代码的人来说却很令人头疼。并且没有任何准则说明这样写的正确的,所以遇到比较新的编译器的时候编译就会出错。关于最新的 C11 可以详见 https://webstore.ansi.org/
总结
我再次呼吁大家,作为一位程序员,秃头不可怕,不要让读你代码的人也难受到秃头,养成一个好的代码书写风格十分重要!当然风格每个人都不一样,我指的是那些固定的格式,有的时候多写一些代码或者加上注释并没有令程序难懂或者复杂,反而增加了其可读性。
我看了一学期的代码,各种千奇百怪:用拼音作函数名;单判断语句不写大括号;从 a 到 z 的变量名;同一区块不同缩进的语句……哎呀说好不举例的结果还是写了,大家还是自行理会吧。
最后给出标准的主函数格式一定要记住哟:
int main(void){ // 当然这边的void可以省略,尽量还是留着
//代码块
return 0;
}