Подтвердить что ты не робот

Локальные переменные для цикла в C

Почему следующий код выводит одну и ту же ячейку памяти каждый раз?

int x;
for (x = 0; x < 10; x++) {
    int y = 10;
    printf("%p\n", &y);
}

Я думал, что место памяти должно измениться, поскольку каждый раз, когда выполняется цикл for, переменная является новой.

4b9b3361

Ответ 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.