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

时间:2014-11-30 13:10:19

标签: 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;
}

代码2

#include<stdio.h>

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

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

4 个答案:

答案 0 :(得分:11)

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

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

 x = &parray[0];

然后使用x相同。

答案 1 :(得分:11)

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

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

因此,在下面给出的代码中,在char数组x中,x是指向第一个元素的指针,&#39; 1&#39;,这是一个字符。所以它是指向角色的指针。

在数组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);
}

答案 2 :(得分:5)

他们完全一样。 C11标准的第5.1.2.2.2段声明:

  

程序启动时调用的函数名为main。该   实现声明此函数没有原型。应该是   使用返回类型int定义并且没有参数:

int main(void) { /* ... */ }
     

或有两个参数(此处称为argcargv   可以使用任何名称,因为它们是它们所在的函数的本地名称   宣布):

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

或等效的; 10)或其他一些实现定义的   方式。

     

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

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

  

应调整参数声明为' type ''的数组   ''合格的指针    type '',其中类型限定符(如果有)是在数组类型派生的[]中指定的类型限定符。 ...

答案 3 :(得分:2)

声明一个这样的数组

char array[]

使其成为const意味着您可以使用以下代码

char array[] = "hello";
array = "hey";

即使第二个字符串较小且适合您,也会出现此错误

  

错误:数组类型&#39; char [6]&#39;不可分配

如果你有**argv,你可以写

main(int argc, char **argv)
{
    char **other_array;
    /*
     * do stuff with other_array
     */
    argv = other_array;
}

如果你有*argv[]那么

main(int argc, char *argv[])
{
    char **other_array;
    /*
     * do stuff with other_array
     */
    argv = other_array;
}

给你这个警告

  

警告:分配给&#39; const char **&#39;来自&#39; char **&#39;丢弃嵌套指针类型中的限定符

所以从技术上讲,这是一个小优化,就像你写了const

一样