一位朋友给了我一个谜语:
#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]);
getchar();
return 0;
}
上面的代码应该打印所有的数组元素,代码中的问题是什么(输出什么都没有)?我认为循环不会迭代一次?
我发现以下代码 有效:
#include<stdio.h>
#define TOTAL_ELEMENTS ((sizeof(array) / sizeof(array[0])))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
int x = (TOTAL_ELEMENTS-2);
for(d=-1;d <= x;d++)
printf("%d\n",array[d+1]);
getchar();
return 0;
}
我有一个理论认为它与宏有关,但我无法理解这个问题。
答案 0 :(得分:35)
问题是(TOTAL_ELEMENTS-2)
是无符号值。进行比较d <= (TOTAL_ELEMENTS-2)
时,两个值都将转换为无符号值,结果为false。
在您的第二个示例中,x
已签名,因此没有问题。
答案 1 :(得分:8)
sizeof
运算符会生成类型为size_t
的结果。在第一个版本中,您要将int
(已签名)与size_t
(未签名)进行比较。
在第二个版本中,通过赋值将size_t
表达式转换为int
,因此比较的两个操作数都属于同一类型。
答案 2 :(得分:3)
另一种看待此问题的方法如下
#include<stdio.h>
int main() {
int i = -5;
unsigned int j = 6;
if(i < j)
printf("-5 is less than 6");
else
printf("-5 is greater than 6");
return 0;
}
输出为:
-5 is greater than 6
<强>原因:强> 将无符号整数与有符号整数进行比较将始终返回false。
在提问者案例中, sizeof 会返回无符号数据类型,但会与已签名数据类型进行比较( - 是一个错误)
答案 3 :(得分:0)
我在不使用任何宏的情况下运行以下程序,输出什么都没有
#include<stdio.h>
int main()
{
int d;
for(d=-1;d<=sizeof(int);d++)
{
printf("sizeof operator\n");
}
return 0;
}
因此,这意味着问题不在 MACRO 中,而是返回值sizeof的类型。 sizeof将数据类型的大小返回为 size_t,这是无符号但 -1隐式转换为无符号,即0xffffffff ,并且明显大于sizeof(int)。 另请查看Noncompliant Code Example (Comparison)