通过指针与数组写入字符串文字

问题描述

在K&R C(第2版)的第5章中,给出了以下两个陈述,据说有细微差别(我按原样粘贴文本)

这些定义之间有一个重要的区别:

char amessage[] = "Now is the time"; /* an array */

char *pmessage = "Now is the time"; /* a pointer */

amessage一个数组,刚好足以容纳 字符和初始化它的 '\0'。内的个别字符 数组可能会更改,但 amessage 将始终引用相同的 贮存。另一方面,pmessage一个指针,初始化为 指向一个字符串常量;指针可能随后被修改 指向别处,但如果您尝试修改,则结果未定义 字符串内容

我无法理解他们在这里想暗示什么。它表示对于 pmessage,如果您尝试修改字符串常量,结果是未定义的。他们说的结果是什么,我们如何修改字符串常量,为什么结果会是undefined?

它还说 amessage 总是指向同一个存储。这个存储是数组在定义时分配的存储吗?

有人可以用更好的方式解释一下吗?我将不胜感激!!

解决方法

之所以未定义,是因为不能保证在每个架构上都可以。

在较旧的机器上(例如 Amiga 1000),您没有 MMU,因此如果您写入“禁区”,它将起作用。在现代平台(如 Linux 或 Windows 等)上,有一个 MMU,可以防止写入某些区域。 通常这样的字符串常量被放入只读区域,如果平台支持它会导致异常。 这就是它未定义的原因。语言不能保证在所有情况下都会发生某种行为,因此它可能会起作用,也可能不会起作用。

把它放在一个数组中,总是可以保证,但使用带有指针的字符串文字,则不能。

,

他们说的结果是什么,我们如何修改字符串常量,为什么结果是未定义的?

未定义行为没有特定的结果,对于调用未定义行为的格式错误的程序没有要求,这意味着它可以做任何事情。试图修改字符串常量的程序就是这种程序的一个例子。

您可以检查未定义行为的 C11 定义 here

它还说 amessage 总是指向同一个存储。这个存储是数组在定义时分配的存储吗?

amessage 是所谓的固定大小数组,它是给定内存地址的别名,一旦初始化为该内存地址,它就无法更改,直到变量生命周期结束, 指出 部分不是我会使用的,它可以说是不好的措辞,因为 amessage 不是指针,更多关于 here

*pmessage 另一方面是一个指针,因此你可以让它指向其他内存地址,你甚至可以让它指向 amessage ie pmessage = amessage,现在 pmessage 指向与 amessage 完全相同的位置,现在可以通过该指针访问或修改 amessage,但是 { {1}} 是不可能的。

,

他们谈论的结果是什么,

运行代码的结果。它可能会起作用,也可能会崩溃,以及许多其他问题。

我们如何修改字符串常量

你不能,除非编译器通过某种扩展提供了这个。如果需要修改,请不要使用字符串文字。

为什么结果是未定义的?

因为标准是这样说的

可以提到的是,在C++中,字符串字面量的类型是const char[],而在C中是char[]。这是历史原因。