Локальные переменные цикла for в C - PullRequest
14 голосов
/ 28 февраля 2011

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

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

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

Ответы [ 4 ]

18 голосов
/ 28 февраля 2011

Да, вы абсолютно правы, что ячейка памяти может измениться. Но это не обязательно :). В каждой итерации старая переменная «уничтожается», а новая «создается» в одном и том же месте. Хотя любой приличный компилятор оптимизировал бы ненужные «действия» подальше

5 голосов
/ 28 февраля 2011

Да, переменная каждый раз новая, но в конце блока все новые переменные в стеке снова освобождаются.

Следовательно, в следующий раз указатель стека вернется точно туда, где он был. NB: это обычное поведение, но не гарантируется по стандартам.

3 голосов
/ 28 февраля 2011

Это оптимизация компилятора.Поскольку локальная переменная выходит из области видимости, а переменная того же типа собирается создаваться, она повторно использует адрес памяти.Важно отметить, что это все еще «новая» или «новая» переменная в том, что касается вашей программы.

Сравните следующие фрагменты кода и выходные данные:

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
0 голосов
/ 28 февраля 2011

Правила области видимости для переменных описывают только область, в которой вы имеете право доступа к локальной переменной: от определения до конца ее блока.

Это правило ничего не говорит о том моменте, когда для него зарезервировано пространство. Обычная стратегия для этого - зарезервировать место для всех переменных, которые понадобятся для вызова функции сразу, в начале функции.

Таким образом, когда выполнение пересекает определение переменной, обычно ничего не нужно делать, ни единой инструкции. С другой стороны, это оставляет значение этой переменной тем, что было найдено ранее. Так что важность инициализации в известное состояние, как вы сделали в своем примере с = 10.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...