Да, время жизни локальной переменной находится в области ({
, }
), в которой она создана.
Локальные переменные имеют автоматическое или локальное хранилище.
Автоматически , поскольку они автоматически уничтожаются, как только заканчивается область, в которой они были созданы.
Однако у вас есть строковый литерал, который выделяется в памяти, определенной для реализации, только для чтения. Строковые литералы отличаются от локальных переменных и остаются живыми в течение всего времени жизни программы. Они имеют статическую длительность [Ref 1] время жизни.
Слово предостережения!
Однако обратите внимание, что любая попытка изменить содержимое строкового литерала является неопределенным поведением.
Пользовательские программы не могут изменять содержимое строкового литерала.
Следовательно, всегда рекомендуется использовать const
при объявлении строкового литерала.
const char*p = "string";
вместо
char*p = "string";
Фактически, в C ++ не рекомендуется объявлять строковый литерал без const
, хотя не в c. Тем не менее, объявление строкового литерала с const
дает вам преимущество в том, что компиляторы обычно выдают предупреждение в случае, если вы попытаетесь изменить строковый литерал во втором случае.
Пример программы :
#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: предупреждения рассматриваются как ошибки
prog.c: в функции «main»:
prog.c: 9: ошибка: при передаче аргумента 1 из strcpy отбрасывает квалификаторы из целевого типа указателя
Обратите внимание, что компилятор предупреждает о втором случае, но не о первом.
РЕДАКТИРОВАТЬ: Чтобы ответить на вопрос, задаваемый несколькими пользователями здесь:
Как обстоят дела с целочисленными литералами?
Другими словами, действителен ли этот код:
int *foo()
{
return &(2);
}
Ответ: Нет, этот код недействителен, он некорректен и выдаст ошибку компилятора.
Что-то вроде:
prog.c:3: error: lvalue required as unary ‘&’ operand
Строковые литералы являются l-значениями, т.е. вы можете взять адрес строкового литерала, но не можете изменить его содержимое.
Однако любые другие литералы (int
, float
, char
и т. Д.) Являются r-значениями (в стандарте c используется термин значение выражения для них), и их адрес не может быть получен в все.
[Ссылка 1] Стандарт C99 6.4.5 / 5 "Строковые литералы - семантика":
На этапе 7 перевода байт или код нулевого значения добавляются к каждой многобайтовой последовательности символов, которая является результатом строкового литерала или литералов. Последовательность многобайтовых символов затем используется для инициализации массива статической продолжительности и длины хранения, достаточных для размещения последовательности . Для строковых литералов символов элементы массива имеют тип char и инициализируются отдельными байтами многобайтовой последовательности символов; для широких строковых литералов элементы массива имеют тип wchar_t и инициализируются последовательностью широких символов ...
Не определено, различаются ли эти массивы при условии, что их элементы имеют соответствующие значения. Если программа пытается изменить такой массив, поведение не определено .