C中命令行参数`argv`的类型是什么?

Jin*_*Jin 14 c arrays pointers argv language-lawyer

我正在阅读C Primer Plus中关于命令行参数的一节argv,我很难理解这句话.

它说,

程序将命令行字符串存储在内存中,并将每个字符串的地址存储在指针数组中.该数组的地址存储在第二个参数中.按照惯例,argv对于参数值,将调用指向指针的指针.

这是否意味着命令行字符串作为指向数组的指针数组存储在内存中char

hac*_*cks 24

argv是类型的char **.它不是一个数组.它是指向指针的指针char.命令行参数存储在存储器中,每个存储器位置的地址存储在一个数组中.这个数组是一个指针数组char.argv指向此数组的第一个元素.

                  Some
                  array

                 +-------+        +------+------+-------------+------+
argv ----------> |       |        |      |      |             |      |
                 | 0x100 +------> |      |      | . . . . . . |      |  Program Name1
         0x900   |       |        |      |      |             |      |
                 |       |        +------+------+-------------+------+
                 +-------+         0x100  0x101
                 |       |        +------+------+-------------+------+
                 | 0x205 |        |      |      |             |      |
         0x904   |       +------> |      |      | . . . . . . |      |  Arg1
                 |       |  .     |      |      |             |      |
                 +-------+        +------+------+-------------+------+
                 |  .    |  .      0x205  0x206
                 |  .    |
                 |  .    |  .
                 |  .    |
                 +-------+  .     +------+------+-------------+------+
                 |       |        |      |      |             |      |
                 | 0x501 +------> |      |      | . . . . . . |      |  Argargc-1
                 |       |        |      |      |             |      |
                 +-------+        +------+------+-------------+------+
                 |       |         0x501  0x502
                 | NULL  |
                 |       |
                 +-------+


0xXXX Represents memory address


1.在大多数情况下,argv[0]代表程序名称,但如果主机环境中没有程序名称,则argv[0][0]表示空字符.

  • 作为一个挑剔,"一些数组"应该有一个存储空指针的元素. (3认同)
  • 另外值得注意的是:argv [0]不保证保存程序名称(但大部分时间都是这样)但只有*表示*程序名称:http://stackoverflow.com/q/2050961/1116364 (3认同)
  • 真有用的ASCII架构! (2认同)

Sou*_*osh 16

直接引用C11,章节§5.1.2.2.1/ p2,程序启动,(强调我的)

int main(int argc, char *argv[]) { /* ... */ }

[...]如果值argc大于零,argv[0]通过 argv[argc-1]包含的数组成员应包含指向字符串的指针,[...]

[...]和argv数组指向的字符串[...]

因此,基本上,argv是指向一个字符串数组的第一个元素音符.这可以通过替代形式更清楚,

int main(int argc, char **argv) { /* ... */ }

你可以将它改为指向指向空终止char数组的第一个元素的指针数组的第一个元素的指针,但我更喜欢坚持使用字符串.


注意:

在上面的答案中阐明"指向数组第一个元素的指针"的用法,遵循§6.3.2.1/ p3

除非它是运算sizeof符,_Alignof运算符或一元运算&符的操作数,或者是用于初始化数组的字符串文字,否则将类型为''数组'的数组的表达式转换为类型为''的表达式指向类型''的指针指向数组对象的初始元素,而不是左值.[...]


M.M*_*M.M 11

这个线程是这样的火车残骸.情况如下:

  • 有一个包含argc+1类型元素的数组char *.
  • argv 指向该数组的第一个元素.
  • 还有argc其他类型char和不同长度的数组,包含表示命令行参数的空终止字符串.
  • 指针数组的元素每个都指向其中一个数组的第一个字符char; 除了指针数组的最后一个元素,它是一个空指针.

有时候人们会写"指向X数组的指针"来表示"指向X数组的第一个元素的指针".您必须使用上下文和类型来确定它们是否确实意味着它.