C字符串操作指针与数组表示法

C字符串操作指针与数组表示法,c,string,C,String,为什么第一个版本会使程序崩溃,而第二个版本不会?他们不是一回事吗 指针表示法 数组表示法 MWE 不!这是C语言中的一个重要问题。首先,创建指向内存只读部分的指针,即不能更改它,只能读取它。第二种方法是创建一个字符数组,即连续字符内存的一部分,在这里您可以同时具有读写访问权限,这意味着您可以读取和更改数组的值。这将创建一个指向现有字符串的指针: char *shift = "mondo"; 这将创建一个新的字符数组: char shift[] = {'m', 'o', 'n', 'd',

为什么第一个版本会使程序崩溃,而第二个版本不会?他们不是一回事吗

指针表示法
数组表示法
MWE
不!这是C语言中的一个重要问题。首先,创建指向内存只读部分的指针,即不能更改它,只能读取它。第二种方法是创建一个字符数组,即连续字符内存的一部分,在这里您可以同时具有读写访问权限,这意味着您可以读取和更改数组的值。

这将创建一个指向现有字符串的指针:

char *shift = "mondo";
这将创建一个新的字符数组:

char shift[] = {'m', 'o', 'n', 'd', 'o', '\0'};
在第二种情况下,您可以修改字符,因为它们是您刚刚创建的字符

在第一种情况下,您只是指向一个不应该修改的现有字符串。字符串存储位置的详细信息取决于特定的编译器。例如,它可以将字符串存储在不可修改的内存中。编译器还可以使用一些技巧来节省空间。例如:

 char *s1 = "hello there";
 char *s2 = "there";
s2
实际上可能指向与
s1
所指向的字符串第七个位置相同的字母“t”

为避免混淆,建议使用带有字符串文字的常量指针:

const char *shift = "mondo";

这样,如果您不小心试图修改它,编译器会让您知道。

第一个指向字符串文字(通常在代码的只读部分中,实际上应该是
const char*
,但由于历史原因,可以不使用它)|

第二个创建一个数组,然后填充该数组


因此,它们是不同的

第一个在.TEXT段中分配内存,而第二个在.BSS中分配内存。.TEXT段中的内存实际上是只读的或常量:

 char *string = "AAAA";
这将创建一个有效的
常量char*
,因为内存将作为字符串文本在.TEXT段中分配。由于这通常被标记为只读,因此尝试对其进行写入将生成访问冲突或分段错误

您要执行以下操作:

 char string[] = "AAAA";

这将按预期工作,为四个大写的字符串分配内存,并使用变量
string
作为指向位置的指针。

每当使用
char*str=“你好”
这是由编译器隐式表示的
const char*str=“你好”
这使得这个符号变成程序内存的只读位置

但在数组的情况下,将其解释为
char const*数组[]
这就是为什么当用户试图更改数组的基址时,编译器会尖叫。

这是由编译器隐式完成的

@user3121023为什么?即使我没有使用
const
?@user3379939-由于历史原因,不需要const。早在70年代,他们还不太清楚——summat与花的力量和感激之情有关dead@user3121023:字符串文字(如
“mondo”
)的分配方式可能是可写的,也可能是不可写的;这取决于平台。在您的情况下,它是不可写的,因此会出现错误。一般来说,行为是未定义的;它可能会工作,它可能会崩溃,它可能会做其他事情。@CoolGuy:最低限度的工作示例。对不起,我没有完全理解你的意思P如果您只想访问这些字符进行读取,则char*string=“string”是有效的。是的,显然,如果你想更改这部分内存中任何字符的任何值,你要么使用数组,就像你所展示的那样,要么动态分配内存。我会更新以澄清……好的,现在我明白你的意思了。但这是不对的。第一种方法是分配一部分4个连续字节的内存,在每个字节中存储十六进制0x41中的“a”值,然后返回第一个字节的地址,“string”是指向该地址的指针。只是你不能改变这个内存,它是只读的。如果使用gdb之类的调试器,您可以理解我的意思完全不准确。尝试编译一些包含
char*string=“AAAA”的代码
并查看生成的汇编代码。它实际上是在内存中(通常在
.text
段中)创建一个字符串literal
“AAAA”
,然后将该literal的地址分配给指针。当试图修改只读内存中存储的值时,程序崩溃。就像zuko32所说的,从那个地址读是可以的,但写信是不行的。我会查一查。。这不是我对发生了什么的理解。你把
常数
放在了
*
的错误的一边。好的,我明白你的意思了
const char *shift = "mondo";
 char *string = "AAAA";
 char string[] = "AAAA";