C 堆栈上的常量数据?

C 堆栈上的常量数据?,c,stack,printf,constants,memory-layout,C,Stack,Printf,Constants,Memory Layout,我打算回答一些人关于printf接受char*的问题,所以我构建了一个小测试程序,并提出了自己的问题。使用GCC 6.3在codechef.com/ide上编译 我想问题是“失踪”const限定符发生了什么,对吗? 产出: 这是字符串1 这是一个字符串2 这里是ctring 3 这是字符串4 我在考虑程序的内存布局,我甚至更加困惑 str1是指向字符串文字“this a string 1\n”的指针。str1存在于数据中,并指向存在于中的字符串文本??(我假设还初始化了数据段) 就内存布局

我打算回答一些人关于printf接受char*的问题,所以我构建了一个小测试程序,并提出了自己的问题。使用GCC 6.3在codechef.com/ide上编译

我想问题是“失踪”const限定符发生了什么,对吗?

产出:

这是字符串1

这是一个字符串2

这里是ctring 3

这是字符串4

我在考虑程序的内存布局,我甚至更加困惑

str1是指向字符串文字“this a string 1\n”的指针。str1存在于数据中,并指向存在于中的字符串文本??(我假设还初始化了数据段)

就内存布局而言,str2与str1类似

str3是它变得有趣的地方。str3位于堆栈上,宽100个字符,并通过声明/赋值为char[0]='T',char[1]='h'等赋值。这不应该是常数。str3的声明和赋值是在堆栈上声明100个字符,并根据数据(rom数据段或初始化数据段或文本?)为它们赋值

str4是堆栈上的指针,指向数据段内存。这就像str1和str2,不太有趣

然后分配str3[8]=“c”只是为了在打印前测试/验证/证明str3的堆栈内存不是只读的

我希望1,2,4可以工作,但为什么3可以工作(甚至没有编译器警告??)。我可能错误地认为const是“只读”的同义词,因为如果我只写str3,它就不可能是“只读”的


有人能解释一下为什么str3没有抛出警告或错误吗?str3不是const char*,要么是编译器优化了它(将赋值更改为“This is ctring 3\n”),要么是警告被抑制(似乎也不太可能),要么是我对cost关键字有一个根本性的误解。堆栈内存常量如何?可能我的一个或多个假设是错误的。

当函数原型包含指向限定对象的指针时,这意味着函数承诺不会尝试修改指向的内容。这并不意味着只能接受指向
const
对象(不管是什么)的指针

另一方面,如果原型包含指向对象的指针,而该对象不是
const
-限定的,这意味着它可能会尝试修改内容。在这种情况下,向不可变对象传递指针将导致未定义的行为。如果您试图传递指向
常量
限定对象的指针(如果启用警告),大多数编译器都会发出警告,因为
常量
限定指针可能指向不可变对象


一般来说,您应该将
const
理解为“我承诺不修改此内容”,而不是“此内容无法修改”。

当函数原型包含指向
const
限定对象的指针时,这意味着函数承诺不尝试修改指向的内容。这并不意味着只能接受指向
const
对象(不管是什么)的指针

另一方面,如果原型包含指向对象的指针,而该对象不是
const
-限定的,这意味着它可能会尝试修改内容。在这种情况下,向不可变对象传递指针将导致未定义的行为。如果您试图传递指向
常量
限定对象的指针(如果启用警告),大多数编译器都会发出警告,因为
常量
限定指针可能指向不可变对象


一般来说,你应该把
const
理解为“我保证不修改这个”而不是“这个不能修改”.

你是说当你传递一个非常量时,你希望编译器在传递一个常量时发出警告吗?@John3136是的,这是我所期望的。你是说当你传递一个非常量时,你希望编译器在传递一个常量时发出警告吗?@John3136是的,这是我所期望的。谢谢你的澄清。我已经接受了你的答案,因为它是有意义的,但是你有一个链接让我可以了解更多吗?@bwebb:任何好的C编程文本:)(但不是K&R;它太旧了。)话虽如此,我没有任何建议。对不起,谢谢你的澄清。我已经接受了你的答案,因为它是有意义的,但是你有一个链接让我可以了解更多吗?@bwebb:任何好的C编程文本:)(但不是K&R;它太旧了。)话虽如此,我没有任何建议。很抱歉
char * str1 = "This is string 1\n";
char str2[] = "This is string 2\n";
int main(void) {

    char str3[100] = "This is string 3\n";
    char * str4 = "This is string 4\n";

    str3[8] = 'c';

    printf(str1);
    printf(str2);
    printf(str3);
    printf(str4);

    return 0;
}