首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么'for‘循环条件失败?

为什么'for‘循环条件失败?
EN

Stack Overflow用户
提问于 2016-08-19 22:34:28
回答 4查看 1.8K关注 0票数 12

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

我想知道,因为当我单独打印TOTAL_ELEMENTS时,它给出了5,所以这自然是5-2=3 => -1<=3,所以它应该打印一些东西。

代码语言:javascript
复制
#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;
}

有人能解释一下这段代码吗?

EN

回答 4

Stack Overflow用户

发布于 2016-08-19 22:41:21

这是“通常的算术转换”的结果。

摘自C standard的6.3.1.8节

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

否则,如果两个操作数都具有带符号整数类型或都具有无符号整数类型,则具有较小整数转换秩的类型的操作数将转换为具有较大秩的操作数的类型。

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

否则,如果带符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值,则具有无符号整数类型的操作数被转换为具有有符号整数类型的操作数类型。否则,这两个操作数都将转换为与带符号整数类型的操作数的类型相对应的无符号整数类型。

sizeof操作符返回一个size_t,它是一个无符号值。所以(sizeof(array) / sizeof(array[0])) - 2也是未签名的。

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

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

代码语言:javascript
复制
for(d=-1;d <= (int)(TOTAL_ELEMENTS-2);d++)

输出:

代码语言:javascript
复制
23
34
12
17
204
99
16

或者,您可以通过规范化索引数组的方式来避免这个问题:

代码语言:javascript
复制
for (d = 0; d < TOTAL_ELEMENTS; d++) {
    printf("%d\n", array[d]);
}
票数 33
EN

Stack Overflow用户

发布于 2016-08-19 22:45:11

当我尝试像这样打印TOTAL_ELEMENTS - 2时:

代码语言:javascript
复制
printf("total %d\n", TOTAL_ELEMENTS - 2);

我得到了一个警告(使用gcc 4.8)说:

代码语言:javascript
复制
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);
  ^

该警告意味着TOTAL_ELEMENTS - 2long unsigned。现在,当您将signed intunsigned int进行比较时,有符号的整数将被视为无符号的。因此在d <= (TOTAL_ELEMENTS-2)中,d变成了一个非常高的正数(假设使用的是2的补数系统)。

您可以将结果强制转换为int以解决此问题。

d <= (int)(TOTAL_ELEMENTS-2)

或者,如果您在许多地方使用宏,则可以像这样进行更改:

代码语言:javascript
复制
#define TOTAL_ELEMENTS (int)(sizeof(array) / sizeof(array[0]))
票数 9
EN

Stack Overflow用户

发布于 2016-08-19 22:55:42

代码语言:javascript
复制
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))

它的计算结果为unsigned类型。然而,在您的循环中,d是一个signed值。在有符号值和无符号值的表达式中,有符号值被转换为无符号值。但是d是-1,它不适合无符号的值,所以它“环绕”到机器上的最高无符号值(在2的补码上)。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39041684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档