我要回答有关printf接受char *的问题,所以我建立了一个小测试程序并提出了自己的问题。使用GCC 6.3在codechef.com/ide上编译
Pass the char* directly to printf 我认为问题是在问“缺少” const限定词发生了什么吗? http://man7.org/linux/man-pages/man3/printf.3.html
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;
}
输出:
这是字符串1
这是字符串2
这是ctring 3
这是字符串4
我当时正在考虑程序的内存布局,我感到更加困惑。 https://www.geeksforgeeks.org/memory-layout-of-c-program/
str1是指向字符串文字“这是字符串1 \ n”的指针。 str1位于数据中,并指向位于??中的字符串文字。 (我假设还初始化了数据段) How is read-only memory implemented in C?
就内存布局而言,str2类似于str1。
str3变得很有趣。 str3驻留在堆栈中,宽度为100个字符,并通过声明/赋值分配给char [0] ='T',char [1] ='h'等。这不应该是常量。 str3的声明和赋值是在堆栈上声明100个字符,并从数据(rom数据段或初始化的数据段或文本?)中为它们分配值。
str4是堆栈上的一个指针,指向数据段内存。就像str1和str2一样,不太有趣。
然后分配str3 [8] ='c'只是为了测试/验证/证明str3的堆栈内存不是仅在printfing之前读取的。
我希望1,2,4可以工作,但是为什么3可以工作(甚至没有编译器警告??)。我可能会错误地假设const是“只读”的同义词,因为如果我刚刚写的话,str3就不可能是“只读”。
Is there a read only memory in the stack for const variable declared in a function?
有人可以向我解释为什么str3没有引发警告或错误吗? str3不是const char *,要么编译器对其进行了优化(将赋值更改为“ This is ctring 3 \ n”),要么警告被抑制(似乎不太可能),或者我对cost关键字有基本的误解。堆栈内存常量如何?也许我的一个或多个假设是错误的。
答案 0 :(得分:3)
当函数原型包含指向const
限定对象的指针时,这意味着该函数承诺不会尝试修改指向的内容。这并不意味着只能接受指向const
对象的指针(无论可能是什么)。
另一方面,如果原型包含指向 const
不合格的对象的指针,则意味着它可能会尝试修改其内容。在这种情况下,将指针传递给不可变对象将导致未定义的行为。如果尝试将指针传递到const
限定对象(如果启用警告),则大多数编译器都会警告您,因为const
限定的指针可能指向不可变的对象。
通常来说,您应该将const
理解为“我保证不会修改”,而不是“无法修改”。