Два сравнения равенства с NULL в C - PullRequest
1 голос
/ 10 февраля 2012

Это касается небольшой путаницы в отношении указателей в C ++ при сравнении их с NULL.Вот код:

struct node
{
  int data;
  struct node *left;
  struct node *right;
}
int main()
{
  struct node *p;
  if(p!= NULL)
     printf("line1\n");
   else
     printf("line2\n");
   struct node *temp;
   if(temp == NULL)
     printf("line3\n");
} 

Выход:

line2
line3

Для следующего фрагмента кода:

struct node
{
  int data;
  struct node *left;
  struct node *right;
}
int main()
{
  struct node *p;
  if(p!= NULL)
     printf("line1\n");
   else
     printf("line2\n");
   struct node *temp;
} 

Это вывод:

line1

Кто-нибудь может объяснить, пожалуйста, причину такого происшествия?

Ответы [ 4 ]

2 голосов
/ 10 февраля 2012

auto переменные (т. Е. Локальные переменные, не объявленные static), такие как p и temp, остаются неинициализированными, поэтому их значение является неопределенным (по существу, любая битовая строка, оставленная в этой конкретной ячейке памяти из предыдущая операция, которая может быть или не быть допустимым значением для данного типа). Никогда не пытайтесь разыменовать неинициализированный указатель.

Переменные, объявленные в области видимости файла (вне функционального блока) или с ключевым словом static, инициализируются следующим образом:

  • указатели инициализируются в NULL;
  • арифметические типы (целые числа или числа с плавающей запятой) инициализируются в 0
  • структуры инициализируются рекурсивно в соответствии с двумя предыдущими правилами
  • Профсоюзам инициализируется первый именованный член в соответствии с первыми двумя правилами

Если вы измените объявление p на

static struct node *p;

тогда p будет инициализировано в NULL. Если вы не хотите объявить p как static, вам придется инициализировать его как часть объявления:

struct node *p = NULL;
2 голосов
/ 10 февраля 2012

Вы читаете неинициализированную переменную. Это неопределенное поведение . В принципе, все может случиться. Если бы вы включили предупреждения вашего компилятора, компилятор сказал бы вам именно это.

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

2 голосов
/ 10 февраля 2012

Вы объявляете указатель, но не инициализируете его. Может принимать любое значение, т. Е. Оно не гарантируется равным NULL. Конечно, это может быть NULL (0), но опять же, на это нельзя рассчитывать.

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

0 голосов
/ 10 февраля 2012

Вам нужно дать значения p amd temp - поскольку у вас их нет, они могут содержать что угодно.

...