通过指针与数组写入字符串文字
Writing to string literal through pointer vs. array
在K&R C(第2版)的第5章中,给出了以下两种说法,据说有细微差别(我是照原样粘贴的)
There is an important difference between these definitions:
char amessage[] = "now is the time"; /* an array */
char *pmessage = "now is the time"; /* a pointer */
amessage
is an array, just big enough to hold the sequence of
characters and '[=12=]'
that initializes it. Individual characters within
the array may be changed but amessage
will always refer to the same
storage. On the other hand, pmessage
is a pointer, initialized to
point to a string constant; the pointer may subsequently be modified
to point elsewhere, but the result is undefined if you try to modify
the string contents.
我不明白他们想在这里暗示什么。它表示对于 pmessage
,如果您尝试修改字符串常量,结果是未定义的。他们说的结果是什么,我们怎么修改字符串常量,为什么结果会是未定义的?
它还说 amessage
总是指向相同的存储。这个存储是数组在定义时分配的存储吗?
谁能用更好的方式解释一下?我将不胜感激!!
What is the result they are talking about,
运行 代码的结果。它可能会工作,也可能会崩溃,还有很多其他事情。
how can we modify the string constants
你不能,除非编译器通过某种扩展提供它。如果需要修改,请不要使用字符串文字。
and why will the result be undefined ?
因为标准是这么说的
可以提到,在C++中,字符串文字的类型是const char[]
,但在C中是char[]
。这是历史原因。
这是未定义的原因是因为不能保证在每个体系结构上。
在旧机器上(比如 Amiga 1000)你没有 MMU,所以如果你写到“禁止区域”它会工作。在现代平台(如 Linux 或 Windows 等)上有一个 MMU,它可以防止写入某些区域。
一般这样的字符串常量都放在只读区,如果平台支持的话会抛出异常。
这就是它未定义的原因。该语言不能保证在所有情况下都会发生某种行为,因此它可能有效,也可能无效。
将它放在一个数组中,将始终保证这一点,但使用带有指针的字符串文字,则不能。
What is the result they are talking about, how can we modify the string constants and why will the result be undefined ?
未定义的行为没有特定的结果,对于调用未定义行为的格式错误的程序没有任何要求,这意味着它可以做任何事情。尝试修改字符串常量的程序就是此类程序的一个示例。
你可以查看未定义行为的C11定义here
Also it says that amessage
always points to the same storage. Is this storage the storage the array is allocated when it gets defined?
amessage
就是所谓的固定大小数组,它是给定内存地址的别名,一旦它被初始化为该内存地址,它就不能更改,直到变量生命周期结束, points 部分不是我会使用的部分,它可以说是糟糕的措辞,因为 amessage
不是指针,更多关于 here.
另一方面,*pmessage
是一个指针,因此你可以让它指向其他内存地址,你甚至可以让它指向 amessage
即 pmessage = amessage
,现在pmessage
指向与amessage
完全相同的位置,现在可以访问amessage
或通过该指针进行修改,但 amessage = pmessage
是不可能的。
在K&R C(第2版)的第5章中,给出了以下两种说法,据说有细微差别(我是照原样粘贴的)
There is an important difference between these definitions:
char amessage[] = "now is the time"; /* an array */ char *pmessage = "now is the time"; /* a pointer */
amessage
is an array, just big enough to hold the sequence of characters and'[=12=]'
that initializes it. Individual characters within the array may be changed butamessage
will always refer to the same storage. On the other hand,pmessage
is a pointer, initialized to point to a string constant; the pointer may subsequently be modified to point elsewhere, but the result is undefined if you try to modify the string contents.
我不明白他们想在这里暗示什么。它表示对于 pmessage
,如果您尝试修改字符串常量,结果是未定义的。他们说的结果是什么,我们怎么修改字符串常量,为什么结果会是未定义的?
它还说 amessage
总是指向相同的存储。这个存储是数组在定义时分配的存储吗?
谁能用更好的方式解释一下?我将不胜感激!!
What is the result they are talking about,
运行 代码的结果。它可能会工作,也可能会崩溃,还有很多其他事情。
how can we modify the string constants
你不能,除非编译器通过某种扩展提供它。如果需要修改,请不要使用字符串文字。
and why will the result be undefined ?
因为标准是这么说的
可以提到,在C++中,字符串文字的类型是const char[]
,但在C中是char[]
。这是历史原因。
这是未定义的原因是因为不能保证在每个体系结构上。
在旧机器上(比如 Amiga 1000)你没有 MMU,所以如果你写到“禁止区域”它会工作。在现代平台(如 Linux 或 Windows 等)上有一个 MMU,它可以防止写入某些区域。 一般这样的字符串常量都放在只读区,如果平台支持的话会抛出异常。 这就是它未定义的原因。该语言不能保证在所有情况下都会发生某种行为,因此它可能有效,也可能无效。
将它放在一个数组中,将始终保证这一点,但使用带有指针的字符串文字,则不能。
What is the result they are talking about, how can we modify the string constants and why will the result be undefined ?
未定义的行为没有特定的结果,对于调用未定义行为的格式错误的程序没有任何要求,这意味着它可以做任何事情。尝试修改字符串常量的程序就是此类程序的一个示例。
你可以查看未定义行为的C11定义here
Also it says that
amessage
always points to the same storage. Is this storage the storage the array is allocated when it gets defined?
amessage
就是所谓的固定大小数组,它是给定内存地址的别名,一旦它被初始化为该内存地址,它就不能更改,直到变量生命周期结束, points 部分不是我会使用的部分,它可以说是糟糕的措辞,因为 amessage
不是指针,更多关于 here.
*pmessage
是一个指针,因此你可以让它指向其他内存地址,你甚至可以让它指向 amessage
即 pmessage = amessage
,现在pmessage
指向与amessage
完全相同的位置,现在可以访问amessage
或通过该指针进行修改,但 amessage = pmessage
是不可能的。