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

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的类

我正在阅读C Primer Plus中关于命令行参数
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:

$