C 这两种说法都是正确的
在第一个代码块中,两个条件都成立。在第二种情况下,第一种是正确的,另一种是错误的C 这两种说法都是正确的,c,C,在第一个代码块中,两个条件都成立。在第二种情况下,第一种是正确的,另一种是错误的 int8_t i8 = -2; uint16_t ui16 = i8; if(ui16 == -2) //this is TRUE if(ui16 == 65534) //this is TRUE as well 这是第二种情况: int8_t i8 = -2; int16_t i16 = i8; if(i16 == -2) //this is TRUE if(i16 == 6553
int8_t i8 = -2;
uint16_t ui16 = i8;
if(ui16 == -2) //this is TRUE
if(ui16 == 65534) //this is TRUE as well
这是第二种情况:
int8_t i8 = -2;
int16_t i16 = i8;
if(i16 == -2) //this is TRUE
if(i16 == 65534) //this is NOT TRUE !!!
在C语言中,无符号整数总是按照模块(时钟面)算法进行运算,但有符号整数只是有时不可靠地这样做
一般来说,期望一个数字等于另一个数字是毫无意义的。你不应该那样写程序。如果希望像
-2
这样的数字表现为正的无符号值,则应显式编写像(uint16\u t)-2
这样的强制转换。否则,可能会出现很多问题。因为-2
适合int16\u t
,而-2
在uint16\u t
中转换为无符号
这是定义明确的行为
来自ISO/IEC 9899(C99标准工作草案):
6.3.1.3有符号和无符号整数
…2否则,如果新类型是无符号的,则通过重复添加或 比新类型中可以表示的最大值多减去一个 直到值在新类型的范围内。49)
…
49)规则描述的是基于数学值的算术运算,而不是给定类型表达式的值 因此,如果我这样做:
uint16_t i = -2;
编译器应执行以下操作:
或
直到我们得到一个可存储在16位内的值,没有符号位
不依赖于-2
的等级,而是数学值
在您的情况下,应该是:65534
[C++对有符号转换遵循相同的规则]
在代码的第二部分中,只需将较低的秩值赋给较高的秩变量
e、 g.使用更多的精度位来存储相同的数字
当您对照i16==65534
进行检查时,您正在从同一节调用标准的这一部分:
3否则,新类型已签名,且无法在其中表示值;要么
结果是定义了实现或发出了定义了实现的信号
因为65534
不能存储在15位和符号位(215-1)中
因此,调用实现定义的行为
除非您是一名编译器开发人员,否则依赖此函数的返回值与依赖未定义的行为一样糟糕。您有问题吗?
65534
属于int
类型-如果int
大于int16\t
,则i16
将被提升为int
,并带有符号扩展名问题“为什么会发生这种情况?”?这里有很多事情需要注意。看起来您使用的是16位编译器。无论如何,你使用的是超出其范围的值,因此(1)你的生活很危险,(2)仔细阅读C标准,特别是晋升规则,可以解释一切。
i = -2 + (USHRT_MAX + 1);
i = -2 - (USHRT_MAX + 1);