C++ 整数转换为字符数组

C++ 整数转换为字符数组,c++,C++,我需要将整数值转换为位层上的字符数组。假设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 - i

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

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

要访问任何类型的二进制表示,可以将指针强制转换为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]);
tx;//什么都可以!
//在C++中
无符号字符常量*常量p=重新解释强制转换(&x);
/*在C中*/
无符号字符常量*常量p=(无符号字符常量*)(&x);
//用法示例:
对于(std::size_t i=0;i!=sizeof(t);+i)
std::printf(“字节%u是0x%02X。\n”,p[i]);
也就是说,您可以将
p
视为指向数组
无符号字符[sizeof(T)]
的第一个元素的指针。(在您的情况下,
T=int


我在这里使用了
unsigned char
,这样在打印二进制值时就不会出现任何符号扩展问题(例如,在我的示例中,通过
printf
)。如果要将数据写入文件,可以使用
char

要访问任何类型的二进制表示,可以将指针强制转换为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]);
int a = 22445;
char *b = (char *)&a;
char b2 = *(b+2); // = 87
char b3 = *(b+3); // = 173
tx;//什么都可以!
//在C++中
无符号字符常量*常量p=重新解释强制转换(&x);
/*在C中*/
无符号字符常量*常量p=(无符号字符常量*)(&x);
//用法示例:
对于(std::size_t i=0;i!=sizeof(t);+i)
std::printf(“字节%u是0x%02X。\n”,p[i]);
也就是说,您可以将
p
视为指向数组
无符号字符[sizeof(T)]
的第一个元素的指针。(在您的情况下,
T=int


我在这里使用了
unsigned char
,这样在打印二进制值时就不会出现任何符号扩展问题(例如,在我的示例中,通过
printf
)。如果要将数据写入文件,可以使用
char

我不确定我是否建议这样做,但您可以
#包括
并写入:

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

htonl
是为了确保在存储整数之前将其保存在中。)

我不确定我是否建议这样做,但您可以
包括
并编写:

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

(在存储整数之前,
htonl
是为了确保整数已输入。)

根据您希望负数的表示方式,您可以简单地转换为
无符号
,然后使用掩码和移位:

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规则,这将产生负数的两个补码表示,这几乎肯定是您想要的)。

根据您希望负数的表示方式,您可以简单地转换为无符号,然后使用掩码和移位:

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规则,这将产生负数的两个补码表示,这几乎肯定是您想要的)。

您已经接受了答案,但我仍将给出我的答案,这可能更适合您(或相同的…)。这就是我所测试的:

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;
}
inta[3]={22445,131208132};
对于(int i=0;i<3;i++)
{
无符号字符*c=(无符号字符*)&a[i];

cout您已经接受了答案,但我仍然会给出我的答案,这可能更适合您(或相同的…)。这是我测试的内容:

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;
}
inta[3]={22445,131208132};
对于(int i=0;i<3;i++)
{
无符号字符*c=(无符号字符*)&a[i];


CUTE对C和C++的标记不重要。C++对内存的混叠有重要的限制。比如,可能的DUP:抱歉,关于标签,我删除了代码> C<代码>,我需要在C++项目中。C和C++都是重要的。C++对内存混叠有很大的限制,比如DUP:对不起,关于标签,我删除了代码>代码>代码>,我需要在C++项目中。用任何代码来命名任何类型的代码都是完全合法的。合法的别名,任何类型的代码都是<代码> char */COD>。@ C++是不可移植的,因为C++中的Endiad依赖性。这是不确定的行为。我预期“不可移植-字节”会出现。如果你有一种检测迂回性的方法,那么,请使用它。你可以读取你想要的任何字节。根本不知道。实际上,我们知道它是PO。SoIP,OP想研究如何在他的平台上实现类型。C++中的UB是访问不活跃的工会成员。这与第一个答案有什么不同?@马丁基姆斯:“看起来工作很好”。是一个完全不合法的行为的表现形式!-)你的圣经没有被触动……在C++中,这是未定义的行为。我期待“不可移植的”-“陈词滥调”出现。如果你有一种检测迂回性的方法,那么,当然,使用它。你可以读出你想要的任何字节。根本不知道。OP想研究在他的平台上如何实现类型。C++中的UB是如何访问不活跃的联盟成员。这与第一个答案有什么不同?@马丁基姆斯:“看起来工作得很好”是一个完全未定义行为的法律表现。————你的圣经没有被感动……我想你错过了一个左翼的引用。(但是IIRC的语法-指针强制转换+作为左值的解引用-可能不是标准的;您可以始终声明一个单独的指针变量)@MatteoItalia:Re:缺少一个解引用:哇,哈,你说得对,现在修好了,谢谢!Re:指针投射+解引用为左值:真的吗?指针投射本身不是左值,但我认为它是一个解引用。(例如,有几个人说是,但似乎没有人这么认为。)