3

可能重复:
对 C 宏扩展和整数算术
A 谜语(在 C 中)感到困惑

以下 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]);

      return 0;
  }

这是为什么?

4

7 回答 7

5

sizeof()返回unsigned int等在 <= 比较中,d被转换为unsigned int. -1 转换unsigned int0xffffff. 因为0xffffff > (7-2),for循环体甚至不会被执行一次。

于 2012-06-05T15:44:42.527 回答
4

这失败了,因为sizeof它返回了一个size_t无符号类型的值。这会导致比较将 提升-1为无符号,这通常是一个非常大的值,从而使比较失败。

您应该收到符号不匹配的警告。

于 2012-06-05T15:43:47.620 回答
3

重点是sizeof返回值的类型。

它是 a size_t,它是一个无符号类型,因此转换-1为该类型进行比较会产生该类型的最大值,该最大值远大于 5。

于 2012-06-05T15:42:46.957 回答
1
for(d=-1;d <= ((int)TOTAL_ELEMENTS-2);d++)
于 2012-06-05T15:45:59.567 回答
1

我想这更清楚:

for(d = 0; d < TOTAL_ELEMENTS; d++)
   printf("%d\n",array[d]);

size_t案例应该不再是问题了。

于 2012-06-05T15:49:34.263 回答
0

编写此有效循环的更标准方法是

for(d = 0; d < TOTAL_ELEMENTS; d++)
   ...

正如其他几个人已经正确指出的那样,问题在于比较有符号/无符号值。这种结构可以避免这个问题。

于 2012-06-05T15:40:26.857 回答
0

当我执行以下操作时,您的原始问题有效:

#define TOTAL_ELEMENTS 7
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]);

  return 0;
}

这与将负数 d=-1 与 (TOTAL_ELEMENTS-2) 进行比较有关。我相信它可能是 sizeof,但我会把找出原因作为练习。

保持原来的#define 不变——

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))

- 但使用从零开始的索引也有效。

我不确定为什么您原来的 TOTAL_ELEMENTS 定义导致循环不打印。

于 2012-06-05T15:52:48.057 回答