C中命令行参数argv的类型是什么?
我正在阅读C Primer Plus中关于命令行参数C中命令行参数argv的类型是什么?,c,arrays,pointers,language-lawyer,argv,C,Arrays,Pointers,Language Lawyer,Argv,我正在阅读C Primer Plus中关于命令行参数argv的一节,我很难理解这个句子 上面说, 程序将命令行字符串存储在内存中,并存储 指针数组中每个字符串的地址。这个地址 数组存储在第二个参数中。按照惯例,此指针指向 指针被称为参数值的argv 这是否意味着命令行字符串作为指向字符数组的指针数组存储在内存中 没错 argv是一个char**或char*[],或者只是一个char*指针数组 因此,argv[0]是一个char*(一个字符串),而argv[0][0]是一个char是 argv的类
argv
的一节,我很难理解这个句子
上面说,
程序将命令行字符串存储在内存中,并存储
指针数组中每个字符串的地址。这个地址
数组存储在第二个参数中。按照惯例,此指针指向
指针被称为参数值的argv
这是否意味着命令行字符串作为指向字符数组的指针数组存储在内存中 没错
argv
是一个char**
或char*[]
,或者只是一个char*指针数组
因此,argv[0]是一个char*
(一个字符串),而argv[0][0]
是一个char是
argv
的类型是char**
,即指向char
的指针。基本上,如果你认为<代码> char */COD>是一个字符串,那么<代码> ARGV 是一个字符串数组的指针。 < P>直接引用<代码> C11<代码>,阿纳尔5.5.1.2.2.1/P2,程序启动,(强调雷)
intmain(intargc,char*argv[]){/*…*/}
[…]如果argc
的值大于零,数组成员argv[0]
通过
argv[argc-1]
应包含指向字符串的指针,[…]
及
[…]和由argv
数组[…]指向的字符串
因此,基本上,argv
是指向字符串数组第一个元素的指针。从另一种形式可以更清楚地看出
intmain(intargc,char**argv){/*…*/}
您可以将其重新表述为指向以null结尾的char
数组的第一个元素的指针数组的第一个元素,但我更喜欢使用字符串
注:
在§6.3.2.1/p3之后,澄清上述回答中“指向数组第一个元素的指针”的用法
除非它是sizeof
运算符、\u Alignof
运算符或
一元&
运算符,或者是用于初始化数组的字符串文字,一个具有
类型“”的数组“”已转换为类型为“”指向类型“”的指针的表达式
指向数组对象的初始元素,并且不是左值。[……]
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
一些
排列
+-------+ +------+------+-------------+------+
argv-------->| | | | | ||
|0x100+--->| | | | | | |程序名1
0x900 | | | | | ||
| | +------+------+-------------+------+
+-------+0x100 0x101
| | +------+------+-------------+------+
|0x205 | | | | ||
0x904 |+------>| | | | | | |Arg1
| | . | | | | |
+-------+ +------+------+-------------+------+
| . | . 0x205 0x206
| . |
| . | .
| . |
+-------+ . +------+------+-------------+------+
| | | | | | |
|0x501+------>| | | | | | |argc-1
| | | | | | |
+-------+ +------+------+-------------+------+
|| 0x501 0x502
|空的|
| |
+-------+
0xXXX表示内存地址
一,。在大多数情况下,argv[0]
表示程序名,但如果主机环境无法提供程序名,则argv[0][0]
表示空字符 这根线就是这样一个火车残骸。情况如下:
- 存在一个数组,其中包含
argc+1
类型为char*
的元素
argv
指向该数组的第一个元素
- 还有
argc
类型为char
的其他数组和各种长度的数组,其中包含表示命令行参数的以null结尾的字符串
- 指针数组的元素每个指向
char
数组之一的第一个字符;除了指针数组的最后一个元素,它是空指针
有时人们写“指向X数组的指针”是指“指向X数组的第一个元素的指针”。您必须使用上下文和类型来确定它们是否真的意味着这一点。argv
是指向字符的指针数组
以下代码显示argv
的值、argv
的内容,并对argv
的内容指向的内存执行内存转储。希望这能阐明间接的意义
#include <stdio.h>
#include <stdarg.h>
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;
}
您有一个很大的连续数组,范围从ffbf12c
到ffbf140
,其中包含命令行参数(标准不保证是连续的,但通常是这样做的)<代码>argv<
$ ./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:
$