char*argv []和char**argv之间的差异,为main()的第二个参数

Jha*_*ani 17 c arrays pointers parameter-passing argv

代码1

#include<stdio.h>

int main(int argc, char *argv[])
{
int j;
printf("%d", argv[1][0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)

代码2

#include<stdio.h>

int main(int argc, char **argv)
{
int j;
printf("%d", argv[1][0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)

CODE 1和CODE 2都提供相同的输出.但是CODE 1和CODE 2中主要功能的参数2是不同的.在编译时在数据部分上创建指针数组.argv是指针数组.然后我们应该在main函数中声明参数作为指向字符的指针,即**argv.在CODE 1中声明如何正确?

bma*_*ies 14

这是c的基础,char** x并且char* x[]是表达同一事物的两种方式.两者都声明该参数接收指向指针数组的指针.回想一下,你总是可以写:

 char *parray[100];
 char **x;

 x = &parray[0];
Run Code Online (Sandbox Code Playgroud)

然后相同地使用x.

  • 除了使用`sizeof` (7认同)
  • IMO,如果您至少简要地注意到 C 中有几个地方(例如 Ed Heal 提到的“sizeof”),其中数组 * 不* 等同于指针,并且“数组调整” in 函数参数声明(问题所询问的)与表达式中的“数组衰减”不同(尽管与之相关)。对于参考,您可以引用例如[什么是“数组/指针等价”的现代术语?](/sf/ask/3420785721/) 和 [数组不衰减为指针的例外?](/sf/ask/3420785721/) /stackoverflow.com/q/17752978) (3认同)

nis*_*002 13

基本上,char*argv []表示char指针数组,而char**argv表示指向char指针的指针.

在任何数组中,数组的名称是指向数组的第一个元素的指针,也就是说,它包含第一个元素的地址.

所以在下面给出的代码中,在char数组x中,x是指向第一个元素的指针,'1',这是一个字符.所以它是指向一个角色的指针.

在数组arr中,arr是指针第一个元素x,它本身就是一个指向字符的指针.所以它是指向另一个指针的指针.

因此,x是char*,arr是char**.

在函数中接收内容时,基本规则是,您必须告诉您正在接收的内容的类型.所以要么你只是说要收到一个char**,要么你也可以说char*arr [].

在第一种情况下,我们不需要考虑任何复杂的事情.我们只知道,我们正在收到一个char*数组.我们不知道吗?所以,我们收到它并使用它.

在第二种情况下,它很简单,正如我上面所解释的那样arr是一个char**,你可以把它作为它的类型并安全地接收它.现在系统知道我们收到的东西的类型,我们可以通过简单地使用数组注释来访问下一个元素.就像,我们收到了数组的起始地址,我们可以肯定地转到下一个元素,并且正如我们所知道它的类型,我们知道它包含什么以及我们如何进一步使用它.我们知道它包含指向char的指针,因此我们也可以合法地访问它们.

void func1(char* arr[])
{
    //function body
}
void func2(char** arr)
{
    //function body
}

int main()
{
    //x, y and z are pointer to char
    char x[3]={'1', '2', '3'};
    char y[3]={'4', '5', '6'};
    char z[3]={'7', '8', '9'};

    //arr is pointer to char pointer
    char* arr[3]={x, y, z};

    func1(arr);
    func2(arr);
}
Run Code Online (Sandbox Code Playgroud)

  • 在这个答案中存在许多误解,这些误解已经混淆了[至少一个人](/sf/ask/3435276071/).首先,`char*argv []`和`char**argv`是完全等价的,并不代表不同的东西.其次,`arr`是_not_指针.我没有对文本进行足够密切的研究,以确定其他具体问题,但这些问题已经严重到需要保证,并希望你在其他人被误导之前重新审视这篇文章! (4认同)

小智 6

他们完全一样.C11标准的5.1.2.2.2规定:

在程序启动时调用的函数被命名main.该实现声明此函数没有原型.它应定义为返回类型int且没有参数:

int main(void) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

或者有两个参数(这里称为argcargv,虽然可以使用任何名称,因为它们是声明它们的函数的本地名称):

int main(int argc, char *argv[]) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

或同等学历; 10)或以某种其他实现定义的方式.

10)因此,int可以替换为定义为的typedef名称int,或者argv可以写为的类型char ** argv,依此类推.

显然,意图是两个声明都是相同的.最重要的是,该规则在§6.7.6.3/ 7中描述:

一个参数为""的阵列的声明类型 "",应调整至""合格指针 键入 "",其中类型限定符(如果有的话)的那些内的指定[]该阵列类型的推导....