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

代码1

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

代码2

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

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

基本上,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); } 

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

  char *parray[100]; char **x; x = &parray[0]; 

然后相同地使用x。

他们完全一样。 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中描述:

将参数声明为” 类型数组”应调整为”限定指向类型 ”,其中类型限定符(如果有)是在数组类型派生的[]中指定的那些。 …

声明这样的数组

 char array[] 

使它成为const意味着您不能拥有以下代码

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

即使第二个字符串较小,应该适合你得到这个错误

错误:数组类型’char [6]’不可分配

如果你有**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; } 

给你这个警告

警告:从’char **’中分配’const char **’会丢弃嵌套指针类型中的限定符

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