我在 C 教程中找到的一行代码让我感到困惑。代码如下:
int main(int argc, char *argv[]){
...
char **inputs = argv+1; // This is the confusing line
...
return 0;
}
我无法理解如何将数组分配给这样的指针。如果有人能为我澄清这一点,我会很高兴。提前谢谢!
我在 C 教程中找到的一行代码让我感到困惑。代码如下:
int main(int argc, char *argv[]){
...
char **inputs = argv+1; // This is the confusing line
...
return 0;
}
我无法理解如何将数组分配给这样的指针。如果有人能为我澄清这一点,我会很高兴。提前谢谢!
假设您执行这样的程序
C:\Temp>myprog.exe 你好世界
操作系统获取这些字符串并将它们放在一起,在一个空终止字符串数组中:
{ "myprog.exe", "hello", "world", NULL }
然后它调用main()
并将字符串的数量 (3)argc
和指向该数组中第一个字符串的指针传递给它。这个指针是调用argv
,并且是类型char**
(char* argv[]
只是语法上的方便,在函数签名内部语义等价)
但是您只想inputs
保存字符串“hello”和“world”,因此您使用此指针 ,argc
并指向下一个元素 - 向其添加一个:
char **inputs = argv+1;
现在inputs
指向{ "hello", "world", NULL }
.
argv
是一个指向字符串的数组指针,最后一个指针为空。假设您的可执行文件名称是exe
并且您像这样运行它:
$ exe fist second
然后argv
是:
+----------+
argv---►| "exe" |
+----------+
argv + 1---►| "first" |
+----------+
argv + 2---►| "second" |
+----------+
argv + 3---►| null |
+----------+
* Notice last is null.
所以char** input = argv + 1
指向作为第一个输入参数的“第一个”字符串。
如果您的打印argv[0]
输出%s
将"exe"
是您的可执行文件名称,并且如果您打印input[0]
输出%s
将是"fisrt"
字符串。
注意:即使你不传递任何参数intput
也会指向NULL(有效地址)。
(这样做的目的是指向输入参数字符串,或者说跳过程序名称"exe"
)
我的以下代码示例及其输出集将帮助您理解。
代码.c:
#include<stdio.h>
int main(int argc, char* argv[]){
char** input = argv + 1;
while(*input) /* run untill input-->null */
printf("%s \n", *input++);
return 1;
}
输出:
~$ gcc code.c -Wall -pedantic -o exe
~$ ./exe
~$ ./exe first
first
~$ ./exe first second
first
second
Array Name 是指向数组第一个元素的常量指针
更多:- http://forum.allaboutcircuits.com/showthread.php?t=56256
函数参数中使用的数组总是转换为指针。
所以char *argv[]
是一样的char **argv
。
argv[0]
包含程序名称(或用于调用程序的名称,在多重链接文件的情况下),因此argv+1
只是程序的参数。
argv
在这种情况下不是数组;它是一个指针值。在函数参数声明的上下文中,T a[N]
和T a[]
等价于T *a
; 在所有三个中都声明a
为指向T
.
但是,即使argv
是数组,仍然可以进行分配。除非它是sizeof
or 或一元运算符的操作数,否则&
“N 元素数组T
”类型的表达式将被转换(“衰减”)为“指针T
”类型的表达式,并且表达式的值是数组的第一个元素。
请注意
char *argv[]
是一个指针数组。数组声明,本身就是一个指针,argv 是一个指针。因为这里我们有一个指针数组,所以 argv 是一个指向指针的指针,就像 char **inputs 一样,因此
char **inputs = argv+1;
只是说输入等于指针 argv 加一,并且由于 argv+1 也是一个指针,所以你有一个指向指针的指针。