Локальные переменные для цикла в C
Почему следующий код выводит одну и ту же ячейку памяти каждый раз?
int x;
for (x = 0; x < 10; x++) {
int y = 10;
printf("%p\n", &y);
}
Я думал, что место памяти должно измениться, поскольку каждый раз, когда выполняется цикл for, переменная является новой.
Ответы
Ответ 1
Да, вы абсолютно правы, что местоположение памяти может измениться. Но это не обязательно:). На каждой итерации старая переменная "разрушается", а новая "создается" в одном месте. Хотя любой достойный компилятор оптимизирует ненужные "действия"
Ответ 2
Да, переменная является новой каждый раз, но в конце блока все новые переменные в стеке снова освобождаются.
Следовательно, следующий раз указатель стека возвращается туда, где он был. NB: это обычное поведение, но не гарантируется стандартами.
Ответ 3
Это оптимизация компилятора. Поскольку локальная переменная выходит за пределы области видимости, и переменная того же типа будет создана, она повторно использует адрес памяти. Важно отметить, что это все еще "свежая" или "новая" переменная в отношении вашей программы.
Сравните следующие фрагменты кода и вывод:
for (i = 0; i < 3; i++) {
int n = 0;
printf("%p %d\n", (void *)&n, n++);
}
0x7fff56108568 0
0x7fff56108568 0
0x7fff56108568 0
for (i = 0; i < 3; i++) {
static int n = 0;
printf("%p %d\n", (void *)&n, n++);
}
0x6008f8 0
0x6008f8 1
0x6008f8 2
Ответ 4
Правила определения областей для переменных описывают только область, в которой вы имеете право на доступ к локальной переменной: от определения до конца своего блока.
Это правило ничего не говорит о том, что пространство зарезервировано для него. Общей стратегией для этого является резервирование пространства для всех переменных, которые понадобятся для вызова функции сразу, в начале функции.
Поэтому, когда выполнение пересекает определение переменной, обычно ничего особо не нужно делать, а не одной инструкции. С другой стороны, это значение переменной остается неизменным. Поэтому важность инициализации в известном состоянии, как и в вашем примере с = 10
.