Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 基本整数赋值_C - Fatal编程技术网

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
name
intN\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
这样的表达式中发生的情况。目前的情况只是转变。