Загадка (в C)

Друг дал мне загадку:

#include<stdio.h>

#define TOTAL_ELEMENTS ((sizeof(array) / sizeof(array[0])))
  int array[] = {23,34,12,17,204,99,16};

  int main()
  {
      int d;
      for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
          printf("%d\n",array[d+1]);
      getchar();
      return 0;
  }

Вышеприведенный код должен печатать все элементы массива, в чем проблема в коде (вывод ничего)? Я думаю, что цикл не повторяется еще раз?

Я узнал, что работает следующий код :

#include<stdio.h>



#define TOTAL_ELEMENTS ((sizeof(array) / sizeof(array[0])))
  int array[] = {23,34,12,17,204,99,16};

  int main()
  {
      int d;
      int x = (TOTAL_ELEMENTS-2);
      for(d=-1;d <= x;d++)
          printf("%d\n",array[d+1]);
      getchar();
      return 0;
  }

У меня есть теория, что это как-то связано с макросом, но я не могу сказать о проблеме.

Ответы

Ответ 1

Проблема заключается в том, что (TOTAL_ELEMENTS-2) - это значение без знака. Когда вы делаете сравнение d <= (TOTAL_ELEMENTS-2), оба значения преобразуются в значения без знака, а результат - false.

В вашем втором примере x подписан, поэтому нет проблем.

Ответ 2

Оператор sizeof дает результат типа size_t. В первой версии вы сравниваете int (подписанный) с size_t (без знака).

Во второй версии вы преобразуете выражение size_t в int, назначив его, и, следовательно, оба операнда сравнения имеют один и тот же тип.

Ответ 3

Еще один способ увидеть эту проблему следующим образом

#include<stdio.h>

int main() {

int i = -5;
unsigned int j = 6;

if(i < j)
  printf("-5 is less than 6");
else
  printf("-5 is greater than 6");

return 0;
}

Выход:

-5 is greater than 6

Причина:  Сравнение беззнакового целого с целым числом со знаком всегда будет возвращать false.

В вопросительном случае sizeof возвращает неподписанный тип данных, но он сравнивается с типом подписан (- это ошибка)

Ответ 4

Я запускаю следующую программу без использования макроса, и вывод ничего не был

#include<stdio.h>
int main()
{
  int d;
for(d=-1;d<=sizeof(int);d++)
{  
 printf("sizeof operator\n");
}
return 0;
}

Итак, это означает, что проблема не в MACRO, а в типе значения sizeof возвращается. sizeof возвращает размер типа данных как size_t без знака, но -1 неявно преобразуется в unsigned, который равен 0xffffffff и, очевидно, больше sizeof (int). Также посмотрите Пример несоответствующего кода (сравнение)