【问题标题】:Difference between 'char *args[]' and 'char **argv' as a parameter [duplicate]'char *args []'和'char **argv'作为参数的区别[重复]
【发布时间】:2018-08-12 09:44:54
【问题描述】:

当你想处理命令行参数时,你可以像下面这样定义main函数。

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

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

很多网站都有解释,第一个argv是指向指针的指针,第二个是指针数组。但是,这是真的吗?实际上,即使您使用第二个定义,您也可以将argv 设置为= 运算符的LHS,如果argv 确实是一个数组,我认为这是不允许的。在我看来,“当写成函数的参数时”,char **argvchar *argv[] 是完全相等的。但是,我还没有找到证据。

谁能帮助我? (我想要的是严格或正式的书面证据。)


注意:我已经阅读了下面的主题。我相信我的帖子不是他们的重复。

What Is The Difference Between char**x and char*x[]

In C, are arrays pointers or used as pointers?

【问题讨论】:

  • 当函数参数被声明为数组时,它会衰减为指针。这两个完全一样。
  • 哪个网站这么说的?
  • @PeteBecker 谢谢。但是,你有书面证据吗?不过我觉得你说的很自然。
  • 当然,去书面证据的标准。
  • @SombreroChicken 我访问过的几乎所有网站。 (它们都是用日语写的。)

标签: c++ c


【解决方案1】:

嗯,C 标准总是有的:

5.1.2.2.1 程序启动

1 程序启动时调用的函数名为main。实现声明没有 这个函数的原型。它应定义为返回类型为 int 并且没有 参数: int main(void) { /* ... / } 或带有两个参数(此处称为 argc 和 argv,尽管任何名称都可以 使用,因为它们对于声明它们的函数是本地的): int main(int argc, char *argv[]) { / ... */ } 或等效的;9) 或以其他一些实现定义的方式。

9) 因此,int 可以替换为定义为 int 的 typedef 名称,或者 argv 的类型可以写为 char ** argv 等等。

这表明 -- 根据脚注 (9) -- char *argv[] 等同于 char **argv

【讨论】:

    【解决方案2】:

    您链接的问题适用于在函数参数列表之外 进行的数组声明。确实,函数参数列表之外的char *argv[] 声明与char **argv 声明非常不同。前者声明一个数组,后者声明一个指针。

    但是,函数参数声明的处理方式非常不同,您链接的问题不适用于函数参数声明。当使用数组声明语法声明函数参数时,数组类型会自动转换为指针类型。因此,在函数参数列表中,char *argv[] 声明转换为 char **argv 声明。从这个意义上说,这些声明在该上下文中是完全等效的。在这两种情况下,您都会得到一个可修改的指针。

    从更一般的角度来看,在 C 中,即使在函数参数列表中,数组语法也不完全等同于指针语法,因为数组语法要求元素类型是完整的

    struct S;
    void foo(struct S s[]); /* invalid in C */
    void bar(struct S *s);  /* OK in C */
    

    【讨论】:

      【解决方案3】:

      很多网站都有解释,第一个argv是指向指针的指针,第二个是指针数组。但是,这是真的吗?

      当数组被声明为函数的参数时,这是不正确的。 main 的两个签名中的 argv 都是 char ** 类型(指向 char 的指针)。
      在 C 中,数组不能传递给函数,而是指向它的指针。当您将函数的参数声明为数组类型时,编译器会将其视为指针类型。下面的原型是等价的

      int foo1(int a[10], int size);
      int foo2(int a[], int size);
      int foo3(int *a, int size);
      

      同样适用char *argv[],作为函数参数相当于char **argv

      【讨论】:

      • 所以我的意见是对的?但是,你有书面证据吗?不过我觉得你说的很自然。
      • @ynn 只要搜索适当的主题at this website,你就会得出结论c 中的数组非常特殊,不能真正将数组作为参数传递。主要原因是当它是函数的参数时,您只能将指针传递给它的第一个元素。所以char x[] 等价于char *x 并且在同样的意义上char *x[] 等价于char **x
      • @hacks 谢谢。我知道*aa[]a[10] 是相同的,但不知道在我的情况下可以应用相同的方法。我觉得一般的定义都写在标准里了,所以我会去你告诉我的网站搜索主题。
      【解决方案4】:

      据我所知,没有。在这两种情况下,argv 的类型都是 char **。这意味着它是pointer to pointer

      【讨论】:

      • 不是多维数组。
      • char ** 不等于 char [][] 吗?编译器允许这两个版本。
      • 你认为编译器在哪里允许char [][]?还是您的意思是 char [][20],在某些情况下是允许的?
      • 没错,我指的是第二个。不过,你能解释一下区别吗?我认为指针类型的指针导致了多维数组。
      猜你喜欢
      • 1970-01-01
      • 2015-01-28
      • 1970-01-01
      • 2014-10-28
      • 2021-11-09
      • 2014-02-25
      • 2013-05-16
      • 1970-01-01
      • 2011-12-14
      相关资源
      最近更新 更多