Я собирался ответить на чей-то вопрос о том, что printf принимает char *, поэтому я создал небольшую тестовую программу и задал свой вопрос. скомпилировано на codechef.com/ide с GCC 6.3
Передайте char* непосредственно в 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
это трейн 3
Это строка 4
Я рассматривал схему памяти программы и еще больше запутался. https://www.geeksforgeeks.org/memory-layout-of-c-program/
str1 — это указатель на строковый литерал «это строка 1\n». str1 живет в данных и указывает на строковый литерал, который живет в ?? (я предполагал также инициализированный сегмент данных) Как реализована память только для чтения в С?
str2 похож на str1 в том, что касается схемы памяти.
str3, вот где становится интересно. str3 живет в стеке шириной 100 символов, и ему назначается char[0] = 'T', char[1] = 'h' и т. д. с объявлением/назначением. Это НЕ ДОЛЖНО БЫТЬ ПОСТОЯННЫМ. Объявление и назначение str3 объявляют 100 символов в стеке и присваивают им значения из данных (либо из сегмента данных, либо из инициализированного сегмента данных, либо из текста?).
str4 — это указатель на стек, указывающий на память сегмента данных. Это как str1 и str2, не слишком интересно.
Затем назначение str3[8] = 'c' только для проверки/проверки/демонстрации того, что память стека для str3 НЕ читается только перед печатью.
Я бы ожидал, что 1,2,4 сработает, но почему сработало 3 (даже не предупреждение компилятора???). Я, вероятно, неправильно предполагаю, что const является синонимом «только для чтения», потому что невозможно, чтобы str3 был «только для чтения», если я только что написал в него.
Есть ли в стеке память только для чтения для константной переменной, объявленной в функции?
Может ли кто-нибудь объяснить мне, почему str3 не выдает предупреждение или ошибку? str3 не является const char *, либо компилятор оптимизировал его (изменив назначение на «This is ctring 3\n»), либо предупреждения были подавлены (также маловероятно), либо у меня есть фундаментальное непонимание ключевого слова cost . Как константа памяти стека? Возможно, одно или несколько моих предположений ошибочны.