2009-02-01 71 views
2

可能重复:
A riddle (in C)为什么这两个程序在ANSI C中表现不同?

1.

main() 
{ 

if(-1<(unsigned char)1) 
    printf("-1 is less than (unsigned char)1:ANSI semantics"); 
else 
    printf("-1 NOT less than (unsigned char)1:K&R semantics"); 
} 

2.

int array[] = {23,41,12,24,52,11}; 
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0])) 
main() 
{ 
    int d = -1,x; 
    if(d<=TOTAL_ELEMENTS -2) 
     x = array[d+1]; 
} 

第一转换无符号字符1到的标志ed变量,而第二个程序将d转换为一个无符号整型,这使得在ANSI C中 条件表达式返回false。 为什么它们的行为有所不同?

+0

在你的第二个代码示例中,你的意思是“数组”而不是“arrary”吗? – mweiss 2009-02-01 09:56:53

回答

4

对于第一个右边是一个无符号字符,并且所有无符号字符值都适合一个带符号整数,所以它被转换为带符号整数。

对于第二个,右侧是一个无符号整型,所以左侧从signed int转换为unsigned int。请参阅this CERT document on integer conversions

1

starblue解释了你的问题的第一部分。我会参加第二部分。因为TOTAL_ELEMENTSsize_t,它是无符号的,所以int被转换为无符号类型。你的size_t是这样int不能代表它的所有值,所以发生intsize_t的转换,而不是size_tint

完美定义负数转换为无符号:值包装。如果您将-1转换为unsigned int,则结果为UINT_MAX。无论您是否使用二进制补码来表示负数,情况都是如此。

rationale for C文件有更多关于保值转换的信息。

0

这是我记得的方式转换是如何自动应用:

  • 如果操作数的大小不同,则转换适用于较小的操作,使其成为同类型较大的操作数(带符号延伸如果较小操作数被签名)

  • 如果操作数的大小相同,但一个是带符号和无符号等,则符号操作数转换为无

虽然上述可能不适用于所有实现,但我相信对于所有二进制补充实现都是正确的。

相关问题