如果代码正确:
char v1[ ] = "AB";
char v2[ ] = {"AB"};
char v3[ ] = {'A', 'B'};
char v4[2] = "AB";
char v5[2] = {"AB"};
char v6[2] = {'A', 'B'};
char *str1 = "AB";
char *str2 = {"AB"};
那为什么另一个不是呢?
char *str3 = {'A', 'B'};
据我所知(如果我错了,请纠正我)"AB"是字符串字面值,' a '和'B'是字符(整数、标量)。In char *str1 = "AB";定义字符串字面值"AB",并设置char指针指向该字符串字面值(指向第一个元素)。char *str3 = {'A', 'B'};定义两个字符并将其存储在随后的内存位置,并且char指针"应该"设置为指向第一个字符。为什么不正确呢?
以类似的方式,像v3[]或v6[2]这样的常规字符数组确实可以用{' a ', 'B'}初始化。这两个字符被定义,数组被设置为指向它们,因此,被"转换为"或被视为字符串字面值。为什么像char *str3这样的char指针不以同样的方式表现?
只是为了记录,我得到的gcc编译器警告是"初始化使指针从整数没有转换",当它到达"a"时,和"标量初始化器中的多余元素",当它到达"B"时。
关于常量字符串字面值,您需要了解一件事。除非用于初始化数组(例如示例代码中的v1
),常量字符串字面量本身就是数组。例如,如果你使用字面量"AB"
,它将被编译器存储为一个由三个字符组成的数组:'A'
, 'B'
和终止符' '
。
当你初始化一个指针指向字符串字面量时,就像str1
和str2
的情况一样,那么你就使这些指针指向数组中的第一个字符。你实际上并没有创建一个名为str1
的数组(例如),你只是让它指向某个地方。
char *str1 = "AB";
等价于
char *str1;
str1 = "AB";
或者
char unnamed_array_created_by_compiler[] = "AB";
char *str1 = unnamed_array_created_by_compiler;
您所展示的定义还存在其他问题。首先是数组v3
, v4
, v5
和v6
。告诉编译器它们将是包含两个char
元素的数组。这意味着你不能在C语言中将它们用作字符串,因为字符串需要特殊的结束符' '
。
事实上,如果你检查v1
和v2
的大小,你会看到它们确实是三个字节大,每个字符加上结束符一次。
char
的数组,但您忽略了常量部分。字符串字面量实际上是只读的,即使没有这样存储。这就是为什么您不应该创建指向char
(如str1
和str2
)的指针来指向它们,您应该创建指向常量 char
的指针。例如const char *str1 = "AB";
(" ")表示字符串,(" ' ")表示字符。对于字符串已分配内存,而对于字符未分配内存。指针指向一个内存,你必须为它分配一个指定的内存,但对于字符数组来说,这是不必要的。