【问题标题】:C - unsigned int to unsigned char array conversionC - unsigned int 到 unsigned char 数组转换
【发布时间】:2012-05-06 09:10:13
【问题描述】:

我有一个 unsigned int 数字(2 字节),我想将它转换为 unsigned char 类型。从我的搜索中,我发现大多数人建议执行以下操作:

 unsigned int x;
 ...
 unsigned char ch = (unsigned char)x;

是正确的方法吗?我问是因为 unsigned char 是 1 字节,我们将 2 字节数据转换为 1 字节。

为了防止任何数据丢失,我想创建一个 unsigned char[] 数组并将各个字节保存到数组中。我陷入了以下困境:

 unsigned char ch[2];
 unsigned int num = 272;

 for(i=0; i<2; i++){
      // how should the individual bytes from num be saved in ch[0] and ch[1] ??
 }

另外,我们如何将 unsigned char[2] 转换回 unsigned int

非常感谢。

【问题讨论】:

标签: c byte unsigned-integer type-conversion unsigned-char


【解决方案1】:

在这种情况下你可以使用memcpy

memcpy(ch, (char*)&num, 2); /* although sizeof(int) would be better */

另外,如何将 unsigned char[2] 转换回 unsigned int。

同理,把memcpy的参数反过来就好了。

【讨论】:

    【解决方案2】:

    怎么样:

    ch[0] = num & 0xFF;
    ch[1] = (num >> 8) & 0xFF;
    

    逆向操作留作练习。

    【讨论】:

      【解决方案3】:

      使用联合怎么样?

      union {
          unsigned int num;
          unsigned char ch[2];
      }  theValue;
      
      theValue.num = 272;
      printf("The two bytes: %d and %d\n", theValue.ch[0], theValue.ch[1]);
      

      【讨论】:

        【解决方案4】:

        这真的取决于您的目标:为什么要将其转换为unsigned char?根据答案,有几种不同的方法可以做到这一点:

        • 截断:这是推荐的。如果您只是想将数据压缩到需要 unsigned char 的函数中,只需强制转换 uchar ch = (uchar)x(当然,请注意如果您的 int 太大会发生什么)。

        • 特定字节序:当您的目标需要特定格式时使用此选项。通常网络代码喜欢将所有内容转换为大端字符数组:

          int n = sizeof x;
          for(int y=0; n-->0; y++)
              ch[y] = (x>>(n*8))&0xff;
          

          会这样做的。

        • 机器字节序。当没有字节序要求时使用它,并且数据只会出现在一台机器上。阵列的顺序将在不同的架构中发生变化。人们通常通过unions 来处理这个问题:

          union {int x; char ch[sizeof (int)];} u;
          u.x = 0xf00
          //use u.ch 
          

          memcpy:

          uchar ch[sizeof(int)];
          memcpy(&ch, &x, sizeof x);
          

          或者使用非常危险的简单强制转换(这是未定义的行为,并且在许多系统上崩溃):

          char *ch = (unsigned char *)&x;
          

        【讨论】:

          【解决方案5】:

          当然,足以包含更大值的字符数组必须与该值本身一样大。 所以你可以简单地假设这个较大的值已经是一个字符数组:

          unsigned int x = 12345678;//well, it should be just 1234.
          unsigned char* pChars;
          
          pChars = (unsigned char*) &x;
          
          pChars[0];//one byte is here
          pChars[1];//another byte here
          

          (一旦你了解了发生了什么,就可以在没有任何变量的情况下完成,一切都只是强制转换)

          【讨论】:

          • 如果12345678 适合unsigned intsizeof(unsigned int) == 2,那么CHAR_BIT 比平时大 ;-)
          • 怪32位社会宠我!
          【解决方案6】:

          您只需要使用bitwise &amp; operator 提取这些字节。 OxFF 是用于提取一个字节的十六进制掩码。请看这里的各种位操作-http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/

          示例程序如下:

          #include <stdio.h>
          
          int main()
          {
              unsigned int i = 0x1122;
              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]);
              printf("i    = %x \n", i);
          
              return 0;
          }
          

          输出:

          $ gcc 1.c 
          $ ./a.out 
          c[0] = 22 
          c[1] = 11 
          i    = 1122 
          $
          

          【讨论】:

          • 您的意思是将 num 和 0xFF00 移动 8 位,对吗? (数字和 0xFF00)>>8。否则,您只有一个 16 位整数,其中低字节恰好为零。你仍然没有一个字节。或者,您可以只转换: num >> 8;
          猜你喜欢
          • 2013-05-16
          • 1970-01-01
          • 2012-04-28
          • 1970-01-01
          • 1970-01-01
          • 2022-01-04
          • 2020-10-11
          • 2014-12-27
          • 1970-01-01
          相关资源
          最近更新 更多