将32位整数值转换为无符号16位整数

时间:2019-01-03 20:05:24

标签: c types type-conversion integer unsigned-integer

C标准怎么说?

uint32_t a = 0x11223344;
uint16_t b = a;

打印时,我得到0x3344,这很有意义;所以这必须是合法且正确的行为吗?

1 个答案:

答案 0 :(得分:4)

C标准所说的内容归结为以下事实:通过计算模2 16 的值0x11223344uint16_t转换为0x3344

但是,到达目标的过程分几个步骤:

uint16_t b = a;是带有初始化的声明,C 2018 6.7.9 11中对此进行了讨论:

  

标量的初始值设定项应为单个表达式,可以选择用大括号括起来。对象的初始值是表达式的初始值(转换后);采用与简单赋值相同的类型约束和转换,将标量的类型作为其声明类型的非限定版本。

因此适用简单分配规则。这些将在6.5.16.1 2中讨论:

  

简单赋值 = )中,右操作数的值将转换为赋值表达式的类型,并替换存储在左操作数。

“赋值表达式的类型”是按照6.5.16 3:左操作数的类型。

  

赋值表达式的类型是左值转换后左操作数将具有的类型。

(在这种情况下,左值转换没有什么特别的;对象uint16_t b会简单地变成uint16_t的值,因此类型为uint16_t。)

根据7.20.1.1 1:uint16_t的类型当然是一个无符号的16位整数

  

typedef名称 uint N _t 指定宽度为 N 并且没有填充位的无符号整数类型。

请注意,它是一个无符号的16位整数,最大值为65535,而最大值为65536(2 16 )。这与最后一步有关,即从右操作数到uint16_t的转换,这在6.3.1.3 1和2中进行了讨论:

  

将整数类型的值转换为 _Bool 以外的其他整数类型时,如果该值可以用新类型表示,则该值不变。

     

否则,如果新类型是无符号的,则通过重复添加或减去新类型所能代表的最大值,直到该值在新类型的范围内,来转换该值。

当我们从0x10000 0x11223344减去65536(0x1122)时,结果是0x3344,可以用uint16_t表示,因此是转换的结果。

相关问题