【问题标题】:How convert unsigned int to unsigned char array如何将 unsigned int 转换为 unsigned char 数组
【发布时间】:2015-06-15 08:29:28
【问题描述】:

我只需要使用按位 & 运算符提取这些字节。 0xFF 是用于提取一个字节的十六进制掩码。对于 2 个字节,此代码工作正常:

#include <stdio.h>

int main()
{
    unsigned int i = 0x7ee;
    unsigned char c[2];

    c[0] = i & 0xFF;
    c[1] = (i>>8) & 0xFF;

    printf("c[0] = %x \n", c[0]);
    printf("c[1] = %x \n", c[1]);


    return 0;
}

输出:

c[0] = ee;
c[1] = 7;

我应该怎么做才能让 4 个字节正常工作?

unsigned int i = 0x557e89f3;
unsigned char c[4];

我的代码:

unsigned char c[4];
         c[0] = i & 0xFF;
         c[1] = (i>>8) & 0xFF;
         c[2] = (i>>16) & 0xFF;
         c[3] = (i>>24) & 0xFF;
         printf("c[0] = %x \n", c[0]);
         printf("c[1] = %x \n", c[1]);
         printf("c[2] = %x \n", c[2]);
         printf("c[3] = %x \n", c[3]);

【问题讨论】:

  • 和你现在做的差不多,但也移动了 16 位和 24 位。
  • 与这个问题非常相似:stackoverflow.com/questions/29862863/… 我从来没有收到过更好的答案,但也许我的第一个解决方案对你来说已经足够了。
  • 我的 16 和 24 c[2] = 0 c[3] = 22 输出无法正常工作
  • @BLUEPIXY 我添加我的代码
  • 试试unsigned long int而不是unsigned int

标签: c++ c


【解决方案1】:
#include <stdio.h>

int main()
{
    unsigned int i = 0x557e89f3;
    unsigned char c[4];

    c[0] = i & 0xFF;
    c[1] = (i>>8) & 0xFF;
    c[2] = (i>>16) & 0xFF;
    c[3] = (i>>24) & 0xFF;

    printf("c[0] = %x \n", c[0]);
    printf("c[1] = %x \n", c[1]);
    printf("c[2] = %x \n", c[2]);
    printf("c[3] = %x \n", c[3]);


    return 0;
}

【讨论】:

  • @girl71 请更清楚地描述什么不起作用。什么是完整的输入。完整的输出是什么。
  • 请检查 sizeof(int),在某些编译器中,整数的大小是 16 位而不是 32 位,这可能是一个原因。
  • 或使用 uint32_t (header ) 用于定义字节数的类型。
  • 需要说,格式说明符可能需要更改,stackoverflow.com/questions/27547377/format-specifier-for-unsigned-char
  • @girl71 此处的代码:ideone.com/HX4x0W 给出了正确的输出,因此请与您自己的程序进行比较。如果你不能让它工作,例如复制粘贴该代码,详细描述您使用的平台和编译器类型。
【解决方案2】:

首先。 C 标准不保证 'unsigned int' 是 32 位长的。为确保它,您应该使用在 stdint.h 标头 (C99) 中定义的 uint32_t 类型。但是,这种类型的实现不是强制性的。 其他解决方案是使用保证至少有 32 位的“无符号长”。所以解决方案应该是:

#include <stdio.h>

int main()

{
    unsigned long int i = 0x557e89f3UL;
    unsigned char c[4];

    c[0] = i & 0xFF;
    c[1] = (i>>8) & 0xFF;
    c[2] = (i>>16) & 0xFF;
    c[3] = (i>>24) & 0xFF;

    printf("c[0] = %x \n", c[0]);
    printf("c[1] = %x \n", c[1]);
    printf("c[2] = %x \n", c[2]);
    printf("c[3] = %x \n", c[3]);


    return 0;
}

【讨论】:

  • uint32_t 在这种情况下是首选。如果编译器由于某种原因不支持 stdint.h,则您需要获得一个新的编译器,句号。附带说明一下,文字 0x557e89f3 保证为无符号且至少 32 位宽,因此 UL 符号对于这种特定情况是多余的(尽管在其他情况下是一种很好的做法)。
  • @DonReba 这被标记为 C 和 C++。在 C (C11) 中,unsigned int 仅保证为 2 个字节长,由 UINT_MAX == 65535。不知道你从哪里得到 C++ 与 C 不同的想法,但在 C++03 18.2.2 中它说:“内容与标准 C 库头文件 ." 相同。这在 C++11 中有所改变吗?
【解决方案3】:

您可以简单地将int* 转换为char*。如果您需要单独数组中的字节,请复制它们。

#include <algorithm>
#include <iomanip>
#include <iostream>
using namespace std;

int main() {
    unsigned int i = 0x557e89f3;

    unsigned char c[4];
    copy_n((unsigned char*)&i, 4, c);

    cout << hex << (int)c[0] << ' ' << (int)c[1] << ' '
        << (int)c[2] << ' ' << (int)c[3] << endl;

    return 0;
}

它在 little-endian 系统上输出以下内容。在大端系统上,顺序将被颠倒。

f3 89 7e 55

【讨论】:

  • 此解决方案的输出取决于系统的字节序。
  • @DonReba 在 Eclipse 中带有标头 函数 'copy_n' 无法解析
  • @girl71,这个功能是在 C++11 中添加的。如果你使用 gcc,它需要 -std=c++11 标志。也许 Eclipse 对此有一个选择。在 C++11 之前,您可以使用 std::copymemcpy
  • 当涉及到以这种方式对整数类型进行序列化/反序列化时,正确的解决方案始终是使用移位运算符。任何其他解决方案都是劣质且不可移植的,因此不应使用。
  • @Lundin,不,这实际上取决于您要实现的目标。例如,如果您想查看内存中的布局,那么强制转换是正确的做法。我们不要教条。
猜你喜欢
  • 1970-01-01
  • 2013-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-28
  • 2012-05-06
  • 2022-01-04
  • 2011-12-15
相关资源
最近更新 更多