C++ - char**argv与char*argv []

Sim*_*ity 52 c++ program-entry-point arguments

char** argv和之间有什么区别char* argv[]?在int main(int argc, char** argv)int main(int argc, char* argv[])

它们是一样的吗?特别是第一部分没有[].

Fre*_*Foo 54

它们完全相同.char *argv[]必须作为指针数组读取,char并将数组参数降级为指针,因此指向指针的指针char,或char **.

这在C中是相同的.

  • @user:这是一个语言规则.当您使用语法`X foo(Y a [])`声明或定义函数时,它实际上变为`X foo(Y*a)`.看起来像函数的数组参数实际上是一个指针.由于`argv`被声明为一个数组(指针),它变成一个指针(指针). (4认同)
  • @user:让我们做一个`typedef char*String`,所以`String`是指向`char`的指针的别名.现在`argv`可以声明为`String argv []`,它是一个`String`数组.因为它是一个参数,它实际上是一个指向`String`的指针,所以`String*argv`.我希望这更清楚,我并不真正关注你的问题. (2认同)

Jam*_*ord 25

它们确实完全一样.

要记住的数组的黄金法则是:

"数组的名称是指向数组第一个元素的指针."

因此,如果您声明以下内容:

char text[] = "A string of characters.";

然后变量"text"是指向你刚刚声明的字符数组中第一个字符的指针.换句话说,"文本"是类型char *.当您使用[ index ] 访问数组的元素时,您实际在做的是将索引的偏移量添加到指向数组的第一个元素的指针,然后取消引用此新指针.因此,以下两行将两个变量初始化为't':

char thirdChar = text[3];
char thirdChar2 = *(text+3);
Run Code Online (Sandbox Code Playgroud)

使用方括号是一种由语言提供的便利性,使代码更具可读性.但是当你开始考虑更复杂的事情时,例如指针指针,这种方法非常重要.char** argvchar* argv[]因为在第二种情况下"数组的名称是指向数组中第一个元素的指针 ".

从这里你也应该能够看到为什么数组索引从0开始.指向第一个元素的指针是数组的变量名(再次是黄金法则)加上偏移量......没有!

我和我的一个朋友讨论过哪个更好用.使用char* argv[]符号,读者可能更清楚的是,这实际上是"字符指针数组",而不是char** argv可以读作"指向字符指针的指针" 的符号.我的观点是,后一种符号并没有向读者传达那么多信息.

很高兴知道它们是完全一样的,但是为了可读性,我认为如果意图是一个指针数组,那么char* argv[]符号表达得更清楚了.

  • _“要记住的数组的黄金法则是”_ 绝对不是你写的。这是一个可怕的、令人沮丧的神话,不会消亡。数组的名称可以_decay_指向指向该数组第一个元素的指针。这绝对不同于等价或同一性。 (2认同)
  • @JamesBedford:不,这并不是真正的编译时与运行时。像“int x[10]”这样的数组是一个由 10 个整数组成的堆栈变量。(当它的封闭范围放入堆栈时,它的帧包含这 10 个整数的空间。)它不是一个指针,指针是一个包含某个地址的变量。与创建指针时不同,创建数组时堆栈上不存储地址。但是,当您将数组传递给函数时,它会_衰减_;该函数接收一个指针,而不是一个数组。 (2认同)
  • 考虑一下:当您获取数组的地址“&x”时,您将获得数组中数据的地址。如果“x”是一个指针,您将获得保存指向数据的指针的内存位置的地址,但您没有。 (2认同)

Dav*_*eau 5

对于问题的第一部分:

  • char** argv:指向 char 的指针
  • char* argv[]:指向数组的指针

所以问题是指向类型 C 的指针和数组 C[] 是否是同一件事。它们根本不是一般的,但在签名中使用时它们是等效的

换句话说,您的示例中没有区别,但重要的是要记住指针和数组之间的区别。

  • _“char* argv[]:指向数组的指针”_号。 `T* param[]` 在语法级别被重写为 `T** param`。您可以将“T**”传递到与数组无关的函数中。 (2认同)