以下C代码有什么问题?

Par*_*rag 0 c arrays c-preprocessor

可能重复:
对C宏扩展和整数运算感到困惑
一个谜语(在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;
  }
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 6

因为sizeof给你一个无符号的价值,你可能有你打开了警戒线,如使用会注意到-Wall -Wextragcc (一):

xyzzy.c: In function 'main':
xyzzy.c:8: warning: comparison between signed and unsigned
Run Code Online (Sandbox Code Playgroud)

如果强制它签名,它可以正常工作:

#define TOTAL_ELEMENTS (int)((sizeof(array) / sizeof(array[0])))
Run Code Online (Sandbox Code Playgroud)

可以从ISO标准中收集详细信息.在不同类型之间的比较中,执行促销以使类型兼容.选择的兼容类型取决于几个因素,例如符号兼容性,精度和等级,但在这种情况下,认为无符号类型size_t是兼容类型,因此d升级到该类型.

不幸的是,转换-1为无符号类型(至少是两个补码,几乎可以肯定你正在使用的那个)会导致相当大的正数.

5你得到的肯定更大(TOTAL_ELEMENTS-2).换句话说,您的for语句实际上变为:

for (d = some big honking number way greater than five;
     d <= 5;
     d++
) {
    // fat chance of getting in here !!
}
Run Code Online (Sandbox Code Playgroud)

(a)这项使用要求extra仍然是gcc开发商与我之间争论的焦点.他们显然正在使用我之前未发现的"全部"这个词的一些定义(道格拉斯亚当斯道歉).

  • 很高兴你找到了答案.我有一个小问题.既然你可以很容易地把你的循环开始在0,为什么所有这些都是逻辑的,你是不是这样? (2认同)