繁体   English   中英

整数到char数组中

[英]Integer into char array

我需要将整数值转换为位层上的char数组。 假设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

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

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

我不确定是否建议这样做,但是可以#include <stddef.h><sys/types.h>并编写:

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

htonl是为了确保在存储整数之前,它是按big-endian顺序排列的 。)

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

要访问任何类型的二进制表示形式,可以将指针转换为字符指针:

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

...对我有用。 现在我知道您请求了一个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)。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM