memcpy of uint8_t to uint16_t

memcpy of uint8_t to uint16_t

本文关键字:uint16 to of memcpy uint8      更新时间:2023-10-16

我有一个代码

#include <iostream>
#include <string.h>
using namespace std;
int main() {
    // your code goes here
    uint8_t x[4] = {55, 11, 0, 20};
    uint16_t y;
    memcpy(&y, &x[0], 2);
    std::cout<<y<<std::endl;
    return 0;
}

(55-37的六角,11-B的六角)其中我希望y包含"37B"(即十进制的-891)。但是,Y实际上包含"B37"(即小数中的2871)。如何在没有端交换操作的情况下使用memcpy维护订单。

memcpy复制内存。它确实维护了内存字节的顺序。你不能让memcpy做其他事情。

你的问题是你不想复制记忆;你想做一些特定的算术运算(例如,连接两个8位的值以获得一个16位的值)。

整数类型在内存中的具体布局方式是未指定的行为。在您的CPU上,memcpy破解不会执行您想要的算术运算。因此,要想做你想做的事,就必须做memcpy之外的事情。

我建议用算术运算来做算术运算:你会得到你可以确信对所有*都有效的代码,而且你的程序很可能会比破解执行得相似(甚至更好),尤其是在启用编译器优化的情况下

*:所有具有相关类型的东西,当然

获得B37的原因是因为您在一台小型endian机器上。

memcpy的调用正在执行您所期望的操作。值0x37被复制到y的第一个字节,而0x0B被复制到y的第二个字节。因为您使用的是小端体系结构,所以y的第一个字节是最不重要的。因此它包含值0xB37

如果您希望x[0]y的高字节,x[1]是低字节,您需要以一种不依赖于endianness的方式来实现:

y = x[1];          // y = 0x0B
y |= x[0] << 8;    // y = 0x0B | 0x3700 = 0x370B

这将使y的值为0x370B。然而,这仍然不是您期望的0x37B值。

如果这是您想要的,那么您需要认识到0x37B对于高字节的值为0x03,对于低字节的值则为0x7B

因此,您需要将x定义如下:

// note the use of hex constants to make the values more clear
uint8_t x[4] = {0x7b, 0x3, 0x0, 0x14};   

或者你需要执行一些额外的比特移位来获得你需要的值:

y = x[1];          // y = 0x0B
y |= x[0] << 4;    // y = 0x0B | 0x370 = 0x37B