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=]'
.
当您将指针初始化为指向文字字符串时,如 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 中将它们用作字符串,因为字符串需要特殊的终止符 '[=18=]'
.
事实上,如果您检查 v1
和 v2
的大小,您会发现它们确实有 三个 字节大,每个字符加上终止符。
您错过的另一件重要事情是,虽然常量字符串文字是 char
的数组,但您错过了 constant 部分。字符串文字实际上是只读的,即使没有这样存储。这就是为什么你不应该创建一个指向 char
的指针(比如 str1
和 str2
)来指向它们,你应该创建指向 constant 的指针 char
。即
const char *str1 = "AB";
如果此代码正确:
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=]'
.
当您将指针初始化为指向文字字符串时,如 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 中将它们用作字符串,因为字符串需要特殊的终止符 '[=18=]'
.
事实上,如果您检查 v1
和 v2
的大小,您会发现它们确实有 三个 字节大,每个字符加上终止符。
您错过的另一件重要事情是,虽然常量字符串文字是 char
的数组,但您错过了 constant 部分。字符串文字实际上是只读的,即使没有这样存储。这就是为什么你不应该创建一个指向 char
的指针(比如 str1
和 str2
)来指向它们,你应该创建指向 constant 的指针 char
。即
const char *str1 = "AB";