通过在 c 中强制转换,将较大大小的变量单元 16 复制到等效的较小数组大小 uint8
Copy larger size variable unit16 to equivalent smaller array size unint8 by casting in c
我有变量uint16 value
,我想将它复制到uint8_t buffer[3]
。是否可以做(小端):
*buffer=*(uint8_t *)&value;
而不是:
buffer[0] = highByte(value);
buffer[1] = lowByte(value);
由于此替换导致 stm32f7 I2C 无法正常工作。有没有正确的转换?
STM32 是小端字节序,因此您首先获取最低有效字节:
uint8_t* ptr = (uint8_t*)&value;
uint8_t low = ptr[0];
uint8_t high = ptr[1];
像这样进行强制转换和取消引用只适用于字符类型。上面的代码假设 uint8_t
是一个字符类型,这很可能是这种情况(在 gcc 和其他主流编译器上)。
有关详细信息,请参阅 What is CPU endianness?
编辑:
如果您只想将一个 16 位数字复制到一个字节数组中,正确的解决方案是:
memcpy(buffer, &value, sizeof(uint16_t)).
我们不能做*(uint16_t*) buffer=value;
,因为它会调用未定义的行为。 buffer
可能未对齐,它也是 strict aliasing violation。这就是为什么我在上面强调写“这只适用于 字符类型 ”。
Is there any correct casting?
没有
*buffer = <expression>
将始终且仅写入 buffer[0]
,永远不会写入 buffer[1]
。
有一件事你可以做——但我强烈建议你不要是这样的:
uint16_t *ptr = (uint16_t*)buffer; // Ugh, danger
*ptr = value;
如果您 运行 在具有不同字节序的机器上使用它,这将是有问题的。很可能还有其他原因不这样做。一旦你问自己是否可以通过转换解决问题,你就应该退后一步。这是我写的两个答案:
假设要解决@Lundin 提到的与高侧和低侧相关的问题,以及取消引用 uint8_t 仅授予对它的第一个数组元素的访问权这一事实,我仅通过一个演员:
*(uint16_t*) buffer=value;
这是以下版本的缩减版:
uint16_t* p;
p= buffer;
*p=value;
我有变量uint16 value
,我想将它复制到uint8_t buffer[3]
。是否可以做(小端):
*buffer=*(uint8_t *)&value;
而不是:
buffer[0] = highByte(value);
buffer[1] = lowByte(value);
由于此替换导致 stm32f7 I2C 无法正常工作。有没有正确的转换?
STM32 是小端字节序,因此您首先获取最低有效字节:
uint8_t* ptr = (uint8_t*)&value;
uint8_t low = ptr[0];
uint8_t high = ptr[1];
像这样进行强制转换和取消引用只适用于字符类型。上面的代码假设 uint8_t
是一个字符类型,这很可能是这种情况(在 gcc 和其他主流编译器上)。
有关详细信息,请参阅 What is CPU endianness?
编辑:
如果您只想将一个 16 位数字复制到一个字节数组中,正确的解决方案是:
memcpy(buffer, &value, sizeof(uint16_t)).
我们不能做*(uint16_t*) buffer=value;
,因为它会调用未定义的行为。 buffer
可能未对齐,它也是 strict aliasing violation。这就是为什么我在上面强调写“这只适用于 字符类型 ”。
Is there any correct casting?
没有
*buffer = <expression>
将始终且仅写入 buffer[0]
,永远不会写入 buffer[1]
。
有一件事你可以做——但我强烈建议你不要是这样的:
uint16_t *ptr = (uint16_t*)buffer; // Ugh, danger
*ptr = value;
如果您 运行 在具有不同字节序的机器上使用它,这将是有问题的。很可能还有其他原因不这样做。一旦你问自己是否可以通过转换解决问题,你就应该退后一步。这是我写的两个答案:
假设要解决@Lundin 提到的与高侧和低侧相关的问题,以及取消引用 uint8_t 仅授予对它的第一个数组元素的访问权这一事实,我仅通过一个演员:
*(uint16_t*) buffer=value;
这是以下版本的缩减版:
uint16_t* p;
p= buffer;
*p=value;