我需要将整数值转换为位层的char数组。假设int有4个字节,我需要将它分成4个长度为1个字节的块作为字符数组。
示例:
int a = 22445;
// this is in binary 00000000 00000000 1010111 10101101
...
//and the result I expect
char b[4];
b[0] = 0; //first chunk
b[1] = 0; //second chunk
b[2] = 87; //third chunk - in binary 1010111
b[3] = 173; //fourth chunk - 10101101
我需要这个转换速度非常快,如果可能的话没有任何循环(可能有点操作的一些技巧)。目标是在一秒钟内进行数千次这样的转换。
答案 0 :(得分:3)
int a = 22445;
char *b = (char *)&a;
char b2 = *(b+2); // = 87
char b3 = *(b+3); // = 173
答案 1 :(得分:3)
我不确定我是否建议这样做,但你可以#include
<stddef.h>
和<sys/types.h>
并写一下:
*(u32_t *)b = htonl((u32_t)a);
(htonl
是为了确保整数在big-endian order之前存储。)
答案 2 :(得分:2)
根据您希望如何表示负数,您只需转换为unsigned
,然后使用掩码和班次:
unsigned char b[4];
unsigned ua = a;
b[0] = (ua >> 24) & 0xff;
b[1] = (ua >> 16) & 0xff;
b[2] = (ua >> 8) & 0xff
b[3] = ua & 0xff;
(由于将负数转换为无符号的C规则,这将产生负数的二进制补码表示,这几乎肯定是你想要的。)
答案 3 :(得分:1)
要访问任何类型的二进制表示,可以转换指向char指针的指针:
T x; // anything at all!
// In C++
unsigned char const * const p = reinterpret_cast<unsigned char const *>(&x);
/* In C */
unsigned char const * const p = (unsigned char const *)(&x);
// Example usage:
for (std::size_t i = 0; i != sizeof(T); ++i)
std::printf("Byte %u is 0x%02X.\n", p[i]);
也就是说,您可以将p
视为指向数组unsigned char[sizeof(T)]
的第一个元素的指针。 (在您的情况下,T = int
。)
我在这里使用unsigned char
,这样在打印二进制值时就不会出现任何符号扩展问题(例如,在我的示例中通过printf
)。如果要将数据写入文件,请改用char
。
答案 4 :(得分:0)
你已经接受了答案,但我仍然会给我,这可能更适合你(或相同......)。这是我测试过的:
int a[3] = {22445, 13, 1208132};
for (int i = 0; i < 3; i++)
{
unsigned char * c = (unsigned char *)&a[i];
cout << (unsigned int)c[0] << endl;
cout << (unsigned int)c[1] << endl;
cout << (unsigned int)c[2] << endl;
cout << (unsigned int)c[3] << endl;
cout << "---" << endl;
}
......它对我有用。现在我知道你要求一个char数组,但这是等价的。您还要求第一种情况下c [0] == 0,c [1] == 0,c [2] == 87,c [3] == 173,此处订单相反。
基本上,您使用SAME值,只能以不同方式访问它。
为什么我没有使用过htonl(),你可能会问?
因为性能是一个问题,我认为你最好不要使用它,因为看起来浪费(珍贵的?)周期来调用一个函数来确保字节将按某种顺序排列,当它们可能有在某些系统上已经按顺序排列,如果不是这样的话,你可以修改你的代码以使用不同的顺序。
相反,您可以先检查订单,然后根据测试结果使用不同的循环(更多代码,但性能得到改善)。
另外,如果您不知道您的系统是否使用2或4字节的int,您可以在之前检查,并根据结果再次使用不同的循环。
重点是:你将拥有更多的代码,但你不会在循环内部的关键区域浪费周期。
如果仍然存在性能问题,可以展开循环(循环内的重复代码,并减少循环计数),因为这样可以节省几个周期。
注意,就C ++而言,使用c [0],c [1]等等等于*(c),*(c + 1)。
答案 5 :(得分:-2)
typedef union{
byte intAsBytes[4];
int int32;
}U_INTtoBYTE;