为什么在C中有一个指向字符串数组的指针

时间:2018-09-17 15:10:17

标签: c pointers

为什么

char *names [] = {"hello", "Jordan"};

做得好

但这不是

char names [] = {"hello", "Jordan"};

如果有人可以向我解释这一点,将非常感谢,谢谢:)。

4 个答案:

答案 0 :(得分:3)

这里

char *names [] = {"hello", "Jordan"};

names字符指针数组,即它可以保存指针,即names每个元素本身都是一个字符数组。但是这里

char names [] = {"hello", "Jordan"};

names只是一个 char数组,即它只能容纳单个"hello"这样的char数组,而不是多个。

第二种情况下

int main(void) {
        char names[] = {"hello", "Jordan"};
        return 0;
}

编译时(建议您使用-Wall -pedantic -Wstrict-prototypes -Werror标志进行编译),编译器会清楚地说明

  

错误:char数组初始化程序中的多余元素

这意味着在这种情况下,您不能有多个char数组。正确的是

char names[] = {'h','e','l','l','o','\0'}; /* here names is array of characters */

编辑:-另外,如果names的语法如下所示,则更有可能

char names[] = { "hello" "Jordan" }; /* its a valid one */

然后在这里helloJordan都加入并成为单个字符数组helloJordan

char names[] = { "helloJordan" }; 

答案 1 :(得分:2)

第一个是一个指向char的指针数组。第二个是char数组,看起来像char names[] = {'a', 'b', 'c'}

答案 2 :(得分:0)

char name[]是一个字符数组,因此您可以在其中存储一个单词:

char name[] = "Muzol";

与以下相同:

char name[] = {'M', 'u', 'z', 'o', 'l', '\0'}; /* '\0' is NULL, it means end of the array */

char* names[]是一个数组数组,其中第一个数组的每个元素都指向第二个数组的元素的开头。

char* name[] = {"name1", "name2"};

与以下相同:

char name1[] = {'n', 'a', 'm', 'e', '1', '\0'}; /* or char name1[] = "name1"; */
char name2[] = {'n', 'a', 'm', 'e', '2', '\0'}; /* or char name2[] = "name2"; */
char* names[] = { name1, name2 };

因此,基本上names[0]指向&name1[0],在这里它可以读取内存直到name1[5],在这里它可以找到'\0' (NULL)字符并停止。 name2[]也是如此;

答案 3 :(得分:0)

字符串文字,例如"hello",作为char数组存储在静态存储器中。实际上,字符串文字的类型为char [N],其中N是数组中的字符数(包括\0终止符)。在大多数情况下,数组标识符会衰减为指向数组第一个元素的指针,因此在大多数表达式中,字符串文字如"hello"会衰减为指向char元素{{1}的指针}。

'h'

这里,两个字符串文字衰减到指向char *names[] = { "hello", "Jordan" }; char的指针'h'的指针。也就是说,这里的字符串文字在转换后的类型为'J'。这些类型与左侧的声明一致,并且使用这两个指针值初始化数组char *(不是字符类型的数组,而是names[]的数组)。

char *

或类似地:

char names[] = "hello";

在这里我们遇到一个特例。当数组标识符是char names[] = { "hello" }; 运算符或一元sizeof运算符的操作数或使用的是字符串文字时,数组标识符 not 不会转换为指向其第一个元素的指针初始化字符类型的数组。因此,在这种情况下,字符串文字&不会衰减为指针。而是使用字符串文字中包含的字符来初始化数组"hello"

names[]

同样,字符串文字将用于初始化数组char names[] = {"hello", "Jordan"}; ,但是初始化器列表中有多余的初始化器。根据标准,这是约束违反。摘自C11标准草案的§6.7.9 ¶2

  

初始化器不得尝试为未包含在正在初始化的实体中的对象提供值。

如果违反约束,则符合标准的实现必须发出诊断,该诊断可能采取警告或错误的形式。在我目前正在使用的gcc版本(gcc 6.3.0)上,此诊断错误:

names[]

但是,对于由error: excess elements in char array initializer 值的初始化列表而不是字符串文字初始化的char数组,相同的诊断是警告而不是错误。

要初始化不是指针数组的char数组,您将在此处需要一个char的二维数组。请注意,第二个维度是必需的,并且必须足够大以包含初始化程序列表中的最大字符串:

char

在这里,每个字符串文字用于初始化char names[][100] = { "hello", "Jordan" }; 的较大2d数组中包含的100 char s的数组。或者,换句话说,char是由100个names[][]组成的数组的数组,每个数组都由初始化程序列表中的字符串文字进行初始化。