C-无符号整型到无符号字符数组的转换

C-无符号整型到无符号字符数组的转换,c,byte,unsigned-integer,type-conversion,unsigned-char,C,Byte,Unsigned Integer,Type Conversion,Unsigned Char,我有一个无符号整数(2字节),我想把它转换成无符号字符类型。从我的搜索中,我发现大多数人建议做以下几点: unsigned int x; ... unsigned char ch = (unsigned char)x; 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

我有一个无符号整数(2字节),我想把它转换成无符号字符类型。从我的搜索中,我发现大多数人建议做以下几点:

 unsigned int x;
 ...
 unsigned char ch = (unsigned char)x;
 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] ??
 }
这是正确的方法吗?我这样问是因为无符号字符是1字节,我们将2字节的数据转换为1字节

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

 unsigned int x;
 ...
 unsigned char ch = (unsigned char)x;
 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] ??
 }
无符号字符ch[2];
无符号整数=272;
对于(i=0;i

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

相反的操作留作练习。

在这种情况下,您可以使用
memcpy

memcpy(ch, (char*)&num, 2); /* although sizeof(int) would be better */
另外,如何将无符号字符[2]转换回无符号整数


同样,只需反转memcpy的参数。

使用联合如何

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]);

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

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
int n = sizeof x;
for(int y=0; n-->0; y++)
    ch[y] = (x>>(n*8))&0xff;

(一旦您了解了发生的事情,就可以不使用任何变量进行转换)

您只需使用
按位和运算符提取这些字节
OxFF
是提取一个字节的十六进制掩码。请查看此处的各种位操作-

示例程序如下所示:

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

这实际上取决于您的目标:为什么要将其转换为
无符号字符
?根据答案,有几种不同的方法:

  • Truncate:这是建议的。如果您只是试图将数据压缩到需要
    无符号字符的函数中,只需强制转换
    uchar ch=(uchar)x
    (当然,要注意int太大时会发生什么情况)

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

    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
    
    int n = sizeof x;
    for(int y=0; n-->0; y++)
        ch[y] = (x>>(n*8))&0xff;
    
    威尔会那样做

  • 机器端号。如果没有端号要求,则使用此选项,数据将仅出现在一台机器上。阵列的顺序将在不同的体系结构中发生变化。人们通常使用
    union
    s来处理此问题:

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

    uchar ch[sizeof(int)];
    memcpy(&ch, &x, sizeof x);
    
    或者使用非常危险的简单强制转换(这是一种未定义的行为,并且在许多系统上崩溃):


如果
12345678
符合
unsigned int
sizeof(unsigned int)==2
,则
CHAR\u BIT
比平常更大;-)我责备32位社会宠坏了我!你的意思是把num&0xFF00移8,对吗?(num&0xFF00)>>8。否则,您只需要一个16位整数,其中低字节恰好为零。你仍然没有一个字节。或者,您可以只移动:num>>8;