news 2026/10/1 11:21:31

C 语言 main 函数为什么要写 return 0?简要了解main函数到底是什么

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C 语言 main 函数为什么要写 return 0?简要了解main函数到底是什么

参考:Andrew Koenig《C 陷阱与缺陷(第二版)》3.10节

目录

书里的三个判断

书给的两个写法

main 不写 return,真的返回垃圾吗?

可以写char main吗?

main的递归调用

必须要写int main(void)吗?

main的参数


作者在 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 都是这个结果):

写法

进程退出码

int main() { }

0

void main() { }

0

int main() { printf("hi\n"); }

0

void main() { printf("hi\n"); }

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[])

至于为什么,以及这代表什么。这里就不讨论了,因为我没搞明白


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 11:21:17

4381张手持刀图像数据集清洗与YOLOv8训练实战

简介&#xff1a;本资源是面向计算机视觉开发者与AI初学者的手持刀具行为检测专用数据集&#xff0c;专为YOLO系列目标检测算法&#xff08;支持YOLOv5/v7/v8/v9/v10/v11&#xff09;训练与验证设计&#xff0c;适用于校园安防、公共区域异常行为识别等实际场景。数据集共4381张…

作者头像 李华
网站建设 2026/10/1 11:21:13

Windows Server 2025 原版ISO下载校验与安装部署指南

最近好多朋友私信问我&#xff1a;Windows Server 2025 的官方原版 ISO 到底该从哪下载&#xff0c;为什么看到的文件名后缀有 26100.1742、26100.32370 这种差异&#xff0c;所谓“2月更新”版本是不是越新越好&#xff0c;标准版和数据中心版在下载和安装时怎么取舍。这篇我就…

作者头像 李华
网站建设 2026/10/1 11:20:44

这是一篇自我介绍

你好&#xff0c;我叫小雪&#xff0c;是一名C语言初学者。以下是我的一些学习规划&#xff1a;编程目标&#xff1a;我的目标是将C语言熟练掌握并能够运用C语言参与程序编写&#xff0c;我也将会以C语言为基础辅助学习更多编程语言时间安排&#xff1a;我每周将花费10个小时以…

作者头像 李华
网站建设 2026/10/1 11:20:11

Spring Cloud 分布式日志架构实战:EFK+Kafka+TraceId全链路

做 SpringCloud 项目&#xff0c;最难搞的往往不是服务拆分、熔断降级&#xff0c;而是日志。服务一拆&#xff0c;日志跟着散落一地&#xff0c;排查一个订单超时问题要翻七八个服务的文件&#xff0c;这个我深有体会。所以前阵子花了两周时间&#xff0c;从 0 开始&#xff0…

作者头像 李华
网站建设 2026/10/1 11:20:07

Linux查看文件最后100行:tail命令原理、实战与避坑指南

有人问"如何查看文件的最后100行"&#xff0c;我第一反应是&#xff1a;这不就是Linux下最经典的需求之一吗&#xff1f;无论是排日志、查报错、看程序输出&#xff0c;还是处理一个大文件的尾部内容&#xff0c;翻到文件末尾永远是那个高频动作。我和这个命令打了十…

作者头像 李华
网站建设 2026/10/1 11:18:43

VC6.0工程中GDI+加载PNG并实现透明绘制的实战指南

简介&#xff1a;面向VC6.0环境下使用C进行图形界面开发的程序员&#xff0c;这份资源专门解决PNG图片加载与透明化处理问题。示例基于GDI实现&#xff0c;覆盖从环境配置、头文件包含、颜色矩阵设置到绘制与资源释放的完整流程&#xff0c;适合需要在旧版开发环境中补足图像处…

作者头像 李华