加载中......
输入验证码,即可复制
微信扫码下载好向圈APP, 登陆后即可进入消息页面查看验证码
只需要3秒时间
main函数即为主函数,C程序总是从main()函数开始执行的。main函数是整个C程序的执行入口,一个程序想要运行起来,必须指定main函数。各种资料和书籍对main函数的写法各有不同,甚至很多的写法都有误区,本文整理了常见的mian函数写法,并逐一测试说明。

注意:以下程序均在GCC9.2环境下编译运行,不同的编译器编译结果并不一定相同。
标准版本

C89/C99/C11标准文档中只提供了两种main函数的写法:
int main(void) { /* ... */ }

int main(int argc, char *argv[]) { /* ... */ }

C99规定:main函数必须有返回值,而且必须是int 类型的,main函数return 0表示函数正常退出,否则表示错误退出,如果没有return语句,编译器自动在目标上添加return 0。

如果把main函数当成普通函数那么除了函数名main不可变,那么其他都有可以变,返回值类型,参数列表,返回值这三种搭配会产生各种形式。
无参main函数

样式一:int main(void){/* ... */}

样式二:void main(void){/* ... */}

样式二:main(void){/* ... */}

样式一不必多说,那么其他两个是怎么出现的?样式二这种常见于老旧的教材,我记忆中那会谭浩强的书里就有这种写法。目前不少的编译器是能够编译通过的,但是这是编译器的处理并不是标准中的定义,甚至在C99之后明确规定这种就是错误写法!样式三不写返回值类型在C89标准中允许,C语言第一版中只有int一种类型,没有char,long,float等,既然只有一种类型,那么就可以不写,后来的改进版为了兼容以前的代码便规定:不明确标明返回值的,默认返回值为int,也就是说样式三等同于样式二。虽然可以编译,但在C99标准中要求编译器至少给 main() 这种用法警告,强烈不建议这么写!

使用以上的形式输出Hello World结果如下:

C语言的main函数的几种写法-1.jpg

样式一和二的结果:C89和C99下编译运行正常

C语言的main函数的几种写法-2.jpg

样式三的结果:C89和C99下编译运行正常,但是C99给出警告

样式四:int main(){/* ... */}

样式五:void main(){/* ... */}

样式六:main(){/* ... */}

样式四样式六对应着样式一样式三,唯一不同在于里面的void省去了,很多人觉得这个应该和void一样的,都是表示不带参数的意思,但实际上并不是!在C语言中func()表示的是参数类型,数目不确定,并且可以重新对它的完整参数类型和个数重新声明。但是func(void)则完全限制了不允许任何参数,即使重新声明,也不能改变。

使用func():
void func(){    printf("func()\n");}int main(void){    func();    func(1,2);    func(1,'a');    func(1,"abc");    return 0;}
C语言的main函数的几种写法-3.jpg

func()任意参数列表都可以编译运行

使用func(void):
void func(void){    printf("func()\n");}int main(void){    func();    func(1,2);    func(1,'a');    func(1,"abc");    return 0;}
C语言的main函数的几种写法-4.jpg

func(void)只要有参数直接报错

使用样式四到样式六输出Hello World结果与样式一到样式三一致,图略。
有参main函数

样式一:int main(int argc, char *argv[]){/* ... */}

样式二:void main(int argc, char *argv[]){/* ... */}

样式三:main(int argc, char *argv[]){/* ... */}

样式四:int main(int argc){/* ... */}

样式五:void main(int argc){/* ... */}

样式六:main(int argc){/* ... */}

样式七:int main(int argc, char *argv[], char *envp[]){/* ... */}

样式八:void main(int argc, char *argv[], char *envp[]){/* ... */}

样式九:main(int argc, char *argv[], char *envp[]){/* ... */}

以上的各种形式中指针数组都可以使用二级指针替换:*argv[]->**argv,*envp[]->**envp.这里不一一列出来了。

标准的main函数中的参数最多有两个:第一个参数argc(argument count)是命令行中的字符串个数。第二个参数argv(argument value)是一个指针数组,一般程序名赋值给argv[0],从argv[1]开始对各个参数依次赋值。这里的参数可选,使用一个,使用两个都可以。

一个argc参数:
int main(int argc){    printf("%d",argc);    return 0;}
C语言的main函数的几种写法-5.jpg

带上程序名,一共四个参数

两个标准参数:
int main(int argc,char *argv[]){    int i;    for ( i = 0; i < argc; i++){        printf("%s|",argv);    }    return 0;}
C语言的main函数的几种写法-6.jpg

输出所有的argv参数,这里的程序名包含路径

main函数还可以有第三个参数,用于获取环境变量,这种形式多源于编译器的扩展。但全局变量environ可以代替envp的作用,获取或者设置环境变量可以使用getenv或putenv,因此这种形式出现的很少。

三参数:
int main(int argc,char *argv[],char *envp[]){    int i;    for ( i = 0; i < argc; i++){        printf("%s|",argv);    }    printf("\n");    int j=0;    while(envp[j]){    printf("%s\n",envp[j]);    j++;    }    return 0;}
C语言的main函数的几种写法-7.jpg

最后一个参数打印了全局环境变量
返回值

main函数的返回值最终会作为程序的退出状态,0表示函数正常退出,否则表示错误退出。这也是不推荐使用void作为返回值类型的原因,一旦声明为void,在程序退出后,想要获取其退出状态也就不可以了!如果main函数的最后没有写return语句的话,C99规定编译器要自动在生成的目标文件中加入return 0,表示程序正常退出。尽管省略return语句后,也能通过编译,但仍建议最好加上return语句,养成好习惯。
其他环境

在其他领域以上规则不尽然完全适用,单片机中使用void main(void)还是很常见的。很多低级单片机的资源有限,常见的比如51单片机,基本上不会使用系统的,一般就是裸跑, 编译器初始化后直接转到main运行,不会给main传任何参数。进入main里面做一些硬件初化后,一般会进入while的死循环保持运行,直到掉电,不需要返回值,所以经常可以看到void main(void)这样的代码。

51单片机点灯:
#include <reg52.h>sbit LED=P1^0;void main(void){   LED=0;   while(1){         LED=1;}}
程序员圈
16941 查看 0 0 反对

说说我的看法高级模式

您需要登录后才可以回帖 登录|立即注册

还没人评论此主题哦