如果此代码正确无误:
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”是字符(整数,标量)。在char * str1 =“AB”;定义字符串文字“AB”,并将char指针设置为指向该字符串文字(到第一个元素)。使用char * str3 = {'A','B'};定义两个字符并将其存储在后续存储器位置中,并且将char指针“应该”设置为指向第一个字符。为什么这不正确?
以类似的方式,像v3 []或v6 [2]这样的常规字符数组确实可以用{'A','B'}初始化。定义了两个字符,数组被设置为指向它们,因此被“变成”或被视为字符串文字。为什么像char * str3这样的char指针的行为方式不一样?
仅仅为了记录,我得到的gcc编译器警告是“初始化使指针来自整数而不是强制转换”,当它到达'A'时,“标量初始化器中的多余元素”到达'B'时。
提前致谢。
答案 0 :(得分:2)
关于常量字符串文字,您需要了解一件事。除非用于初始化数组(例如,在示例代码中为v1
),常量字符串文字本身就是数组。例如,如果您使用文字"AB"
,它会被编译器存储在一个由三个字符组成的数组:'A'
,'B'
和终止符'\0'
。
初始化指向文字字符串的指针时,如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中的字符串,因为字符串需要特殊的终止符'\0'
。
事实上,如果你检查v1
和v2
的大小,你会发现它们确实是三个字节大,每个字符加上终结符一次。
你想念的另一个重要的事情是,虽然常量字符串文字是char
的数组,但你会错过常量部分。字符串文字实际上是只读的,即使没有这样存储。这就是为什么你永远不应该创建指向char
的指针(如str1
和str2
)来指向它们,你应该创建指向常量 {{1}的指针}。即。
char
答案 1 :(得分:0)
(“”)用于字符串,('')用于字符。对于字符串,已分配内存而不是字符。指针指向一个内存,你必须为它分配一个指定的内存,但是不需要字符数组。