我有一个代码
#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维护订单而不进行endian交换操作。
答案 0 :(得分:3)
memcpy
复制内存。它 维持内存字节的顺序。你无法让memcpy
做其他事情。
你的问题是你不想复制记忆;你想做一些特殊的算术运算(例如,连接两个8位值来得到一个16位的值)。
确切地说,整数类型在内存中的布局方式是未指定的行为。在您的CPU上,memcpy
hack不执行您想要的算术运算。因此,要做你想做的事,除了memcpy
之外,还必须做一些事情。
我建议使用算术运算进行算术运算:你会得到代码,你可以肯定在所有 * 上工作,你的程序很可能与黑客行为相似(甚至更好)无论如何,特别是在打开编译器优化的情况下。
*:具有相关类型的所有内容,当然
答案 1 :(得分:1)
您获得B37
的原因是因为您使用的是小端机器。
对memcpy
的调用正在做你期望的事情。值0x37
将复制到y
的第一个字节,而0x0B
将复制到y
的第二个字节。而且因为你是一个小端架构,y
的第一个字节是最不重要的。因此它包含值0xB37
。
如果您希望x[0]
为高字节且x[1]
为y
的低字节,则需要以不依赖于字节序的方式执行此操作:
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