主函数

来自cppreference.com
< c‎ | language

每个要在宿主环境运行的编码 C 程序都含有称作 main 的函数定义(非原型),它是函数的受指定起始点。

int main (void) { body } (1)
int main (int argc, char *argv[]) { body } (2)
/* 其他实现定义签名 */ (C99 起) (3)

参数

argc - 代表程序所运行的环境传递给程序的参数数量。
argv - 指向 argc + 1 个指针的数组的首元素的指针。数组末元素为空指针,而若前面有元素,则它们指向表示从宿主环境传递给程序的参数的字符串。若 argv[0] 不是空指针(或等价地 argc > 0 ),则它指向表示程序名的字符串。若程序名从宿主环境不可用则该字符串为空。

名称 argcargv ,还有这些参数的类型表示是任意的: int main(int ac, char** av) 同样合法。

main 的常见实现定义形式是 int main(int argc, char *argv[], char *envp[]) ,其中第三参数类型为 char*[] ,指向指向宿主环境变量的指针的数组

返回值

若使用返回语句,则返回值会用作隐式调用 exit() 的参数(细节见下)。值零和 EXIT_SUCCESS 指示成功终止,值 EXIT_FAILURE 指示不成功终止。

解释

在程序启动时,初始化所有静态存储期对象后调用 main 函数。它指明执行于宿主环境(即在操作系统中)的程序入口点。任何独立程序(引导程序、操作系统核心等)的入口点的名称和类型是实现定义的。

主函数的双参数形式允许从执行环境传递任意的多字节字符串(常称作命令行参数)。指针 argv[1] .. argv[argc-1] 指向每个这些字符串的首字符。 argv[0] 指向代表用于调用程序自身的名称的,空终止多字节字符串的首字符(或者若宿主环境不支持此做法,则保证 argv[0][0] 为零)。

若宿主环境不能一同提供大写和小写字母,则转换命令行参数为小写。

字符串可修改,而且任何修改会留存到程序终止时,尽管这些修改不会传播回宿主环境:例如能以 strtok 使用它们。

argv 所指的数组大小至少是 argc+1 ,并保证末元素 argv[argc] 为空指针。

main 函数拥有几个特殊属性:

1) 程序不能提供此函数的原型
2) 若主函数的返回类型与 int 兼容,则从对 main 的初次调用(但不是任何后继、递归调用)返回,等价于以主函数返回值为参数执行 exit 函数(将调用 atexit 所注册的函数,冲入并关闭所有流,删除 tmpfile 所创建的文件,并返还控制给执行环境)。
3)

若 main 函数执行不指定值的 return ,或同样地未执行 return 就抵达结尾的 } ,则返回给宿主环境的终止状态未定义。

(C99 前)

若 main 函数的返回类型与 int兼容(如 void main(void) ),则返回给宿主环境的值未指定。若返回类型与 int 兼容且控制抵达结尾的 } ,则返回给执行环境的值与如同执行 return 0; 的结果相同。

(C99 起)

示例

演示如何告知程序其寻找输入处及写结果处。 调用: ./a.out indatafile outdatafile

#include <stdio.h>
 
int main(int argc, char *argv[])
{
    printf("argc = %d\n", argc);
    for(int ndx = 0; ndx != argc; ++ndx)
        printf("argv[%d] --> %s\n", ndx,argv[ndx]);
    printf("argv[argc] = %p\n", (void*)argv[argc]);
}

可能的输出:

argc = 3
argv[0] --> ./a.out
argv[1] --> indatafile
argv[2] --> outdatafile
argv[argc] = (nil)

引用

  • C11 standard (ISO/IEC 9899:2011):
  • 5.1.2.2.1 Program startup (p: 13)
  • C99 standard (ISO/IEC 9899:1999):
  • 5.1.2.2.1 Program startup (p: 12)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 5.1.2.2 Hosted environment

参阅