Запрос на запись активации в C - PullRequest
0 голосов
/ 23 июня 2010

Ниже приведен код, который я не понимаю.

#include<stdio.h>

int main(int argc, char *argv[])
{
      int num;

      printf("\n Number: " );
      scanf("%d", &num);

      if (num >= 0)
      {
           int abs = num;
      }
      else
      {
            int abs = -num;
      }

      {
          int abs;
          printf("\n Values are %d %d", num ,abs);
       }
      return 0;
}

Когда я ввожу число как 4, вывод будет Values are 4 4
Когда я введу число как -4, вывод будет Values are -4 4

Я нев состоянии понять, как это может печатать абсолютное значение ?.переменная abs, определенная в циклах if и else, должна была быть освобождена после выхода.

Пожалуйста, дайте мне знать.

С уважением, темный

Ответы [ 5 ]

6 голосов
/ 23 июня 2010

Вы абсолютно правы.

Видите ли вы последний блок, где int abs объявлен в последний раз?Обратите внимание, что abs не инициализируется, и использование неинициализированных переменных дает неопределенные результаты.С вашим конкретным компилятором бывает так, что вам не повезло, и блок памяти, в котором находится новый abs, все еще содержит результат из его (просроченной) предыдущей области.

1 голос
/ 23 июня 2010

Это называется "неопределенное поведение".

Вы получаете "мусор в стеке", когда объявляете abs с printf.

Работает так:

if (num >= 0) {
  create 'abs' at memory address N, put 'num' in it.
  destroy 'abs' // but leave the 'garbage' at memory address N
} else {
  create 'abs' at memory address N, put '-num' in it.
  destroy 'abs' // but leave the 'garbage' at memory address N
}

{
  create 'abs' at memory address N, don't put anything in it.
  // your compiler has decided it will reuse N.  That's a valid choice.
  // your compiler has decided it will not zero the memory at address N.  That's valid.
  read whatever was at 'abs'.  // it's whatever was assigned in the conditional.
}

Всегда компилировать с -Wall:)

1 голос
/ 23 июня 2010

Эти переменные размещены в стеке, но вы не изменили его, я имею в виду, что вы не вышли из функции, поэтому программно вы получите «новый» abs в последнем кодеблок, но на самом деле этот «новый» «abs» int находится в том месте, где был старый «abs» (на СТЕКЕ!), поэтому его значение по умолчанию такое же.

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

Веселый код.

Он основан на том факте, что все три определения abs будут размещены в одном месте в стеке из-за оптимизации компилятора.Будучи случайным garbag, мусор оказывается результатом предыдущей переменной с тем же именем (имя не имеет значения).

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

Вы используете неинициализированное значение abs в printf. Стандарт языка C не требует, чтобы он был чем-то конкретным, потому что он неинициализирован. Это может быть 0, или 1, или -32765

В этом конкретном случае вы, вероятно, получаете тот же номер, потому что скомпилированный код повторно использует регистр для временных значений abs, и этот же регистр снова для вашей переменной abs в блоке printf.

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

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