char *a[]={"hello", "world"}; 和有什么区别?和字符 a[][10]={"hello", "world"};?

Shi*_*sui 2 c arrays pointers declaration implicit-conversion

当我尝试这段代码时

char *a[] = {"hello", "world" };
char **p = a;
char a[][10]={"hello", "world"};
Run Code Online (Sandbox Code Playgroud)

我的编译失败,我被告知变量 a 存在冲突类型错误。顶部声明与底部声明有何不同?

Vla*_*cow 5

在第一个声明中

char *a[] = {"hello", "world" };
Run Code Online (Sandbox Code Playgroud)

数组a的类型为char * [2]。数组元素的类型为char *

在表达式中用作例如初始化器,它被隐式转换为指向其具有类型的第一个元素的指针char **

所以这个声明

char **p = a;
Run Code Online (Sandbox Code Playgroud)

是正确的。

本声明

char a[][10]={"hello", "world"};
Run Code Online (Sandbox Code Playgroud)

声明一个类型为 的数组char [2][10]。数组元素的类型为char[10]

在表达式中使用时,它被隐式转换为指向其类型第一个元素的指针char ( * )[10]

所以指针的正确声明将是

char ( *p )[10] = a;
Run Code Online (Sandbox Code Playgroud)

因此,数组的两个声明声明了不同类型的数组。

请注意,您不能使用第一个数组的元素(指针)更改字符串文字。

在第二个声明中,文字的元素被复制到数组的元素中。由于数组没有限定符,const因此您可以更改存储的字符串。


M.M*_*M.M 5

这是内存布局的图片。这对应于代码:

char *a[2] = { "hello", "world" };
char **p = a;
char b[][10] = { "hello", "world" };
char **q = b;   // Error
Run Code Online (Sandbox Code Playgroud)

内存布局图

红色 = 字符数组,绿色 = 字符指针,青色 = 字符指针。

A char **(即指向 的指针char *)只能指向char *变量,不能指向字符数组。

如您所见,被char **调用p者指向 a 的存储char *

但是哪里可以q指点呢?没有正确类型的变量。如果您想直接指向b或 的行b,那么您需要一个指向 char 数组的指针(而不是指向 char 指针的指针)。