C 语言 main 函数为什么要写 return 0?简要了解main函数到底是什么
参考:Andrew Koenig《C 陷阱与缺陷(第二版)》3.10节
目录
作者在 3.10 节开头给了"最简单的 C 程序":
main()
{
}
然后说:这个程序包含一个不易察觉的错误。

错在哪?
书里的三个判断
第一,返回类型默认是 int。
函数 main 与其他任何函数一样,如果并未显式声明返回类型,那么函数返回类型就默认为是整型。但是这个程序中并没有给出任何返回值。
main() 没写 int,编译器按 int 处理。
既然声明成 int,就该有东西返回。可函数体里一句 return 都没有。
但实测编译器并不会给出提醒(VS2022)。
第二,通常情况下这没事。
通常说来,这不会造成什么危害。一个返回值为整型的函数如果返回失败,实际上是隐含地返回了某个"垃圾"整数。只要该数值不被用到,就无关紧要。
注意"只要该数值不被用到"这个前提。
第三,main 的返回值恰恰是会被用到的。

然而,在某些情形下函数 main 的返回值却并非无关紧要。大多数 C 语言实现都通过函数 main 的返回值来告知操作系统该函数的执行是成功还是失败。
典型的处理方案是,返回值为 0 代表程序执行成功,返回值非 0 则表示程序执行失败。如果一个程序的 main 函数并不返回任何值,那么有可能看上去执行失败。……
书里举的场景是软件管理系统——比如 make,它靠这个值决定下一步走不走。
程序明明跑成功了,退出码却是个垃圾数,make 那边就当成失败。
书给的两个写法
严格说来,我们前面的最简单的 C 程序应该像下面这样编写代码:

main()
{
return 0;
}
或者:
main()
{
exit(0);
}
书里最后补上了经典的 hello world:
#include <stdio.h>
main() {
printf("hello world\n");
return 0;
}
到这里书讲完了,总结就是
main 的返回值是给操作系统看的,0 表示成功,非 0 表示失败。
下面继续探究一下main()函数。
main 不写 return,真的返回垃圾吗?
在 VS 2022 上实测,四种写法(x64,Debug / Release 都是这个结果):
| 写法 | 进程退出码 |
|
| 0 |
|
| 0 |
|
| 0 |
|
| 0 |
全是 0,连不标准的 void main() 也一样。这是为什么呢?
C99(1999 年)起,标准明文规定:main 的返回类型与 int 兼容时,走到结尾的 } 等价于 return 0。 编译器照着这条规则,替你补上了那句 return。
但别急着说书错了。把 main 换成一个普通函数再试:
#include <stdio.h>
int f(void) { }
int main(void)
{
printf("f() = %d\n", f());
return 0;
}
Debug (/Od) -> f() = -2008539640
Release (/O2) -> f() = 0
(VS 2022 同时给一条 warning C4716: "f": 必须返回一个值。)
里没有任何语句给返回值赋过值,函数就退出了。所以调用方拿到的,是上一次函数调用留在那儿的东西。
把 f 改一行,让"上一次留下的东西"露出来:
int f(void) { printf("in f\n"); }
Debug (/Od) -> in f
f() = 5
Release (/O2) -> in f
f() = 0
Debug 下是 5——printf 返回"写了几个字符","in f\n" 正好 5 个。
f 没打算返回什么,就把上一个调用的结果原样交了出去。
Release 下变成 0,因为优化器重排了代码,那个 5 不再留在返回值该在的位置上。
同一个 bug,两种配置两个数。
这才是"垃圾"二字的含义:值是多少不重要,它根本没打算给一个值。
所以书说的"隐含返回垃圾整数",在普通函数上完全成立;
只有 main 被特殊照顾。
可以写char main吗?
#include<stdio.h>
char main(void)
{
printf("1");
return 'a';
}
实测是可以的 返回值是97 也就是‘a’的ASCII码
但不建议这么写,是“无厘头”的做法
main的递归调用
#include <stdio.h>
int main()
{
static int cnt = 0;
cnt++;
printf("cnt=%d\n", cnt);
if (cnt < 3)
main();
return 0;
}
可以替代一个简单的循环
但不建议这么做:
栈会累积,容易栈溢出
可读性极差,别人读代码会很迷惑
必须要写int main(void)吗?
C 里 int main() 的空括号意思是 “参数表未指定” ,不是"无参数"。
#include <stdio.h>
int main()
{
static int cnt = 0;
cnt++;
printf("cnt=%d\n", cnt);
if (cnt < 3)
main(100, 200, 300);
return 0;
}
这种情况下,即使传了没用的参数,也不会报错
#include <stdio.h>
int main(void)
{
static int cnt = 0;
cnt++;
printf("cnt=%d\n", cnt);
if (cnt < 3)
main(100, 200, 300);
return 0;
}
如果这样写,就会报错
区别就在这里。
main的参数
我们通常是这样写
int main(void)
{
}
看似main是没有参数的,但实际上是有的——
int main(int argc, char *argv[])
至于为什么,以及这代表什么。这里就不讨论了,因为我没搞明白
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)