我希望方法将整数转换为字节数组(小端), 从字节数组(以小端方式编码)到C中的整数; 无论我们是在LE还是BE机器上工作。
这些功能对此有用吗?
void Int2ByteArrayLE(int x,unsigned char *byteArray)
{
byteArray[0]=x;
byteArray[1]=x>>8;
byteArray[2]=x>>16;
byteArray[3]=x>>24;
}
void ByteArrayLE2Int(unsigned char *byteArray, int*x)
{
*x=byteArray[0] | (byteArray[1]<<8) | (byteArray[2]<<16) | (byteArray[3]<<24);
}
PS。如果x已签名,这是否也有效?
答案 0 :(得分:2)
您实际要做的是在主机字节顺序和网络字节顺序之间进行转换。您需要的是函数htonl
和ntohl
。
要从主机转换为网络字节顺序,请使用:
uint32_t n = (uint32_t)htonl((uint32_t)h);
反方向:
int h = (int)ntohl((uint32_t)n);
这些函数了解主机平台的字节顺序。因此,如果您在大端机器上执行代码,这些函数什么都不做。但是在一个小端机器上,函数会反转字节。
在评论中,您认为您的通信协议要求以小端字节顺序传递信息。这肯定是个错误。您应该遵循标准协议并以网络字节顺序在线路上传输数据。
如果你真的无法改变协议,并且希望通过线路获得小端,那么你只需要一个memcpy
。你的价值观已经是小端,并明显扭转了不会有帮助的字节。
如果您发现自己处于大端客户端,那么您现在需要反转字节。使用此功能:
uint32_t reverseBytes32(uint32_t v){
return ((v & 0xFF) << 24) | ((v & 0xFF00) << 8)
| ((v & 0xFF0000) >> 8) | ((v & 0xFF000000) >> 24);
}
您需要使用强制转换功能将已签名的int
重新解释为未签名的uint32_t
。
答案 1 :(得分:1)
您的代码存在一些问题:
int
的系统上,代码无效。因此代码通常是不可移植的。您需要将代码更改为以下内容:
#include <stdint.h>
void uint32_to_ByteArrayLE (uint32_t x, uint8_t* byteArray)
{
// explicit casts will prevent implicit conversion warnings:
byteArray[0] = (uint8_t)(x >> 0);
byteArray[1] = (uint8_t)(x >> 8);
byteArray[2] = (uint8_t)(x >> 16);
byteArray[3] = (uint8_t)(x >> 24);
}
void ByteArrayLE_to_uint32 (const uint8_t* byteArray, uint32_t* x)
{
/* casts -before- shifting are necessary to prevent integer promotion
and to make the code portable no matter integer size: */
*x = (uint32_t)byteArray[0] << 0 |
(uint32_t)byteArray[1] << 8 |
(uint32_t)byteArray[2] << 16 |
(uint32_t)byteArray[3] << 24;
}
如果不是第二个函数中的强制转换,则转移将发生在int
上,这不是您想要的。
答案 2 :(得分:0)
让我们看一下标准(5.8 Shift运算符):
“E1&lt;&lt; E2 ......如果E1具有有符号类型和非负值,并且E1 * 2 ^ E2在结果类型中可表示,那么这就是结果值;否则,行为是未定义“。
“E1的值&gt;&gt; E2 s E1右移E2位位置....如果E1具有有符号类型和负值,则结果值是实现定义的。”
因此,当x被签名为负数时,对于&lt;&lt;&lt;&lt;&lt;和实现 - 为&gt;&gt;定义。通常,对于带符号的x,如果只有x是非负的,代码将起作用。
答案 3 :(得分:0)
雅。它也可以在有符号整数上工作,因为这个代码与MSB上的符号位扩展无关&gt;&gt;转移。即,是否实现了符号位,它不会影响代码,因为它只涉及处理32位的X.只需存储并检索32位。所以由&gt;&gt;添加的位在MSB将不予考虑。要理解,请考虑
如果x是int x;
//i.e。有符号整数然后
x = -1,即11111111 11111111 11111111 11111111
的ByteArray [0] = X; 11111111 11111111 11111111 11111111
的ByteArray [1] = X&GT;&GT; 8; xxxxxxxx 11111111 11111111 11111111
的ByteArray [2] = X&GT;&GT; 16; xxxxxxxx xxxxxxxx 11111111 11111111
的ByteArray [3] = X&GT;&GT; 24; xxxxxxxx xxxxxxxx xxxxxxxx 11111111
由&gt;&gt;添加的位xxxxxxxx xxxxxxxx xxxxxxxx
未被存储/使用,因此不会影响代码
因此,移位运算符的符号位扩展为done or not
不会影响代码,因为从上面的示例可以清楚地看出,由x
插入的位不用于存储。因此代码可以成功存储binartarray中的数字,并可以重新回到int x