如何对变量进行位移并形成整个值
how to bit shift the variable and form the whole value
我在 C 中有以下代码:
#include <stdint.h>
uint32_t result;
uint8_t bit[4] = {1, 2, 3, 4};
由于 bit
数组的每个元素占用 8 位,而变量 result
占用 32 位,我想使用 bit
中的 4 个元素组成 result
数组,bit[0]
取最高位(MSB) result
的8位,bit[1]
取第二个MSB result
的8位,bit[2]
取第三个result
的MSB 8位,bit[3]
取result
的最低位8位,在C中如何构成?
我知道位移运算符,但是把所有的元素移位后,如何组合起来形成一个值?
经典方法是相应地移动值并按位或它们:
result = bit[3] | (bit[2] << 8) | (bit[1] << 16) | (bit[0] << 24);
当你对小于int
的类型执行移位操作时,它会自动"promoted"到int
(查找"integer promotion") .由于 int
在所有实际系统上至少是 32 位,因此此代码在实际意义上是安全的。
但是,如果您需要使用大于 int 的数据类型,则应在转换前将 bit[x]
转换为目标类型。例如,如果您在 int 为 16 位(例如 8086)的平台上工作,则正确的代码将是:
result = (uint32_t)bit[3] | ((uint32_t)bit[2] << 8) | ((uint32_t)bit[1] << 16) | ((uint32_t)bit[0] << 24);
(这有一些不必要的转换,但说明了一点并且不会伤害任何东西)
同样,如果 result
是 uint64_t
并且您在 bit
中有 8 个元素,您需要将它们全部转换为 uin64_t
,因为默认情况下它们只会升级到 int
,(可能)是 32 位。
但是,如果您想访问 uint32_t
的特定字节,您可以将它们声明为联合:
union { uint32_t result; uint8_t bytes[4]; } u;
u.result = 0xabcdef12;
u.bytes[2] = 0x78;
printf("%x", u.result);
我在 C 中有以下代码:
#include <stdint.h>
uint32_t result;
uint8_t bit[4] = {1, 2, 3, 4};
由于 bit
数组的每个元素占用 8 位,而变量 result
占用 32 位,我想使用 bit
中的 4 个元素组成 result
数组,bit[0]
取最高位(MSB) result
的8位,bit[1]
取第二个MSB result
的8位,bit[2]
取第三个result
的MSB 8位,bit[3]
取result
的最低位8位,在C中如何构成?
我知道位移运算符,但是把所有的元素移位后,如何组合起来形成一个值?
经典方法是相应地移动值并按位或它们:
result = bit[3] | (bit[2] << 8) | (bit[1] << 16) | (bit[0] << 24);
当你对小于int
的类型执行移位操作时,它会自动"promoted"到int
(查找"integer promotion") .由于 int
在所有实际系统上至少是 32 位,因此此代码在实际意义上是安全的。
但是,如果您需要使用大于 int 的数据类型,则应在转换前将 bit[x]
转换为目标类型。例如,如果您在 int 为 16 位(例如 8086)的平台上工作,则正确的代码将是:
result = (uint32_t)bit[3] | ((uint32_t)bit[2] << 8) | ((uint32_t)bit[1] << 16) | ((uint32_t)bit[0] << 24);
(这有一些不必要的转换,但说明了一点并且不会伤害任何东西)
同样,如果 result
是 uint64_t
并且您在 bit
中有 8 个元素,您需要将它们全部转换为 uin64_t
,因为默认情况下它们只会升级到 int
,(可能)是 32 位。
但是,如果您想访问 uint32_t
的特定字节,您可以将它们声明为联合:
union { uint32_t result; uint8_t bytes[4]; } u;
u.result = 0xabcdef12;
u.bytes[2] = 0x78;
printf("%x", u.result);