打印数组中的元素

3
以下是C程序的输出,目的是打印数组中的元素。但实际运行时并未这样做。此问题可能与C宏展开和整数算术有关。请参考以下链接:Confused about C macro expansion and integer arithmeticA riddle (in 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;
  }

为什么呢?

1
这是作业吗?(如果是的话,你应该相应地标记它。) - eq-
2
非常可怕的宏,它包含数组的名称,而不是将其作为参数传递。非常令人困惑。 - unwind
请看Hari Mahadevan的回答。您能告诉我们为什么将变量d设置为-1而不是零? - Miguel Rentes
cannot-enter-in-while-statement - unsigned-and-signed-comparison - unsigned-int-and-signed-char-comparison 无法进入 while 语句 - 无符号和有符号比较 - 无符号整数和有符号字符比较 - gliderkite
1
我很好奇:这段代码是你写的,但你自己不明白,还是教授提供的一个“这段晦涩代码做什么”的测验? - Robᵩ
7个回答

5

sizeof()返回unsigned int,所以在<=比较中,d被转换为unsigned int。当-1转换为unsigned int时,结果是0xffffff。由于0xffffff > (7-2),所以for循环体不会执行。


1
当转换为无符号整数时,*-1的值为0xffffff,或者是0xffff,或者是0xffffffffffffffff,总是一个很大的数字。 - Robᵩ

4
这个错误的发生是因为sizeof返回了一个size_t类型的值,它是无符号的。这会导致比较操作将-1转换为无符号数,通常是一个非常大的值,从而导致比较失败。
你应该会收到有关符号不匹配的警告。

3

关键点在于sizeof返回的值的类型。

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


当我打印出TOTAL_ELEMENTS的值时,我得到了7。 - Levon
@Levon 但是有一个 (TOTAL_ELEMENTS-2) - Daniel Fischer

1
for(d=-1;d <= ((int)TOTAL_ELEMENTS-2);d++)

我认为你的答案更好 ;) 这段代码可能来自一道有意“有缺陷”的考试/测试题。你和我都提供了正确的建议,但这个代码似乎在说“你抓不到我”。 - ManieQ

1

我想这样更清楚:

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

现在,size_t的情况不应该再是问题了。


0

更标准的编写此循环的方式是:

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

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

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定义导致循环未打印。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接