Namespaces
Variants

Main function

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

程序应包含一个名为 main 的全局命名空间函数,该函数是托管环境中程序的指定起始点。它必须采用以下形式之一:

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

目录

说明

main 函数在完成具有静态 存储期 的非局部对象 初始化 后,于程序启动时被调用。它是 托管环境 (即具备操作系统)下程序执行的指定入口点。而 独立环境 程序(引导程序、操作系统内核等)的入口点由具体实现定义。

双参数形式的 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 函数的任何 后置条件断言 (since C++26) ),然后以与 return 参数相同的参数调用 std::exit std::exit 随后会销毁静态对象并终止程序)。

main 函数具有若干限制(违反这些限制将导致程序格式错误):

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

注释

如果 main 函数被定义为带有 函数 try ,由静态对象析构函数(通过隐式 std::exit 销毁)抛出的异常不会被其 捕获

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

一种非常常见的实现定义形式的 main ( ) 具有第三个参数(除了 argc argv 之外),其类型为 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++标准。

缺陷报告 应用于 发布时行为 正确行为
CWG 1003 C++98 main 函数支持的参数名称限制过于严格 支持所有有效参数
名称
CWG 1886 C++98 允许 main 函数声明时使用语言链接规范 禁止使用
CWG 2479 C++20 允许将 main 函数声明为 consteval 禁止使用
CWG 2811 C++98 N3214 之后是否使用 main 函数不明确 被命名时即视为使用

参见

C 文档 关于 main 函数