从-1开始的循环不会打印任何内容

roh*_*mar 55 c integer loops sizeof negative-number

该程序应该打印出来的元素array,但是当它运行时,没有显示输出.

#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)

为什么这个程序没有显示任何输出?

cs9*_*s95 155

sizeof返回无符号整数,因此TOTAL_ELEMENTS也是无符号整数.

d签了.最初d-1.但是,在进行比较时,d隐式地对无符号进行类型转换,因此不再-1进行比较时TOTAL_ELEMENTS,它实际上是UINT_MAX(它4294967295在我的机器上,但可能与其他机器不同).

也,

如果你想解决这个问题,TOTAL_ELEMENTS可以使用int:

for(d = -1; d <= (int)(TOTAL_ELEMENTS - 2); d++) 
Run Code Online (Sandbox Code Playgroud)

这将打印:

23
34
12
17
204
99
16
Run Code Online (Sandbox Code Playgroud)

正如你所料.您可能还希望查看无符号和有符号整数的比较操作,以获取有关无符号比较主题的更多信息.

值得注意的是,启用编译器警告可以帮助您弄清楚发生了什么(正如hyde在他的评论中所观察到的):

$ gcc -Wall -Wextra test.c
test.c:7:17: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
      for(d = 0; d < TOTAL_ELEMENTS; d++) 
              ~ ^ ~~~~~~~~~~~~~~
1 warning generated.
Run Code Online (Sandbox Code Playgroud)

或者,为什么不开始d0和运行TOTAL_ELEMENTS - 1呢?你甚至可以放弃类型转换,这只是角落的必要条件d = -1.

for(d = 0; d < TOTAL_ELEMENTS; d++) 
    printf("%d\n", array[d]);
Run Code Online (Sandbox Code Playgroud)

作为脚注,以下是相关的C99标准摘录:

  1. 6.3.1.8p2定义了从有符号到无符号类型的转换.

    如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的等级,则具有有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型.

  2. 6.3.1.3p2定义了转换的完成方式:通过添加UINT_MAX + 1到已签名的表示.

    如果新类型是无符号的,则通过重复地添加或减去一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内.

    对于这种情况,所以-1=> -1 + (UINT_MAX + 1)= UINT_MAX.


CIs*_*ies 39

我的gcc输出此警告:

warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
      for(d = 0; d < TOTAL_ELEMENTS; d++) 
Run Code Online (Sandbox Code Playgroud)

这意味着,(TOTAL_ELEMENTS-2)unsigned int同时dsigned int.这使表达式始终false为初始值d,因为(unsigned int)(-1) > (TOTAL_ELEMENTS-2).

  • 是的.课程:始终启用所有警告并阅读它们 (20认同)

Pat*_*att 5

不同整数类型之间的二进制运算是在所谓的“普通”算术转换定义的“公共”类型内执行的。因此,int d是使用值-1初始化的单一类型。转换为unsigned int时,它将返回unsigned int的最大值,该最大值远大于TOTAL_ELEMENTS返回的值。