基本整数赋值

时间:2015-04-24 12:09:54

标签: c

这是让我感到沮丧的原因:

我们有两个整数:一个是int16_t类型,另一个是int8_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

对我来说,my_int应该等于0b1111 1010对吧?作为16bit整数的值 0b1111 1010的十进制表示为250.好的,但它没有。

打印my_int的值我得到-6,二进制表示为0b1111 1111 1111 1010 short_int完全不同作为二进制。

5 个答案:

答案 0 :(得分:15)

int8_t short_int = 250会导致实现定义的行为。 int8_t的范围是-128127

显然,您的实现会在此为-6生成值short_int。好到目前为止。

但是现在您必须记住C具有保值转换。如果您将-6转换为任何其他有符号整数类型,则无论其位代表是什么,它仍将是-6

有些人会谈论“符号扩展”和其他类似的东西,但是为了理解C的工作方式,你只需要记住,除非超出类型的范围,否则值将被保留;在这种情况下,它被截断(对于无符号类型)或实现定义的行为(对于有符号的类型;通常是2的补码截断)。

答案 1 :(得分:13)

C基于值而不是位模式。

如果您将int8_t分配给int16_t,则两者之后都具有相同的值。

对于负值,这意味着它们具有不同的位模式(假设负值的公共表示)。

请注意,您的int8_t实际上是否定的。

答案 2 :(得分:2)

使用:

int16_t my_int = (uint8_t) short_int;

而不是:

 int16_t my_int = short_int;

short_int是一个负的有符号整数,因此在转换为int16_t时会经历符号扩展。

答案 3 :(得分:0)

标准说

C11:7.20.1.1

  

typedef名称intN_t指定宽度为N有符号整数类型,无填充位和二进制补码表示。因此,int8_t表示宽度精确为signed integer位的8类型。

short_int分配给my_int时,其二进制表示的位数会增加,同时保留short_int符号和值(称为"符号扩展")。

short_int为负数,因此my_int将具有相同的值,但具有相同的值,但带有一些填充位。

答案 4 :(得分:0)

ungur_gongor的回答是正确的。如果您确实想要访问位模式,就好像它是int8_tint16_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_t的填充位置?)和int16_t的字节顺序。

这会保留位模式(而不是值),尽管可能仅在覆盖short_int的字节上(这就是为什么我先将my_int设置为0)。