整型转换为字符数组

Integer into char array

本文关键字:数组 字符 转换 整型      更新时间:2023-10-16

我需要将整数值转换为位层上的字符数组。假设int有4个字节,我需要把它分成4个长度为1字节的块作为char数组。

的例子:

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

我需要这个转换非常快,如果可能的话没有任何循环(一些技巧与位操作可能)。我们的目标是在一秒钟内完成数千次这样的转换。

我不确定我是否推荐这样做,但您可以#include <stddef.h><sys/types.h>并写入:

*(u32_t *)b = htonl((u32_t)a);

(htonl是为了确保整数在存储之前是大端序)

int a = 22445;
char *b = (char *)&a;
char b2 = *(b+2); // = 87
char b3 = *(b+3); // = 173

根据您希望负数的表示方式,您可以简单地转换为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规则将负数转换为无符号,这将产生负数的两个补码表示,这几乎肯定是您想要的)。

要访问任何类型的二进制表示,可以将指针强制转换为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

你已经接受了一个答案,但我还是会给出我的答案,这可能更适合你(或相同…)下面是我的测试:

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;
}

…这对我很有效。我知道你请求的是一个字符数组,但这是等价的。对于第一种情况,您还要求c[0] == 0, c[1] == 0, c[2] == 87, c[3] == 173,这里顺序颠倒了。

基本上,你使用相同的值,你只是访问它不同。

你可能会问,为什么我没有使用htonl() ?

既然性能是一个问题,我认为你最好不要使用它,因为调用一个函数来确保字节将按某种顺序排列,当它们在某些系统上已经可以按这种顺序排列时,当你可以修改你的代码以使用不同的顺序时,如果不是这样的话,它似乎是浪费(宝贵的?)周期。

因此,您可以在之前检查顺序,然后根据测试结果使用不同的循环(更多的代码,但提高了性能)。

同样,如果你不知道你的系统使用的是2字节还是4字节的int,你可以先检查一下,然后根据结果再次使用不同的循环。

的要点是:你将有更多的代码,但你不会浪费循环的关键区域,这是在循环内。

如果您仍然有性能问题,您可以展开循环(在循环中重复代码,并减少循环计数),因为这也将节省几个循环。

注意,使用c[0], c[1]等。就c++而言,等于*(c), *(c+1)。

typedef union{
  byte intAsBytes[4];
  int int32;
}U_INTtoBYTE;