C语言中函数main的参数argc和argv是什么

在 Xcode 中新建一个 macOS 平台 Command Line Tool,使用 C 语言,会发现 main 带了两个参数:argcargv。如下:
请添加图片描述
argc被程序唤起的命令行参数的数量,用于统计参数数量。这里会导致你有一个误区,在下面argv[]部分细说。需要注意的是,虽然一些程序支持-abcd这种合在一起的程序,但是 C 会将其认为是一个,需要手动去改。

argv这里需要细致说一下,之前写的太简洁了,评论有人没看懂,有一些底层逻辑需要说明一下。

之前写的版本为:

argv是一个指向一个字符串数组的指针,数组包含了参数,每个字符串就是一个参数,最后一个元素为0。不过一般习惯使用多级指针来操作字符串。

现在看来确实太简洁了,而且很多人对于数组和指针搞不太清楚,下面详细解释一下,最后进行反省思考。

char *argv[]表示argv[]是一个存放字符类型元素地址的数组,因为 C 中是有字符串的概念的:将每个字符存放在 char 数组,最后一个元素为\0表示字符串的结束。printf(%s)就是输出字符串。并且一般使用argv指针来访问、处理argv[]数组的内容。
C语言中,数组等价于一个指针加偏移量。所以可以把argv当作指向一个指针数组argv[]的指针,不用定义,直接可以用。(指针的核心在于“指”,比如说a是个指针,那么它会指向一块空闲的内存,然后使用这部分内存。而数组,比如这里的argv则是直接是数组的位置)
argv[]数组中存放的的指针指向输入命令的各部分(调用程序、选项、参数)。Shell 中输入的命令通过判断空格进行分割,然后将字符串的头地址放入argv[]数组中,最后放入一个0,表示空指针。
比如说如果 Shell 输入为echo hello, world!,那么argv[]数组存放的指针有 4 个:

  1. 值为echo\0头地址的指针;
  2. 值为hello,\0头地址的指针;
  3. 值为world!\0头地址的指针;
  4. 空指针0

像这条调用程序后面直接就是参数的很容易判断,直接数组第二个开始即可。
但是很多程序是要判断情况的,也就是选项,开发者应该怎么判断选项和参数呢?
一般习惯使用多级指针来操作字符串。前辈们很聪明,利用这点发明了“UNIX 风格”的命令,比如说ls -s .这种命令,选项前面加一个横杠-,这样就可以区分开二者了。
按照 UNIX 的代码惯例,上来直接跳过第一个,然后判断指针指向的字符串第一个字符是不是-,如果是的,那么进入一个switch判断,用case列出多种支持的情况下,应该执行什么代码。例如下面这样就可以判断选项和处理参数:

int c;
while (--argc > 0 && (*++argv)[0] == '-' {
	while (c = *++argv[0] {
		switch(c){
		case 'x':
			...
			break;
		case 'n':
			...
			break;
		default:
			printf("xxx: illegal opyion %c\n", c);
			...
			break;
		}
	}
}

最后逐句思考一下自己之前的版本为什么会有人看不懂。原文截图如下:
请添加图片描述
argv是一个指向一个字符串数组的指针,数组包含了参数”:“argv”这种对于很多人来说就是数组本身。但是一般情况下,如果单独说“argv”,指的是数组的指针。如果指的是数组,需要用“数组 argv”、“argv 数组”、“argv[]”来表示。因为前面说到过,数组和指针关系十分密切,所以原文我加了代码样式,如果在代码中,argv就直接表示为指针。并且一般代码中,数组是直接通过指针来使用的(这样的好处是长度不用预先设置好)。但是在我也问了一下我朋友之后,才知道很多人不清楚这点,以后还是要详细说明一下这种东西。
“每个字符串就是一个参数,最后一个元素为0”: 这句话的问题在于有一点歧义,加上省略了太多东西(看上面的解释也看得出来)。我的意思“程序运行时,会自动将从输入的获取的字符串分割成多个字符串,然后将这些字符串存放在 argv 数组,数组中最后一个元素被存放为空指针0”。导致歧义的原因是使用了从句。在中文中使用从句确实会导致这个问题,以后注意。
“不过一般习惯使用多级指针来操作字符串”: 这个属于我只当笔记记了,这个如果没有看过一些源码的人根本看不懂在说什么东西,心理估计是“你说这个谁懂啊.mp4”。所以以后还是要详细说明一下,当作记录。不然我现在记得什么情况,过了一两年自己也看不懂了。

希望以后博客当中不要再出这些问题了,对于之前打开这篇博客没得到解决的人说一声抱歉。

2023-11-23 更新:
最近发现了一种新方法,写了篇博客《C语言获取命令行选项(option/flag)和输入的内容的一种巧妙的办法》

  • 7
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值