这可能是一个基本问题,但写char * []和char **有什么区别?例如,在main中,我可以有一个char * argv []。或者我可以使用char ** argv。我假设两种符号之间必须存在某种差异。
答案 0 :(得分:20)
在这种情况下,根本没有区别。如果您尝试使用数组类型作为函数参数,编译器会将其“调整”为指针类型(即,T a[x]
作为函数参数表示完全< / em>与T *a
)相同。
在正确的情况下(例如,不作为函数参数),使用数组和指针表示法之间可能存在差异。一个常见的是extern
声明。例如,假设我们有一个包含以下内容的文件:
char a[20];
我们想让它在另一个文件中可见。这将有效:
extern char a[];
但这不会:
extern char *a;
如果我们改为使用指针数组:
char *a[20];
...同样仍然如此 - 声明一个extern数组工作正常,但声明一个extern指针不会:
extern char *a[]; // works
extern char **a; // doesn't work
答案 1 :(得分:9)
取决于具体情况。
作为一个函数参数,它们对于编译器来说意味着相同的东西,但是编写它char *argv[]
可能有助于使程序员明白传递的char**
指向一个元素的第一个元素。数组char*
。
作为变量声明,它们意味着不同的东西。一个是指针指针,另一个是指针数组,数组大小不明确。所以你可以做:
char * foo[] = {0, 0, 0};
获取一个包含3个空指针的数组。三个char*
与指向char*
的指针完全不同。
答案 2 :(得分:4)
您可以使用cdecl.org将其转换为英语:
char *argv[]
=将argv
声明为char的指针数组
char **argv
=将argv
声明为指向char的指针
答案 3 :(得分:2)
我认为这比语法糖更多一点,它还提供了一种表达每种声明所隐含的(自愿)合同的语义信息的方法。
对于char*[]
,您说这是用作数组。
使用char**
,你说你可以将它用作数组,但这不是它的用途。
答案 4 :(得分:2)
此确实取决于声明发生位置的上下文。
在函数参数定义之外,声明
T a[];
将a
声明为未知大小的T数组;数组类型不完整,因此,除非a
定义在其他地方(在此翻译单元或另一个链接的翻译单元中),否则不会留出任何存储空间对于它(如果你试图链接,你将可能得到一个“未定义的引用”错误,虽然我认为gcc的默认行为是用1个元素定义数组)。它不能用作sizeof
运算符的操作数。 可以用作&
运算符的操作数。
例如:
/**
* module1.c
*/
extern char *a[]; /* non-defining declaration of a */
void foo()
{
size_t i = 0;
for (i = 0; a[i] != NULL; i++)
printf("a[%lu] = %s\n", (unsigned long) i, a[i++]);
}
module1.c使用a
的非定义声明来引入名称,以便可以在函数foo
中使用它,但由于没有指定大小,在此翻译单元中没有为其预留存储空间。最重要的是,表达式a
不是指针类型;它是一个不完整的数组类型。它将在通常规则的printf
调用中转换为指针类型。
/**
* module2.c
*/
char *a[] = {"foo", "bar", "bletch", "blurga", NULL}; /* defining declaration of a */
int main(void)
{
void foo();
foo();
return 0;
}
module2.c包含a
的定义声明(数组的大小是根据初始化程序中的元素数计算的),这会导致为数组分配存储空间。
样式说明:请不要写这样的代码。
在函数参数声明的上下文中,T a[]
与T *a
同义;在这两种情况下,a
都是指针类型。在函数参数声明的上下文中,这只是 true。
答案 5 :(得分:1)
保罗在上面的评论中说,这是语法糖。 char *和char []都是相同的数据类型。在内存中,它们都包含char的地址。
数组/索引表示法在声明和访问中等效于指针表示法,但有时更直观。如果要创建一个char指针数组,您可能希望以某种方式编写它以阐明您的意图。
编辑:没有考虑杰瑞在另一个答案中提到的案例。看一看。
答案 6 :(得分:1)
正如在其他答案中提到的那样,char*[]
声明了一个指向char的指针数组,char**
声明了一个指向char的指针(可以用作数组)。
一个区别是数组是常量,而指针不是。
示例:
int main()
{
char** ppc = NULL;
char* apc[] = {NULL};
ppc++;
apc++; /* this won't compile*/
return 0;
}
答案 7 :(得分:1)
char *ptr[2]={"good","bad"}; //Array of ptr to char
char **str; //Refer ptr to ptr to char
int i;
//str = &ptr[0]; //work
str = ptr;
for(i=0;i<2;i++) printf("%s %s\n",ptr[i],str[i]);
它的o / p相同。使用它我们可以很容易地理解。