主函数中** argv的表示法

时间:2012-11-13 15:09:48

标签: c main argv argc

  

可能重复:
  argc and argv in main

我很难理解用于一般主函数声明的符号,即int main(int argc, char *argv[])。我明白实际传递给main函数的是一个指向char指针的指针,但我觉得这个符号很难。例如:

为什么**argv指向第一个字符而不是整个字符串?同样,为什么*argv[0]指向与前一个示例相同的东西。

为什么*argv指向整个第一个字符串,而不是像上一个示例那样指向第一个char

这有点无关,但为什么*argv + 1指向字符串'减去第一个字符'而不是指向数组中的下一个字符串?

5 个答案:

答案 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减去第一个元素。