Почему компилятор назначил разные адреса памяти одной и той же переменной после переопределения переменной? - PullRequest
1 голос
/ 09 октября 2019

Код выглядит следующим образом:

#include <stdio.h>
int main()
{
    int i;
    printf("%p\n",&i);
    for (i = 0; i < 5; i++)
    {
        int i = 10;
        printf("%d %p\n", i,&i);
        i++;
    }
    return 0;
}

Сначала мы определили переменную i (сразу после main). Затем в начале цикла for мы снова определили ту же самую переменную i. Таким образом, внутри цикла for значение i равно 10. Цикл for должен повторяться только один раз, поскольку i>5 после первой итерации. Но, к моему удивлению, вывод выглядит следующим образом:

0x7ffe8b799da0
10 0x7ffe8b799da4
10 0x7ffe8b799da4
10 0x7ffe8b799da4
10 0x7ffe8b799da4
10 0x7ffe8b799da4

Мои вопросы:
1) Почему компилятор учитывает начальную определенную переменную i при выполнении инструкции i<5;i++, а неПереопределенная переменная i? (после первой итерации).

2) Почему компилятор назначил разные адреса памяти одному и тому же идентификатору переменной i?

Ответы [ 2 ]

3 голосов
/ 09 октября 2019

Почему компилятор учитывает начальную определенную переменную i при выполнении инструкции i <5; i ++, а не переопределенную переменную i? (после первой итерации). </p>

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

2) Почему компилятор назначил разные адреса памяти одному и тому же идентификатору переменной i?

Даже если вы не можете получить доступ к внешнему int i внутри цикла, так как второй затеняет его, он все еще существует и поэтому нуждается в собственной памяти. Это не перезаписывается другим int i. Вы можете увидеть это, поместив printf("%d\n", i); после цикла - он напечатает 5, потому что это значение этого i после цикла.


В другой ноте, i++;на конец цикла не влияет, так как влияет на i внутри цикла, который выходит за пределы области сразу после i++;. Это не похоже на i++; в for (i = 0; i < 5; i++), который увеличивает внешний i.

0 голосов
/ 09 октября 2019

У вас есть две разные переменные с именами i, поэтому очевидно, что ситуация будет запутанной! Для каждого i в программе мы должны спросить: это «внешний» i или «внутренний» i?

Снова ваша программа, переменные для ясности переименованы:

#include <stdio.h>
int main()
{
    int i1;
    printf("%p\n",&i1);
    for (i1 = 0; i1 < 5; i1++)
    {
        int i2 = 10;
        printf("%d %p\n", i2,&i2);
        i2++;
    }
    return 0;
}

К вашему конкретному вопросу причина, по которой цикл запускается 5 раз, заключается в том, что элемент управления цикла for (i = 0; i < 5; i++), безусловно, использует external i.

...