C之main函数和命令行参数(三十)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C之main函数和命令行参数(三十)相关的知识,希望对你有一定的参考价值。

        我们知道在 C 语言中,程序是从 main 函数开始运行的,我们称其为主函数。我们来看看下面几种 main 函数定义正确吗?


技术分享图片

        那么 main 函数的原型到底是什么呢?我们来看看编译器怎么说,我们分别编译下四种 main

 函数的形式,经过编译后,程序可以编译通过并且执行完成。那么最标准的 main 函数的原型是上面的第四种,main 函数是操作系统调用的函数,操作系统总是将 main 函数作为应用程序的开始并且将 main 函数的返回值作为应用程序的退出状态。那么 C 编译器为什么要支持这么多不同的 main 函数原型呢?我们来做个实验,代码如下

#include <stdio.h>

int main()
{
    printf("hello\n");
    
    return 99;
}

        我们在 BCC 编译器下编译看看,结果肯定是打印 hello 了。但是我们返回的是 99,我们顺便打印下环境变量的值,看看有什么玄机

技术分享图片

        我们看到打印的环境变量的值为 99。如果我们将上面程序中的 return 后面改成 0。再来编译看下环境变量的值是多少

技术分享图片

        我们看到环境变量的值变成 0 了。那么 main 函数的返回值是将它返回到系统中并保存下来。那么回到我们之前所说的问题,在以前的程序中,好多中编程写法。我们为了兼容以前所有的程序,编译器就必须得支持所有的 main 函数的写法。那么程序执行时可以向 main 函数传递参数,格式:int main(int argc, char *argv[], char *env[])a> argc - 命令行参数个数;b> argv - 命令行参数数组;c> env - 环境变量数组;我们平时见到的大多数是带前两种的 main 函数的写法。

        那么在gcc编译器中,常见用法如下:

技术分享图片

        我们下来看个示例代码,代码如下

#intclude <stdio.h>

int main(int argc, char* argv[], char* env[])
{
    int i = 0;
    
    printf("============== Begin argv ==============\n");
    
    for(i=0; i<argc; i++)
    {
        printf("%s\n", argv[i]);
    }
    
    printf("============== End argv ==============\n");
    
    return 0;
}

        我们来看看编译效果

技术分享图片

        我们可以看到打印出了 ./a.out。也就是说打印出了除过 gcc 以外的命令行参数,我们再以下面这种方式来打印呢

技术分享图片

        那么我们可以看到打印出了除 gcc 以外的所有参数。讲到最后,我们再来讨论个有意思的问题:main 函数一定是程序执行的第一个函数吗?咋一听,就是啊,我们平时书上所见到的,还有老师说的都是这样的哈。那么我们来做个实验,代码如下

#include <stdio.h>

#ifndef __GNUC__
#define __attribute__(x) 
#endif

__attribute__((constructor))
void before_main()
{
    printf("%s\n",__FUNCTION__);
}

__attribute__((destructor)) 
void after_main()
{
    printf("%s\n",__FUNCTION__);
}

int main()
{
    printf("%s\n",__FUNCTION__);
    
    return 0;
}

        我们看到如果是 GUNC 编译器的话,便定义 __attribute__ 宏。通过这个宏,我们分别声明了两个函数,我们来看看编译结果

技术分享图片

        我们看到竟然在 main 函数的前后分别执行了这两个函数。感觉很神奇,那么这个 __attribute__ 宏便是我们 gcc 编译器所特有的属性关键字。使用就可以在 main 函数的执行前后再去执行别的函数。我们再来看看在 BCC 编译器中,它还支持吗

技术分享图片

        我们看到它不支持那个 __FUNCTION__ ,我们便将他换成对应的字符串。编译后的结果是只打印了 main,也就是说它在 main 函数前后并没有去执行那两个函数。所以这个特性也是编译器特有支持的,但起码说明了在现代编译器中支持在 main 函数前调用其他函数


        欢迎大家一起来学习 C 语言,可以加我QQ:243343083

以上是关于C之main函数和命令行参数(三十)的主要内容,如果未能解决你的问题,请参考以下文章

linux下,在调用main函数之前怎样得到命令行参数argc和argv

传递命令行参数示例代码 (C 和 Python)

C 语言数组 ( 指针数组用法 | 命令行参数处理 )

162VC++的main函数接收命令行参数

162VC++的main函数接收命令行参数

C之数组参数和指针参数(三十一)