C 中指向 Char 初始化的指针

Pointer to Char Initialization in C

如果此代码正确:

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指针"should"设置为指向第一个。为什么不正确?

以类似的方式,像 v3[] 或 v6[2] 这样的常规字符数组确实可以用 {'A', 'B'} 初始化。定义了这两个字符,数组设置为指向它们,因此被 "turned into" 或视为字符串文字。为什么像 char *str3 这样的 char 指针的行为不同?

仅作记录,当它到达 'A' 时,我收到的 gcc 编译器警告是 "initialization makes pointer from integer without a cast",当它到达 'B' 时是 "excess elements in scalar initializer"。

提前致谢。

(" ") 是字符串,(' ') 是字符。对于字符串,已经分配了内存,而对于字符,则没有。指针指向内存,您必须为其分配指定的内存,但对于字符数组则不是必需的。

关于常量字符串文字,您需要了解一件事。除非用于初始化数组(例如示例代码中 v1 的情况)常量字符串文字本身就是数组。例如,如果您使用字面量 "AB",编译器会将其存储为包含三个字符的数组:'A''B' 和终止符 '[=18=]'.

当您将指针初始化为指向文字字符串时,如 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 中将它们用作字符串,因为字符串需要特殊的终止符 '[=18=]'.

事实上,如果您检查 v1v2 的大小,您会发现它们确实有 三个 字节大,每个字符加上终止符。

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

const char *str1 = "AB";