C 基本整数赋值
以下是让我沮丧的原因: 我们有两个整数:一个是C 基本整数赋值,c,C,以下是让我沮丧的原因: 我们有两个整数:一个是int16\u t类型,另一个是int8\u t。我已按如下方式初始化了这两个变量: int8_t short_int = 250 //This equals -6, and its binary representation is 0b1111 1010 到目前为止还不错 int16_t my_int = short_int //as we already know short_int is 0b1111 1010 对我来说,我的int
int16\u t
类型,另一个是int8\u t
。我已按如下方式初始化了这两个变量:
int8_t short_int = 250 //This equals -6, and its binary representation is 0b1111 1010
到目前为止还不错
int16_t my_int = short_int //as we already know short_int is 0b1111 1010
对我来说,我的int应该等于0b1111 1010,对吗?将值设置为16位整数
0b1111 1010的十进制表示形式为250。好的,但它没有
打印my_int I get-6的值,二进制表示为0b1111 1111 1111 1010与作为二进制的
short_int
完全不同 C基于值而不是位模式工作
如果将int8\u t
分配给int16\u t
,则两者之后的值相同
对于负值,这意味着它们具有不同的位模式(假设负值的公共表示)
请注意,您的int8\t
实际上是负数。使用:
int16_t my_int = (uint8_t) short_int;
而不是:
int16_t my_int = short_int;
short\u int
是一个负有符号整数,因此它在转换为int16\u t
int8\u t short\u int=250时会进行符号扩展,从而导致实现定义的行为。int8\u t
的范围是-128
到127
显然,您的实现在这里为short\u int
生成值-6
。好的,到目前为止
但是现在你必须记住C有保值转换。如果将-6
转换为任何其他有符号整数类型,则无论其位表示是什么,该类型仍将是-6
有些人会谈论“符号扩展”和其他类似的东西,但是要理解C是如何工作的,你只需要记住值是保留的,除非它超出了类型的范围;在这种情况下,它要么被截断(对于无符号类型),要么被实现定义的行为(对于有符号类型;通常是2的补码截断)。标准说
C11:7.20.1.1
typedef
nameintN\u t
指定一个有符号整数类型,其宽度N
、无填充位和两个补码表示形式。因此,int8\u t
表示宽度正好为8
位的有符号整数
类型
将short\u int
赋值给my\u int
时,其二进制表示的位数增加,同时保留short\u int
符号和值(称为“符号扩展”)
short\u int
是负数,因此my\u int
将有相同的符号,具有相同的值,但有一些填充位。ungur\u gongor的答案是正确的。如果您确实希望访问位模式,就像它是int8\u t
或int16\u t
,则可以使用union
:
union {
int8_t short_int;
int16_t my_int;
} converter;
converter.my_int = 0;
converter.short_int = 250;
printf("%d\n", converter.my_int);
但是要注意对齐(其中是int8\u t
的填充?)和int16\u t
的结尾
这将保留位模式(而不是值),尽管可能只在包含short\u int
的字节上(这就是为什么我首先将my\u int
设置为0)。搜索并阅读符号扩展。@JoachimPileborg:或者更好,不要这样做。我不认为“符号扩展”是C标准中的一个东西。@KerrekSB我可以引用C标准中关于整数转换的段落,但我更喜欢写符号扩展。这是你的特权,但是,用如此低级的细节解释高级概念鼓励了这种位模式思维,而这种思维最初是OP所遭遇的…@KerrekSB“符号扩展”,“符号扩展”术语在C编程语言中大量使用,其次是K&R,其目的是向用户解释C,这不是C标准的目标。不,这不是“整数溢出”。这仅仅是一个实现定义的、改变值的转换。1+首先说明要点。其余的只是细节,细节永远无法提供真正解释所提供的洞察力。@KerrekSB更新。因此,intN\u t
类型有这个要求,而其他有符号整数类型没有这个要求。@KerrekSB为什么从技术上讲它不溢出gcc
将我与警告混淆:隐式常量转换溢出
没错。类型也是可选的,即ti不必存在。@vsoftco它不是溢出(由C标准定义),它是超出范围的转换。gcc有点马虎。“溢出”是当算术运算产生超出范围的结果时。@ VSOFTCO:GCC并不总是有最有用的诊断(尝试编译C++)。溢出是在像a+b
这样的表达式中发生的情况。目前的情况只是转变。