当我声明并运行以下命令时,它给了我一个分段错误。
main()
{
char *p = "boa";
*(p+1) = 'y';
printf("%s",p);
}
我怀疑char *p
是一个常数,等等。
但以下工作正常。
main()
{
int i = 300;
char *p = (char*)&i;
*(p+1) = 'y';
printf("%s",p);
}
这背后的原因是什么?上述规则是否也适用于此?
这取决于您对“工作正常”的定义。但是赋值没有分段错误的原因是因为p
指向i
变量的地址,这显然不是一个常量。i
被分配了一个常数值,但i
它本身不是一个常数。
对于i = 300
(假设 little endian x86):
+--+--+--+--+
i:|2c|01|00|00|
+--+--+--+--+
.
/|\
|
p:&i
后*(p+1) = 'y'
+--+--+--+--+
i:|2c|79|00|00|
+--+--+--+--+
.
/|\
|
p:&i
因此,打印语句恰好,y
为您打印,但这只是因为您依赖于平台的字节顺序(这2c
是一个可打印的ASCII字符)。在大端机器上,和/或如果它是非 ASCII 的,情况可能会有所不同。
区别在于:
char *p="boa";
p
是一个指针。您正在指出无法修改p
的字符串文字,并且当您尝试修改它时会发生段错误。"boa"
int i=300;
char *p=(char*)&i;
i
是类型的变量int
,您只使用常量300
来初始化i
并将 的值按位复制300
到 的位置i
,但您永远不会指向常量本身,只是将其用作初始化程序。这就是区别,p
在您的第一个示例中,它指向一个常量字符串文字,而在您的第二个示例中,它指向一个 type 的变量int
。因此,i
稍后使用指针修改位置就可以了,p
因为您正在修改非常量对象i
。
好家伙...
由于字符串存在const
(你说得对),第一个 seg-faults 。然而,第二个是对指针语义的迷人滥用!;-)
这是您在第二个示例中所做的事情:
int
带有值的随机数(在你的情况下 - 300
)int
- 基本上是一个地址到一个包含int
300 (32位?)的位置并将其转换为 a char*
,其中每个元素都指向一个 8 位值