C中命令行参数`argv`的类型是什么?
我正在阅读C Primer Plus中关于命令行参数argv
一节,我很难理解这句话。
它说,
程序将命令行字符串存储在内存中,并将每个字符串的地址存储在指针数组中。 该数组的地址存储在第二个参数中。 按照惯例,指向指针的指针称为
argv
,用于参数值。
这是否意味着命令行字符串作为指向char
数组的指针数组存储在内存中?
直接引用C11
,章节§5.1.2.2.1/ p2,程序启动, (强调我的)
int main(int argc, char *argv[]) { /* ... */ }
[…]如果
argc
的值大于零, 则数组成员argv[0]
到argv[argc-1]
包含指向字符串的指针 ,[…]
和
[…]和
argv
数组指向的字符串[…]
所以,基本上, argv
是一个指向字符串数组的第一个元素的指针。 从替代forms可以更清楚地看出这一点,
int main(int argc, char **argv) { /* ... */ }
你可以将它改为指向指向以null结尾的char
数组的第一个元素的指针数组的第一个元素的指针,但我更喜欢坚持使用字符串。
注意:
在上面的答案中阐明“指向数组第一个元素的指针”的用法,遵循§6.3.2.1/ p3
除非它是
sizeof
运算符,_Alignof
运算符或一元&
运算符的操作数,或者是用于初始化数组的字符串文字,否则具有类型”数组类型”的表达式将转换为表达式输入”指向类型‘的指针 ,指向数组对象的初始元素,而不是左值。 […]
argv
的类型为char **
。 它不是一个数组 。 它是指向char
指针。 命令行参数存储在存储器中,每个存储器位置的地址存储在一个数组中。 这个数组是一个指向char
的指针数组。 argv
指向此数组的第一个元素。
一些 排列 + ------- + + ------ + ------ + ------------- + ------ + argv ----------> | | | | | | | | 0x100 + ------> | | | 。 。 。 。 。 。 | | 程序名称1 0x900 | | | | | | | | | + ------ + ------ + ------------- + ------ + + ------- + 0x100 0x101 | | + ------ + ------ + ------------- + ------ + | 0x205 | | | | | | 0x904 | + ------> | | | 。 。 。 。 。 。 | | Arg 1 | | 。 | | | | | + ------- + + ------ + ------ + ------------- + ------ + | 。 | 。 0x205 0x206 | 。 | | 。 | 。 | 。 | + ------- +。 + ------ + ------ + ------------- + ------ + | | | | | | | | 0x501 + ------> | | | 。 。 。 。 。 。 | | Arg argc-1 | | | | | | | + ------- + + ------ + ------ + ------------- + ------ + | | 0x501 0x502 | NULL | | | + ------- + 0xXXX表示内存地址
1.在大多数情况下, argv[0]
表示程序名称,但如果主机环境中没有程序名称,则argv[0][0]
表示空字符。
这个线程是这样的火车残骸。 情况如下:
- 有一个数组有
argc+1
char *
类型的元素。 -
argv
指向该数组的第一个元素。 - 还有
argc
其他类型为char
和各种长度的数组,包含表示命令行参数的空终止字符串。 - 指针数组的元素每个都指向一个
char
数组的第一个char
; 除了指针数组的最后一个元素,它是一个空指针。
有时候人们会写“指向X数组的指针”来表示“指向X数组的第一个元素的指针”。 你必须使用上下文和类型来确定它们是否确实意味着它。
对,就是这样。
argv
是char**
或char*[]
,或者只是一个char *指针数组。
所以argv [0]是char*
(字符串), argv[0][0]
是char
。
argv
是一个指向字符的指针数组。
以下代码显示argv
的值, argv
的内容,并在argv
内容指向的内存上执行内存转储。 希望这能说明间接的意义。
#include #include print_memory(char * print_me) { char * p; for (p = print_me; *p != '\0'; ++p) { printf ("%p: %c\n", p, *p); } // Print the '\0' for good measure printf ("%p: %c\n", p, *p); } int main (int argc, char ** argv) { int i; // Print argv printf ("argv: %p\n", argv); printf ("\n"); // Print the values of argv for (i = 0; i < argc; ++i) { printf ("argv[%d]: %p\n", i, argv[i]); } // Print the NULL for good measure printf ("argv[%d]: %p\n", i, argv[i]); printf ("\n"); // Print the values of the memory pointed at by argv for (i = 0; i < argc; ++i) { print_memory(argv[i]); } return 0; }
样品运行:
$ ./a.out Hello World! argv: ffbfefd4 argv[0]: ffbff12c argv[1]: ffbff134 argv[2]: ffbff13a argv[3]: 0 ffbff12c: . ffbff12d: / ffbff12e: a ffbff12f: . ffbff130: o ffbff131: u ffbff132: t ffbff133: ffbff134: H ffbff135: e ffbff136: l ffbff137: l ffbff138: o ffbff139: ffbff13a: W ffbff13b: o ffbff13c: r ffbff13d: l ffbff13e: d ffbff13f: ! ffbff140: $
你有这个大的连续数组,从ffbff12c
到ffbff140
,它包含命令行参数(这不能保证是标准的连续,但它是如何通常完成的)。 argv
只包含指向该数组的指针,因此您可以知道在哪里查找单词。
argv
是指针......指向字符的指针
是。
argv
的类型是char**
,即指向char
指针。 基本上,如果您将char*
视为字符串,则argv
是指向字符串数组的指针。