Почему этот код печатает мусорное значение? - PullRequest
0 голосов
/ 23 июня 2018

Этот фрагмент кода был взят из онлайн-викторины по программированию на C.

https://www.youtube.com/watch?v=5sOZ7l2it2I

Пожалуйста, помогите мне понять этот код. По-видимому, это печатает мусорное значение. Здесь у нас есть локальная переменная var, которая скрывает область видимости глобальной переменной var. Я предположил, что локальная переменная var инициализируется значением глобальной переменной var, а значение глобальной переменной копируется в локальную переменную. Я понимаю, что с этого момента имя var в коде теперь относится к локальному var. Таким образом, печать локальной переменной также должна печатать 5. Но это не так. Программа печатает мусорное значение. Это означает, что локальная переменная не была инициализирована или произошла какая-то ошибка во время инициализации локальной переменной. Что здесь происходит? Это проблема неопределенного поведения?

#include <stdio.h>
int var = 5;
int main() {
  int var = var;
  printf("%d", var);
}

1 Ответ

0 голосов
/ 23 июня 2018

Грубо говоря, ваша int var = var; внутри main равна эквивалентной до:

int var; // this var is now in the current scope but is uninitialized
var = var; // assign the garbage value from var to var.

Таким образом, глобальный var игнорируется, а локальный var сохраняет свое значение мусора (поскольку он назначен самому себе).

Читайте о лексическая область видимости . Проверьте стандарт C11 n1570 (особенно его §6.2.1).

Кстати, достаточно хороший компилятор может предупредить вас, если вы запросите все предупреждения и отладочную информацию (например, gcc -Wall -Wextra -g с GCC ; на самом деле это не относится к gcc 8 в Debian / Linux ... ).

Как правило, лучше давать более длинные и описательные имена глобальным переменным и всегда избегать именования локальных (блок-область) автоматических переменных , таких как глобальные или статические (файл-область).

Относительно неопределенного поведения , прочитайте блог Латтнера и будьте напуганы UB.

...