指向C中字符初始化的指针

时间:2016-09-28 09:31:37

标签: c string pointers initialization braces

如果此代码正确无误:

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'时。

提前致谢。

2 个答案:

答案 0 :(得分:2)

关于常量字符串文字,您需要了解一件事。除非用于初始化数组(例如,在示例代码中为v1),常量字符串文字本身就是数组。例如,如果您使用文字"AB",它会被编译器存储在一个由三个字符组成的数组:'A''B'和终止符'\0'

初始化指向文字字符串的指针时,如str1str2的情况,那么您将使这些指针指向这些数组中的第一个字符。你实际上并没有创建一个名为str1的数组(例如),只是让它指向某处。

定义

char *str1 = "AB";

相当于

char *str1;
str1 = "AB";

或者更确切地说

char unnamed_array_created_by_compiler[] = "AB";
char *str1 = unnamed_array_created_by_compiler;

您展示的定义还有其他问题。首先是数组v3v4v5v6。您告诉编译器它们将是两个char元素的数组。这意味着您不能将它们用作C中的字符串,因为字符串需要特殊的终止符'\0'

事实上,如果你检查v1v2的大小,你会发现它们确实是三个字节大,每个字符加上终结符一次。

你想念的另一个重要的事情是,虽然常量字符串文字是char的数组,但你会错过常量部分。字符串文字实际上是只读的,即使没有这样存储。这就是为什么你永远不应该创建指向char的指针(如str1str2)来指向它们,你应该创建指向常量 {{1}的指针}。即。

char

答案 1 :(得分:0)

(“”)用于字符串,('')用于字符。对于字符串,已分配内存而不是字符。指针指向一个内存,你必须为它分配一个指定的内存,但是不需要字符数组。