Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么';对于';循环条件失败?_C_Type Conversion_C Preprocessor_Implicit Conversion - Fatal编程技术网

C 为什么';对于';循环条件失败?

C 为什么';对于';循环条件失败?,c,type-conversion,c-preprocessor,implicit-conversion,C,Type Conversion,C Preprocessor,Implicit Conversion,在下面显示的代码中,没有打印任何内容,这意味着for循环中的条件失败。原因可能是什么 我很好奇,因为当我单独打印TOTAL_ELEMENTS时,它会给出5,所以自然这一定是5-2=3=>-1这是“常用算术转换”的结果 根据本规范第6.3.1.8节: 如果两个操作数的类型相同,则不需要进一步转换 需要 否则,如果两个操作数都具有有符号整数类型或都具有 无符号整数类型,类型为较小的操作数 整数转换秩转换为操作数的类型 具有更高的等级 否则,如果具有无符号整数类型的操作数 等级大于或等于其他类型的等级

在下面显示的代码中,没有打印任何内容,这意味着
for
循环中的条件失败。原因可能是什么

我很好奇,因为当我单独打印
TOTAL_ELEMENTS
时,它会给出
5
,所以自然这一定是
5-2=3=>-1这是“常用算术转换”的结果

根据本规范第6.3.1.8节:

如果两个操作数的类型相同,则不需要进一步转换 需要

否则,如果两个操作数都具有有符号整数类型或都具有 无符号整数类型,类型为较小的操作数 整数转换秩转换为操作数的类型 具有更高的等级

否则,如果具有无符号整数类型的操作数 等级大于或等于其他类型的等级 操作数,则有符号整数类型的操作数为 已转换为具有无符号整数的操作数类型 类型。

否则,如果带符号整数类型的操作数的类型 用无符号表示操作数类型的所有值 整数类型,则具有无符号整数类型的操作数为 已转换为带符号整数类型的操作数类型

否则,两个操作数都将转换为无符号 与带符号的操作数类型相对应的整数类型 整数类型

sizeof
运算符返回一个
size\u t
,它是一个无符号值。因此
(sizeof(array)/sizeof(array[0])-2
也是无符号的

因为要比较有符号值和无符号值,所以有符号值将转换为无符号值。将-1转换为无符号将产生最大的无符号值,这将导致比较结果为false

如果将右侧强制转换为
int
,它将按预期工作

for(d=-1;d <= (int)(TOTAL_ELEMENTS-2);d++)
或者,可以通过规范化对数组的索引方式来避免此问题:

for (d = 0; d < TOTAL_ELEMENTS; d++) {
    printf("%d\n", array[d]);
}
for(d=0;d
当我尝试打印
总计元素-2
时,如下所示:

printf("total %d\n", TOTAL_ELEMENTS - 2);
#define TOTAL_ELEMENTS (int)(sizeof(array) / sizeof(array[0]))
我收到一条警告(使用gcc 4.8)说:

警告意味着
TOTAL_ELEMENTS-2
长无符号的
。现在,当您将
有符号整数
无符号整数
进行比较时,该有符号整数将被视为无符号整数。所以在
d中
这将计算为无符号类型。但是,在循环中,
d
是一个有符号的值。在有符号和无符号值参与的表达式中,有符号值将转换为无符号值。但是
d
是-1,它不能放入无符号中,因此它“环绕”到机器上的最高无符号值(在2的补码上)

您知道35; define TOTAL_ELEMENTS(sizeof(array)/sizeof(array[0])返回一个无符号数,-1可能会成为最大的数字,因为它会转换为无符号数

您可以测试表达式“printf(“%d\n”,-1
for (int d = 0; d < TOTAL_ELEMENTS; d++) {
    printf("%d\n", array[d]); }
for(int d=0;d

我不认为让
d
变量相关是一个好方法,因为
d
for
循环中的一个变量。

正如其他答案所解释的,原因是通常的算术转换,使用
sizeof
获得的类型大小导致int转换为与类型大小对应的无符号类型

我想补充一点,行为是由实现定义的1。这个循环可以进行,也可以不进行。这取决于类型大小的定义


C标准允许类型size\u t的秩低于类型int。在这种情况下,整数提升将类型size\u t提升为类型int。此时,双方都具有相同的类型int,因此转换停止。比较
d见:“因为当我单独打印TOTAL_元素时,结果是5”-不,不是。有什么原因让它这么复杂吗?我不知道您使用的是哪种编译器,但GCC给了您一个正确的提示:“警告:有符号整数和无符号整数之间的比较”。当然,如果您已打开所有警告。谁给了这8张(大写:8!)的赞成票?@deamentiaemundi,这个警告只会出现
-Wextra
。不是每个人都使用它,但每个人都应该使用它。为什么要在-1处启动for循环,然后将1添加到数组索引中?
test.c:8:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
  printf("total %d\n", TOTAL_ELEMENTS - 2);
  ^
#define TOTAL_ELEMENTS (int)(sizeof(array) / sizeof(array[0]))
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
for (int d = 0; d < TOTAL_ELEMENTS; d++) {
    printf("%d\n", array[d]); }