C中使用char*和char[]表示常量char数组的区别

Ere*_*cie 5 c arrays constants

在 C 中创建常量字符串的好方法是什么?无法通过对其索引位置之一进行字符分配来改变的字符串。并且在初始化后的后续执行中不能被另一个字符串替换的字符串。

我在下面的代码中尝试了 char* 和 char[] 。我尝试过使用和不使用“const”关键字。结果非常奇怪。

以下是我的代码:

#include <stdio.h>
main() {
    char a []= "abc" "def";
    char* b = "abcdef";
    const char c [] = "abcdef";
    const char* d = "abcdef";

    a[1] = 'y';
    b[1] = 'y';
    c[1] = 'y';
    d[1] = 'y';
    printf("%s %s %s %s \n", a, b, c, d);

    a = "overwrited";
    b = "overwrited";
    c = "overwrited";
    d = "overwrited";
    printf("%s %s %s %s \n", a, b, c, d);
}
Run Code Online (Sandbox Code Playgroud)

结果是,在第一个printf中,所有a、b、c、d都可以变异;但c和d出现警告“分配只读位置”。在第二个 printf 中,a 和 c 都返回错误。但 b 和 d 顺利地被另一个字符串替换并被“覆盖”。

我对这个结果感到非常困惑,似乎“const”关键字对字符串赋值没有影响;但它对索引字符突变有影响。char[] 和 char* 也表现出不同的行为。有人可以向我解释一下这背后的机制吗?

caf*_*caf 3

const如果您希望最大化将数组放入实际只读内存中的机会,您static也应该将它们设置为:

static const char c[] = "abcdef";
Run Code Online (Sandbox Code Playgroud)

这是因为所有具有自动存储期限的变量通常都是在同一内存区域中创建的,无论它们是否是const- 限定。因此,该内存区域不能设为只读。

但是,鉴于您的实现显然也不将字符串文字放入只读内存中,因此它可能根本不使用只读内存,并且警告可能是您所希望的最好结果。如果您使用基于 gcc 的编译器,您也可以尝试-fno-writable-strings编译器选项。


这两行错误的原因是:

a = "overwrited";
c = "overwrited";
Run Code Online (Sandbox Code Playgroud)

因为ac是数组,而数组不能直接用运算符赋值=(无论是否const)。变量声明=中的 不是=运算符 - 它只是初始化语法的一部分,并且可以初始化数组。

这些行没问题的原因是:

b = "overwrited";
d = "overwrited";
Run Code Online (Sandbox Code Playgroud)

是因为bd是指向常量 s 的非常量指针char。这些赋值不会改变bandd指向的原始字符串——它们会改变bd指向不同的字符串(实际上可能是相同的字符串)。

如果您希望bd成为常量指针(以便指针本身无法更改),您可以更改声明:

char * const b = "abcdef";
const char * const d = "abcdef";
Run Code Online (Sandbox Code Playgroud)

b..并且对和 的赋值d至少应该从编译器发出错误消息。