在C语言中将2个字节合并成一个短整数

在C语言中将2个字节合并成一个短整数,c,network-programming,int,hex,bit-shift,C,Network Programming,Int,Hex,Bit Shift,我通过网络数据包接收到一个短int,这意味着它将以网络字节顺序(big-endian)的2字节形式出现 我想把我收到的两个字节组合成我机器上的一个短int变量,它是小端字节顺序 例如: short int test = 400; //0x190 in big endian, 0x9001 in little endian char testResponse[2] = {0x01, 0x90}; //here is my attempt short int result = testRespons

我通过网络数据包接收到一个短int,这意味着它将以网络字节顺序(big-endian)的2字节形式出现

我想把我收到的两个字节组合成我机器上的一个短int变量,它是小端字节顺序

例如:

short int test = 400; //0x190 in big endian, 0x9001 in little endian
char testResponse[2] = {0x01, 0x90};
//here is my attempt
short int result = testResponse[1] << 8 | testResponse[0];
printf("%d\n", result); //-28671 when expecting 400
short int test=400//大端号为0x190,小端号为0x9001
char testResponse[2]={0x01,0x90};
//这是我的尝试
short int result=testResponse[1]
#include
#包括
int16_t结果;
memcpy(&result,testResponse,sizeof(int16_t));
结果=(int16)ntohs((uint16)结果);

有些平台,如32位arm,不允许未对齐的访问。因此,在调用ntoh之前,请使用memcpy将其转换为正确大小的int。

您混淆了索引。小端数字是0x0190,但您的代码计算的是大端数字,即
0x9001
,在有符号短时间内,左移到符号位时也会导致整数溢出

代码确实不是很容易移植,因为
char
可能是有符号的,也可能是无符号的。虽然大多数体系结构都有无符号字符,但事实是大多数C程序都是为有符号字符体系结构(x86)编写的。0x90是符号扩展的事实可能会导致意外的结果

因此,更便于携带

char testResponse[2] = {0x01, 0x90};
unsigned int tmp = (unsigned)testResponse[0] << 8 | (unsigned)testResponse[1];
short result = tmp;  // implementation-defined behaviour
printf("%d\n", result); // 400
chartestresponse[2]={0x01,0x90};

unsigned int tmp=(unsigned)testResponse[0]您有什么问题?组合这两个数字的方法似乎比OR左移位8位,但这似乎不能给出正确的结果,因此我想知道是否有人知道我的位算术是怎么错的。C中没有“8位左移位”。如果有,移位计数
8
将调用未定义的行为。您最有可能受到integer促销的影响,了解他们吧!并使用固定宽度的无符号类型
char
不保证无符号,也不保证有8位。根据你在现在删除的评论回答:我们需要所有相关信息。或者正如我所说,你得到了正确的代码。endian是字节在内存中的存储方式,而不是如何计算值。要获得
0x0190
您需要
0x01@JeremyRobertson您是否可以通过
short int result=testResponse[0]获得预期的答案?迂腐地说:
*(uint16\u t*)testResponse
是UB as
char testResponse[]
可能无法满足
uint16\u t
的对齐要求。它甚至不学究,但在许多ARM处理器上都很实用。此外,严格的别名,即使在未对齐的访问可能有效的平台上,编译器也可能会出现错误行为。@chux是正确的。我添加了一个memcpy来解决对齐问题。
char testResponse[2] = {0x01, 0x90};
unsigned int tmp = (unsigned)testResponse[0] << 8 | (unsigned)testResponse[1];
short result = tmp;  // implementation-defined behaviour
printf("%d\n", result); // 400