1

我们可以将字符串常量分配给char *char [ ]就像:

char *p = "hello";
char a[] = "hello"; 

现在对于字符串数组,自然会是这样的:

char **p = {"hello", "world"};   //  Error
char *a[] = {"hello", "world"};

第一种方法会在编译时产生一个警告,并且Segmentation fault当我试图打印字符串常量时有一个printf("%s\n", p[0]);

为什么 ?

4

4 回答 4

2
char **p = {"hello", "world"};

在这里,p是一个指向指针的指针,char该指针无法使用带有指针数组的数组初始化程序进行初始化(每个字符串文字在初始化期间都被转换为指针——C 中字符串文字的实际类型是char[n])。

类型不兼容,即 p 属于 typechar **而 RHS 属于 type char *[]。因此,诊断由编译器发出。

然而,

char *a[] = {"hello", "world"};

a和指向的指针数组一样有效,char并且类型匹配。因此这是一个有效的初始化。


从 C99 开始,C 语言支持复合文字(6.5.2.5,C99),您可以使用它来初始化:

char **p = (char *[]) {"hello", "world"}; 

因此,如果您的编译器支持 C99 或更高版本,请使用复合文字。否则,坚持指针数组初始化 ( char *a[])。

您可以在此处阅读有关复合文字的各种示例(gcc 手册)。

于 2013-11-02T05:55:24.490 回答
1

因为char **p是指向指针的指针而不是指针数组,哪里char* a[]是指针数组

char *ptr ="hello";

定义ptr为指向(只读)字符串的指针"hello",因此包含字符串 say 的地址100ptr本身必须存储在某个地方:说位置200.

char **p = &ptr;

现在p指向ptr,即它包含ptr(即200)的地址。

printf("%s",**p);

因此,您创建一个pointer to another pointer但不是额外的内存来存储多个字符串但char *a[]创建指针数组取决于您给出的大小

一个建议

不要使用char *p = "hello"; use const char *p = "hello"; ,因为字符串文字保存在只读内存中

于 2013-11-02T05:39:16.557 回答
1

总而言之,因为 char **p 指向一个指针,而不是一个指针数组。

发生这种情况是因为您需要自己构建阵列。对于每个级别(或维度),您需要为指针持有者保留内存。

你需要做的是:

// this holds you pointers
char **p = malloc( sizeof( char *) * nr of elements);

// to set the elements, you need to:
p[0] = "hello";
p[1] = "world";

这需要针对您拥有的尽可能多的级别(或维度)进行。

于 2013-11-02T05:44:30.917 回答
0

首先,char *p = "hello"不同于char a[] = "hello".

char *p = "hello"

"hello"实际上是一个指向文字常量的指针。您将指向文字常量的指针分配给p. 所以最好使用const char *p = "hello".

char a[] = "hello"

中的字符以结尾"hello"复制到数组中。a'\0'

第二,

char *a[] 

定义了一个指针数组,所以可以使用char *a[] = {"hello", "world"};

char **p 

定义了一个指向 char 指针的指针,因此使用它没有任何意义char **p = {"hello", "world"};

于 2013-11-02T05:56:18.197 回答