我最近了解到可以使用指针更改c中的常量值,但字符串文字不可能。可能的解释在于,常量和其他字符串在空间中的可修改区域中被分配空间,而字符串文字在空间(可能是代码段)中进入不可修改的区域。我编写了一个显示这些变量地址的程序。输出也显示出来。
#include <stdio.h>
int x=0;
int y=0;
int main(int argc, char *argv[])
{
const int a =5;
const int b;
const int c =10;
const char *string = "simar"; //its a literal, gets space in code segment
char *string2 = "hello";
char string3[] = "bye"; // its array, so gets space in data segment
const char string4[] = "guess";
const int *pt;
int *pt2;
printf("\nx:%u\ny:%u Note that values are increasing\na:%u\nb:%u\nc:%u Note that values are dec, so they are on stack\nstring:%u\nstring2:%u Note that address range is different so they are in code segment\nstring3:%u Note it seems on stack as well\nstring4:%u\n",&x,&y,&a,&b,&c,string,string2,string3,string4);
}
请解释这些变量究竟在哪里获得空间? 全局变量在哪里获取空间,常量在哪里得到,字符串文字在哪里得到??
答案 0 :(得分:5)
“可能”过度陈述案例。
您可以编写尝试修改const对象的代码(例如,通过将其地址转换为指向非const类型的指针)。您还可以编写尝试修改字符串文字的代码。
在这两种情况下,您的代码都有未定义的行为,这意味着标准并不关心会发生什么。实现可以做它喜欢的事情,发生的事情通常是其他重要的事情的偶然副作用。你不能依赖这种行为。简而言之,那段代码是错误的。定义为const
和字符串文字的对象都是如此。
可能在特定实现中,效果是更改对象或文字。可能是在另一个实现中,您遇到访问错误并且程序崩溃。可能是在第三种实现中,有时会出现一种行为,有时会出现另一种行为。可能会发生完全不同的事情。
它是变量获取空间的特定于实现的,但在典型的实现中:
x
和y
位于可修改的数据段a
在堆栈中。如果不是因为你接受了它的地址,那么可以完全优化变量存储,并且值5
在编译器为使用{的代码发出的任何CPU指令中用作立即值。 {1}}。a
我认为是一个错误 - 未初始化的const对象。也许这是允许的,但编译器可能应该警告。b
位于堆栈中,与c
相同。a
和string3
是堆栈中的数组。每个都是通过复制字符串文字的内容来初始化的。答案 1 :(得分:1)
我最近了解到可以使用指针
更改c中的常量值
这样做会导致未定义的行为(参见标准6.7.3),这意味着任何事情都可能发生。实际上,您可以修改某些基于RAM的系统上的常量。
字符串文字不可能
这同样是未定义的行为,可能会起作用,也可能不起作用,或者可能导致蓝色烟雾从你的硬盘中升起。
可能的解释在于,常量和其他字符串在空间中的可修改区域中分配空间,而字符串文字在空间中进入不可修改的区域
这与系统有关。在某些系统上,它们都位于恒定/虚拟RAM段中,有些可能位于非易失性闪存中。讨论关于事物在内存中的最终位置是没有意义的,没有说明你在谈论什么系统。没有通用的案例。