以下程序编译成功但是当我运行它时,它在我用-1初始化for循环时没有打印,但是当我用0初始化循环时它成功遍历所有数组。我想问我们可以不要&# 39;当我们用负值??
初始化for循环时,t遍历数组#include <stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23, 34, 12, 17, 204, 99, 16};
int main(void) {
int d;
//printf("%d",TOTAL_ELEMENTS);
for (d = -1; d <= (TOTAL_ELEMENTS - 2); d++)
{
printf("%d ",d);
printf("%d\n", array[d+1]);
}
return 0;
}
答案 0 :(得分:2)
sizeof
运算符的结果是size_t
类型,这是一种无符号类型。
因此,TOTAL_ELEMENTS
的类型也是无符号的。将-1
与之进行比较时,会将其转换为无符号数。这就是为什么d <= (TOTAL_ELEMENTS - 2)
是错误的。
答案 1 :(得分:1)
这不符合你的想法:
d <= (TOTAL_ELEMENTS - 2)
相反,这样做:
d <= int(TOTAL_ELEMENTS - 2)
否则你的签名与未签名比较,你的-1成为最大的size_t
。
答案 2 :(得分:1)
此处d <= (TOTAL_ELEMENTS - 2)
个操作数是通常的算术转换(6.3.1.8)的主题。实际上,整数促销规则适用于您的情况:
如果两个操作数具有相同的类型,则不再进一步转换 需要的。
否则,如果两个操作数都有有符号整数类型或两者都有 有无符号整数类型,操作数类型较小 整数转换等级转换为操作数的类型 更高的等级。
否则,如果操作数具有无符号整数类型 等级大于或等于另一个等级的等级 操作数,然后将带有符号整数类型的操作数转换为 具有无符号整数类型的操作数的类型。
否则,如果是类型 带有符号整数类型的操作数可以代表所有的 具有无符号整数类型的操作数类型的值,然后是 具有无符号整数类型的操作数转换为的类型 带有符号整数类型的操作数。
- 醇>
否则,两个操作数都是 转换为对应于类型的无符号整数类型 带有符号整数类型的操作数。
根据您所获得的代码,您的代码属于第3条,然后您的签名-1
将通过规则(6.3.1.3)进行转换:
否则,如果新类型是无符号的,则转换为 重复加或减一个以上的最大值 可以用新类型表示,直到值在范围内 新类型。
结果它变成一个非常大的无符号值,肯定大于TOTAL_ELEMENTS - 2
并且你永远不会进入循环。
答案 3 :(得分:0)
sizeof
生成size_t
的结果,该结果是无符号的。比较有符号和无符号类型,你只能期望事情爆发。
详细说明,当您尝试在算术运算中同时使用有符号和无符号类型时,签名类型将被提升为无符号类型,从而生成巨大数字。因此,提升为无符号类型的d
的值将无法满足条件d <= (TOTAL_ELEMENTS - 2);
,因此循环体将不会执行。
对于期望算术类型的操作数导致转换的运算符。这种模式称为通常的算术转换。对于这个特殊情况,引用标准,章节§6.3.1.8
否则,将对两个操作数执行整数提升。那么 以下规则适用于提升的操作数:
[...]
- 否则,如果具有无符号整数类型的操作数的等级更大或 等于另一个操作数的类型的等级,然后是操作数 有符号整数类型转换为带有unsigned的操作数的类型 整数类型。
,关于排名,
- 任何无符号整数类型的等级应等于相应的等级 有符号整数类型,如果有的话。
另外,作为参考,引用C11
,第7.19章,(强调我的)
size_t
是sizeof运算符的结果的无符号整数类型;
提示:启用编译器警告,它将指向您的错误。