字符串如何在 C 中工作?

How do strings work in C?

String 在 C 编程语言中被称为常量。

所以,当我给出像 char *s = "Hello" 这样的语句时,我了解到 s 指向 H 的内存位置,因为 "Hello" 存储在程序的一些静态内存中,并且 "Hello" 是不可变的。

是否表示变量s现在是指向常量数据类型的变量,例如const int a = 3;const int *i = &a;。这似乎是因为我无法操纵数据(当我这样做时,它会导致分段错误)。

但是,如果是这样,编译器不应该能够检测到并说我已经将合格的数据分配给了不合格的变量。 像 char *p p 是指向不合格字符的指针 而当我说 char *p="Hello" p 时,指向不合格字符的指针不能指向const 字符类型?

我在这里错过了什么?

如果不是上面的情况,那么常量字符数组是如何做到不可变的呢?

语法 char *s = "Hello";const 关键字不属于 C 规范的日子开始就存在了。后来它保留了反向兼容性。写入这样的 s[i] 会导致未定义的行为。 (在您的案例中观察到几次运行出现段错误)

此行为(从字符串字面量或 const char [] 到非常量 char * 的转换)在 C++ 中得到了短暂的支持,直到 C++11 才被弃用。

C 中的类型安全是有限的。

首先,C 中的 string 不是不可变的。 C 甚至不知道字符串的 type —— string 只是定义为 char 以 [= 结尾的序列11=].

你说的是字符串文字,它们可以是不可变的。 C 标准定义试图修改字符串文字是 未定义的行为 ,但它们的类型仍然是 char *。所以,如果您确定在您的 C 实现中,字符串文字是可写的,您就可以这样做! *)

但是您的代码将不再是定义明确的 C 代码,并且将无法在具有只读字符串文字的其他平台上运行。它将 编译 ,因为通过 char * 编写非常好,但在运行时以不可预测的方式失败(例如,可能是崩溃)。

因此,将字符串文字仅分配给 const char * 指针是可移植代码的最佳实践,如果您需要可变字符串,请使用字符串文字作为 初始化器 对于 char [].


*) 请注意,这是 非常 不常见的,现在只有针对嵌入式或非常旧的平台的专用编译器才会发现它。现代平台 将字符串文字放在只读数据段或类似数据段中。