命名空间
变体
操作

主函数

来自 cppreference.cn
< cpp‎ | 语言
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句 (循环)
for
范围 for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (在 C++17* 中弃用)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
 
 

程序应包含一个名为 main 的全局函数,它是宿主环境中程序的指定启动点。它应具有以下形式之一

int main() { body } (1)
int main(int argc, char* argv[]) { body } (2)
int main(/* 实现定义 */) { body } (3)
1) 独立于环境提供的参数运行的 main 函数。
2) 接受环境提供的参数的 main 函数。
argcargv 的名称是任意的,参数类型的表示也是如此:int main(int ac, char** av) 同样有效。
3) 实现定义的类型,返回 intmain 函数。
C++ 标准建议实现定义的 main 函数将额外的(可选的)参数放在 argv 之后。
argc - 非负值,表示从程序运行的环境传递给程序的参数数量。
argv - 指向 argc + 1 个指针数组的第一个元素的指针,其中最后一个指针为空,之前的指针(如果有)指向表示从执行环境传递给程序的参数的空终止多字节字符串。如果 argv[0] 不是空指针(或者,等效地,如果 argc > 0),它指向一个表示用于调用程序的名称的字符串,或者指向一个空字符串。
body - main 函数的主体。

目录

[编辑] 解释

main 函数在程序启动时,在静态存储期的非局部对象初始化之后被调用。它是宿主环境(即带有操作系统的环境)中执行的程序的指定入口点。独立式程序(引导加载程序、OS 内核等)的入口点是实现定义的。

双参数形式的 main 函数的参数允许从执行环境传递任意多字节字符串(这些通常被称为命令行参数),指针 [argv[1]argv[argc - 1]] 指向每个字符串中的第一个字符。argv[0] (如果非空) 是指向空终止多字节字符串的初始字符的指针,该字符串表示用于调用程序本身的名称(如果执行环境不支持,则为空字符串 "")。这些字符串是可修改的,尽管这些修改不会传播回执行环境:例如,它们可以与 std::strtok 一起使用。argv 指向的数组的大小至少为 argc + 1,并且保证最后一个元素 argv[argc] 是一个空指针。

main 函数具有以下几个特殊属性

1) main 函数的主体不需要包含 return 语句:如果控制到达 main 的末尾而没有遇到 return 语句,则效果等同于执行 return 0;
2) return 的执行(或到达 main 末尾时的隐式返回)等效于首先正常退出函数(这将销毁具有自动存储期的对象 并评估 main 的任何后置条件断言(自 C++26 起)),然后使用与 return 的参数相同的参数调用 std::exitstd::exit 然后销毁静态对象并终止程序)。

main 函数有几个限制(违反这些限制会使程序格式错误)

1) 它不能在程序中的任何地方被命名
a) 特别是,它不能被递归调用
b) 不能获取它的地址
c) 它不能在 typeid 表达式 decltype 说明符(自 C++11 起) 中使用
2) 它不能被预定义,也不能被重载:实际上,全局命名空间中的名称 main 保留给函数(尽管它可以用于命名类、命名空间、枚举和非全局命名空间中的任何实体,但名为 main 的实体不能在任何命名空间中用 C 语言链接声明。
3) 它不能被定义为删除或(自 C++11 起)用任何语言链接constexpr(自 C++11 起)consteval(自 C++20 起)inlinestatic 声明。
4) main 函数的返回类型不能被推导(auto main() {...} 是不允许的)。
(自 C++14 起)
5) main 函数不能是协程
6) main 函数不能附加到命名的模块
(自 C++20 起)

[编辑] 注解

如果 main 函数是用函数 try定义的,则静态对象的析构函数(由隐含的 std::exit 销毁)抛出的异常不会被它捕获

在操作系统命令行中给出的参数转换为 argv 引用的多字节字符数组的方式可能涉及实现定义的处理

一个非常常见的实现定义的 main() 形式具有第三个参数(除了 argcargv 之外),类型为 char**,指向 执行环境变量的指针数组

[编辑] 示例

演示如何告知程序在哪里查找其输入以及在哪里写入其结果。
可能的调用:./convert table_in.dat table_out.dat

#include <cstdlib>
#include <iomanip>
#include <iostream>
 
int main(int argc, char *argv[])
{
    std::cout << "argc == " << argc << '\n';
 
    for (int ndx{}; ndx != argc; ++ndx)
        std::cout << "argv[" << ndx << "] == " << std::quoted(argv[ndx]) << '\n';
    std::cout << "argv[" << argc << "] == "
              << static_cast<void*>(argv[argc]) << '\n';
 
    /* ... */
 
    return argc == 3 ? EXIT_SUCCESS : EXIT_FAILURE; // optional return value
}

可能的输出

argc == 3
argv[0] == "./convert"
argv[1] == "table_in.dat"
argv[2] == "table_out.dat"
argv[3] == 0

[编辑] 参考

扩展内容
  • C++23 标准 (ISO/IEC 14882:2024)
  • 6.9.3.1 main 函数 [basic.start.main]

[编辑] 缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
CWG 1003 C++98 main 的受支持形参名称受到过度限制 支持所有有效的形参
名称
CWG 1886 C++98 main 函数可以用语言链接声明 禁止
CWG 2479 C++20 main 函数可以声明为 consteval 禁止
CWG 2811 C++98 N3214 之后是否使用 main 函数尚不清楚 当命名时,它被认为是已使用的

[编辑] 参见

C 文档 关于 main 函数