可能重复:
argc and argv in main
我很难理解用于一般主函数声明的符号,即int main(int argc, char *argv[])
。我明白实际传递给main函数的是一个指向char
指针的指针,但我觉得这个符号很难。例如:
为什么**argv
指向第一个字符而不是整个字符串?同样,为什么*argv[0]
指向与前一个示例相同的东西。
为什么*argv
指向整个第一个字符串,而不是像上一个示例那样指向第一个char
?
这有点无关,但为什么*argv + 1
指向字符串'减去第一个字符'而不是指向数组中的下一个字符串?
答案 0 :(得分:8)
考虑使用argc == 3
的程序。
argv
|
v
+---------+ +----------------+
| argv[0] |-------->| program name\0 |
+---------+ +-------------+--+
| argv[1] |-------->| argument1\0 |
+---------+ +-------------+
| argv[2] |-------->| argument2\0 |
+---------+ +-------------+
| 0 |
+---------+
变量argv
指向指针数组的开头。 argv[0]
是第一个指针。它指向程序名称(或者,如果系统无法确定程序名称,则argv[0]
的字符串将为空字符串; argv[0][0] == '\0'
)。 argv[1]
指向第一个参数,argv[2]
指向第二个参数,argv[3] == 0
(等效argv[argc] == 0
)。
当然,您需要知道的其他细节是任何数组的array[i] == *(array + i)
。
你具体问:
- 为什么** argv指向第一个字符而不是整个字符串?
*argv
相当于*(argv + 0)
,因此argv[0]
。这是char *
。当您取消引用char *
时,您将获得字符串中的“第一个”字符。因此,**argv
相当于*(argv[0])
或*(argv[0] + 0)
或argv[0][0]
。
(可以合理地认为**argv
是一个字符,而不是一个指针,因此它不会'指向第一个字符'。它只是'p'
{的另一个名称{1}}。)
- 同样,为什么* argv [0]指向与前一个示例相同的东西。
如前所述,"program name\0"
是指向字符串的指针;因此argv[0]
必须是字符串中的第一个字符。
- 为什么
*argv[0]
指向整个第一个字符串,而不是像上一个示例那样的第一个字符串?
这是一个常规问题。 *argv
指向第一个字符串的第一个字符。如果将其解释为指向字符串的指针,则它指向“整个字符串”,与*argv
指向“整个字符串”的方式相同。如果将其解释为指向单个字符的指针,则它指向字符串的第一个字符。可以把它想象成波粒二象性,只有这里才是字符串二元性。
- 为什么
char *pqr = "Hello world\n";
指向字符串'减去第一个字符'而不是指向数组中的下一个字符串?
*argv + 1
是*argv + 1
。如前所述,(*argv) + 1
指向第一个字符串的第一个字符。如果向指针添加1,则指向下一个项目;由于*argv
指向一个字符,*argv
指向下一个字符。
*argv+1
指向下一个字符串的(第一个字符)。
答案 1 :(得分:3)
这一切都归结为指针算术。
*argv[0] = *(*(argv + 0)) = **argv
由于[]
的优先级高于一元*
。
另一方面,*argv
给出数组中的第一个单元格,一个包含指针的数组。这个指针指向什么?当然为什么是char数组,字符串。
*argv + 1
给出了它给出的内容,因为+
的优先级低于一元*
,所以首先我们得到一个指向字符串的指针,然后我们向它添加1,从而得到一个指针第二个
字符串中的字符。
答案 2 :(得分:2)
I understand that what is actually passed to the main function is a pointer to a pointer to char
不,传递的是一个char指针数组(一个字符串数组)。如果我在命令提示符下给出它,可以这样想:
>> ./program hello 456
我的节目主要得到:
argc == 3
argv[0] == program (the name of the program as a string)
argv[1] == hello (the first parameter as a string)
argv[2] == 456 (the second parameter as a string)
Why does **argv point to the first char and not the whole string?
char *argv[] //an array of character pointers
*argv // an array decays to a pointer, so this is functionally equivalent to
// argv[0]
**argv // Now the argv[0] decays to a pointer and this is functionally
// equivalent to (argv[0])[0]
Likewise, why does *argv[0] point to the same thing as the previous example.
见上文。
Why does *argv point to the whole first string, instead of the first char like the previous example?
见上文。
答案 3 :(得分:0)
char ** argv ,保存传递给C应用程序的输入。每个argv
位置都有一个字符串,在C中由字符数组表示。
应用程序可以接收多个参数(即多个字符串)。因此,更多的是一个字符数组,这就是为什么我们有 char ** argv 。
当./your_application 1 10 3
argv
包含1 10 3时,如下所示:
argv[0] = "1";
argv[1] = "10";
argv[2] = "3";
Argc
会告诉您应用程序收到的参数数量。在这种情况下argc = 3
。
当你事先知道尺寸时,如果你事先不知道你做 char * array ;你可以做这样的事情 array [M] 。基本上说变量array
将指向未来字符数组的第一个内存位置。
你可以更深入,拥有多个字符串,你可以char array[N][M]
或者你不知道大小char **array
。按照同样的思路,第一个指针指向字符数组的第一个内存位置,第二个指针指向第一个字符数组的字符。
为什么argv
指向第一个字符而不是整个字符串?
因为argv
是一个字符数组数组,所以第一个指针指向第一个字符数组,第二个指针指向该数组的第一个字符。
所以*argv[0]
是相同的,因为指针指向字符数组,并指定所需的位置,在本例中为零,因此它将是您指向的数组的第一个字符。
您还可以通过执行argv[1][0]
之类的操作来指定所需的字符数组,在这种情况下,您指向第二个数组的第一个字符。
答案 4 :(得分:-1)
这都是因为数组也是指向c中数组中第一个元素的指针。 **argv
取消引用指向char的指针两次,给我们一个char。 *argv[0]
基本上是说'取消引用该地址,并返回我们刚从解除引用获得的地址所描述的数组中的第一个元素',这恰好是同样的事情。 *argv
只取消引用一次,所以我们仍然有一个指向char或char数组的指针。 *argv + 1
取消引用一次,给我们第一个字符串,然后将1加到地址,给我们第二个元素的地址。因为指针也是数组,我们可以说这是数组*argv
减去第一个元素。