Да, время жизни локальной переменной находится в пределах области ({
, }
), в которой она создана.
Локальные переменные имеют автоматическое или локальное хранилище.
Automatic потому что они автоматически уничтожаются после того, как область действия, в которой они созданы, заканчивается.
Однако у вас есть строковый литерал, который выделяется в определенной для реализации памяти только для чтения. Строковые литералы отличаются от локальных переменных, и они остаются в живых на протяжении всей жизни программы. Они имеют статическая продолжительность[Ref 1] lifetime.
Осторожно!
Однако обратите внимание, что любая попытка изменить содержимое строкового литерала - это неопределенное поведение. Пользовательским программам не разрешается изменять содержимое строкового литерала.
Следовательно, всегда рекомендуется использовать const
при объявлении строкового литерала.
const char*p = "string";
вместо того,
char*p = "string";
В самом деле, в C++ это не рекомендуется, чтобы объявить строку буквального без const
хотя и не в с. Однако объявление строкового литерала с помощью const
дает вам преимущество в том, что компиляторы обычно выдавали вам предупреждение, если вы попытаетесь изменить строковый литерал во втором случае.
Sample program:
#include<string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[]="Sample string";
strcpy(str1,source); //No warning or error just Uundefined Behavior
strcpy(str2,source); //Compiler issues a warning
return 0;
}
Выход:
cc1: warnings being treated as errors
prog.c: In function ‘main’:
prog.c:9: error: passing argument 1 of ‘strcpy’ discards qualifiers from pointer target type
Обратите внимание, что компилятор предупреждает для второго случая, но не для первой.
EDIT: Для того, чтобы ответить на Q попросили парой пользователей здесь:
Что такое сделка с целыми литералов?
Других слов этот код действителен:
int *foo()
{
return &(2);
}
Ответ, Нет, это не правильный код, он плохо сформированный & выдаст ошибку компилятора.
Что-то вроде:
prog.c:3: error: lvalue required as unary ‘&’ operand
Строковые литералы л-значения, то есть: Вы можете взять адрес в строку буквального, но не может изменить его содержание.
Тем не менее, любые другие литералами (int
, float
, char
и т.д.) являются г-значением (C стандарт использует термин значение выражения для них) & их адреса не может быть принят на всех.
[Ссылка 1]C99 стандарт 6.4.5/5 "Строковые литералы - Семантика":
Единственный «var», который у вас есть в вашей функции, - это параметр 'int rc'. Его срок службы заканчивается на каждом из «возвратов». Указатели, которые вы возвращаете, являются строковыми литералами. Строковые литералы имеют статическую продолжительность хранения: их срок службы по крайней мере такой же продолжительный, как и у программы. – Kaz
Что делать, если это не строковый литерал, а другие литералы, такие как: int * foo() {return &(2); // или // int n = 2; // return & n; } –
Отметьте Edit в моем ответе, который обращается к вашему запросу. Обратите внимание, что вы должны были разместить это как комментарий, а не ответ. В комментариях должны быть опубликованы комментарии, сомнения и т. Д., Ответы должны быть опубликованы только в ответах. –