分享

深入理解C语言main函数的参数

 乐创客搬运工 2021-04-29

文/Edward



 1  命令就是程序
我想绝大多数看这篇文章的读者基本上都用过Windows操作系统下的命令提示符。比起图形化界面的操作,如果熟悉了Windows的命令提示符,你将会更快地操作这个操作系统。Windows图形化界面如图1所示。

图1 Windows图形化界面

不过,在Windows底下,大部分操作者还是习惯于图形化界面的操作,因为作为一个商用化个人电脑操作系统,Windows的图形化界面做的非常流利,功能非常齐全。而如果你是一名服务器运维人员,你的服务器操作系统是Linux,而且Linux主机位于云端,那么你在运维的时候大概率会通过ssh工具远程登陆,展开日常的运维工作。此时,这种Linux下的终端命令操作,将会是你日常的操作,如图2所示。

图2 Linux下的终端界面

在操作Linux终端时,我们会在终端里面输入常用的命令,在Linux操作系统“一切皆文件”的设计哲学下,你日常输入的这些命令,其实都是一个个“小程序”。然而,几乎所有的操作系统都一样,你想要操作一个命令,这个命令对应的可执行文件必须位于操作系统的环境变量中,在Linux操作系统下,这个环节变量的名称叫做“PATH”,我们可以使用”echo $PATH”命令将环境变量打印出了,如图3所示。

图3 Linux下的环境变量

通过环境变量的打印,我们可以清楚的看到此Linux操作系统的环境变量路径,只要可执行文件或者链接(软连接)文件位于这些文件目录下,那么我们直接在终端里面输入对应的应用程序名称即可运行。
现在,我们使用“cd /bin”命令打开根目录下的“bin”文件夹,我们可以发现很多平时常用的命令,如“cp”,“chmod”等,如图4所示。

图4 /bin文件夹下的可执行文件

 2  Linux下命令执行的原理
上述内容,我们大致了解了Linux下操作命令终端运行可执行文件的原理,这些命令说到底都是应用程序。但是大家是否想过,这些命令在运行时后面可以跟上命令选项,如“ls -l”可以列出当前文件夹下所有文件的详细信息,“ls -s”可以列出所有文件的大小。那么命令后面的参数是如何传进命令的应用程序里面的呢?如图5所示。

图5 ls命令不同参数下的输出

 3  C语言main函数的入口
这些Linux命令程序大多都是采用C语言开发而成的,我们平时都知道,C语言整个程序的唯一入口就是“main”函数,一般我们在做一些简单程序的时候都是用“int main(void)”的形式来定义主函数,而Linux下,一个C语言“main”函数的标准原型应该是“int main(int argc, char *argv[], char *env[] );”,其中的三个参数分别是:
int argc:传入参数的数量;
char *argv[]:传入的参数列表;
char *env[]:环境表地址。
在ANSI C中,规定main函数只有两个参数,argc和argv,而且第三个参数与全局变量environ相比也没有带来更多益处,所以POSIX.1也规定应使用environ而不使用第三个参数。通常用getenv和putenv函数来存取特定的环境变量,而不是用environ变量。所以我们见到的main函数的原型多是下面这种 形式:“int main ( int argc, char* argv[]);”。
比如,我们假设在Linux下有一个“小程序”x,在我们使用x命令的时候,后面会有可变的参数a,b,c。一般我们使用这个x命令的时候,它的形式为“x  ”,也就是说,x后面可以跟0个,1个,2个,3个参数,那当这个命令执行的时候,传入x的main函数时,“agrc”表示参数个数,如当用户使用“./x a b”运行这个程序时,“agrc”为3,而这时候,*agrv[]这变成了长度为3的字符串数组,其中agrv[0]=”./x”,agrv[1]=”a”, agrv[2]=”b”。按照这个思路,我们可以写出如图6所示的代码。

图6 x命令的实现

最后,我们只需要将x可执行文件放到环境变量路径中去,就可以在终端的任何地方运行这个x命令了。由于x名称太过简单,我们首先先将x改名成“xccmd”,再将其移入“/usr/sbin”文件夹中。接着,我们退到根目录底下来运行命令“xccmd a b c d e f”。如图7所示。

图7 将编译结果添加到环境变量

以上就是Linux操作系统下添加自定义程序的方法,Windows下也适用,如果想实现具体的功能,只需要在代码里面实现即可。

 附 程序源码
#include <stdio.h>int main(int argc, char* argv[]){ int i; printf("argc:%d\n", argc); for(i=0;i<argc;i++) { printf("argv[%d]:%s\n", i, argv[i]); } return 0;}


    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多