I have an unsigned int number (2 byte) and I want to convert it to unsigned char type. From my search, I find that most people recommend to do the following:
我有一个未签名的整数(2个字节),我想把它转换成无符号的char类型。从我的搜索中,我发现大多数人建议做以下工作:
unsigned int x;
...
unsigned char ch = (unsigned char)x;
Is the right approach? I ask because unsigned char is 1 byte and we casted from 2 byte data to 1 byte.
是正确的做法吗?我问,因为无符号char是1个字节,我们从2字节数据转换为1字节。
To prevent any data loss, I want to create an array of unsigned char[] and save the individual bytes into the array. I am stuck at the following:
为了防止任何数据丢失,我希望创建一个无符号字符数组,并将单个字节保存到数组中。我被困在下面:
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] ??
}
Also, how would we convert the unsigned char[2] back to unsigned int.
另外,如何将未签名的char[2]转换为unsigned int。
Thanks a lot.
非常感谢。
6 个解决方案
#1
16
You can use memcpy
in that case:
在这种情况下,你可以使用memcpy:
memcpy(ch, (char*)&num, 2); /* although sizeof(int) would be better */
Also, how would be convert the unsigned char[2] back to unsigned int.
另外,如何将未签名的char[2]返回到unsigned int。
The same way, just reverse the arguments of memcpy.
用同样的方法,只是颠倒了memcpy的参数。
#2
15
How about:
如何:
ch[0] = num & 0xFF;
ch[1] = (num >> 8) & 0xFF;
The converse operation is left as an exercise.
相反的操作是作为一个练习。
#3
7
How about using a union?
使用工会怎么样?
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
4
Of course, array of chars large enough to contain a larger value has to be exactly as big as this value itself. So you can simply pretend that this larger value already is an array of chars:
当然,包含较大值的chars数组必须与这个值本身一样大。所以你可以简单地假设这个更大的值已经是一个字符数组:
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
(Once you understand what's going on, it can be done without any variables, all just casting)
(一旦你明白了发生了什么,你就可以不用任何变量,所有的事情都能完成)
#5
4
It really depends on your goal: why do you want to convert this to an unsigned char
? Depending on the answer to that there are a few different ways to do this:
这实际上取决于您的目标:为什么要将其转换为无符号字符?根据不同的答案有几种不同的方法:
-
Truncate: This is what was recomended. If you are just trying to squeeze data into a function which requires an
unsigned char
, simply castuchar ch = (uchar)x
(but, of course, beware of what happens if your int is too big).Truncate:这是recomended。如果您只是试图将数据压缩到一个需要无符号字符的函数中,那么只需cast uchar ch = (uchar)x(但是,当然,要注意如果int太大会发生什么)。
-
Specific endian: Use this when your destination requires a specific format. Usually networking code likes everything converted to big endian arrays of chars:
特定的endian:当您的目的地需要特定的格式时使用它。通常,网络代码喜欢所有转换成大字节数组的字符:
int n = sizeof x; for(int y=0; n-->0; y++) ch[y] = (x>>(n*8))&0xff;
will does that.
会这样。
-
Machine endian. Use this when there is no endianness requirement, and the data will only occur on one machine. The order of the array will change across different architectures. People usually take care of this with
union
s:机器尾数法。当没有发现需求时使用这个,数据只会出现在一台机器上。数组的顺序将在不同的体系结构中发生变化。人们通常会用工会来解决这个问题:
union {int x; char ch[sizeof (int)];} u; u.x = 0xf00 //use u.ch
with
memcpy
:memcpy:
uchar ch[sizeof(int)]; memcpy(&ch, &x, sizeof x);
or with the ever-dangerous simple casting (which is undefined behavior, and crashes on numerous systems):
或者使用危险的简单铸件(这是未定义的行为,并在许多系统上崩溃):
char *ch = (unsigned char *)&x;
#6
2
You just need to extract those bytes using bitwise & operator
. OxFF
is a hexadecimal mask to extract one byte. Please look at various bit operations here - http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/
您只需要使用位和操作符来提取这些字节。OxFF是一个十六进制的掩码,用来提取一个字节。请查看这里的各种操作:http://www.catonmat.net/blog/low-level- bit-hacks-absolutelly -必知/。
An example program is as follows:
一个示例程序如下:
#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;
}
Output:
输出:
$ gcc 1.c
$ ./a.out
c[0] = 22
c[1] = 11
i = 1122
$
#1
16
You can use memcpy
in that case:
在这种情况下,你可以使用memcpy:
memcpy(ch, (char*)&num, 2); /* although sizeof(int) would be better */
Also, how would be convert the unsigned char[2] back to unsigned int.
另外,如何将未签名的char[2]返回到unsigned int。
The same way, just reverse the arguments of memcpy.
用同样的方法,只是颠倒了memcpy的参数。
#2
15
How about:
如何:
ch[0] = num & 0xFF;
ch[1] = (num >> 8) & 0xFF;
The converse operation is left as an exercise.
相反的操作是作为一个练习。
#3
7
How about using a union?
使用工会怎么样?
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
4
Of course, array of chars large enough to contain a larger value has to be exactly as big as this value itself. So you can simply pretend that this larger value already is an array of chars:
当然,包含较大值的chars数组必须与这个值本身一样大。所以你可以简单地假设这个更大的值已经是一个字符数组:
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
(Once you understand what's going on, it can be done without any variables, all just casting)
(一旦你明白了发生了什么,你就可以不用任何变量,所有的事情都能完成)
#5
4
It really depends on your goal: why do you want to convert this to an unsigned char
? Depending on the answer to that there are a few different ways to do this:
这实际上取决于您的目标:为什么要将其转换为无符号字符?根据不同的答案有几种不同的方法:
-
Truncate: This is what was recomended. If you are just trying to squeeze data into a function which requires an
unsigned char
, simply castuchar ch = (uchar)x
(but, of course, beware of what happens if your int is too big).Truncate:这是recomended。如果您只是试图将数据压缩到一个需要无符号字符的函数中,那么只需cast uchar ch = (uchar)x(但是,当然,要注意如果int太大会发生什么)。
-
Specific endian: Use this when your destination requires a specific format. Usually networking code likes everything converted to big endian arrays of chars:
特定的endian:当您的目的地需要特定的格式时使用它。通常,网络代码喜欢所有转换成大字节数组的字符:
int n = sizeof x; for(int y=0; n-->0; y++) ch[y] = (x>>(n*8))&0xff;
will does that.
会这样。
-
Machine endian. Use this when there is no endianness requirement, and the data will only occur on one machine. The order of the array will change across different architectures. People usually take care of this with
union
s:机器尾数法。当没有发现需求时使用这个,数据只会出现在一台机器上。数组的顺序将在不同的体系结构中发生变化。人们通常会用工会来解决这个问题:
union {int x; char ch[sizeof (int)];} u; u.x = 0xf00 //use u.ch
with
memcpy
:memcpy:
uchar ch[sizeof(int)]; memcpy(&ch, &x, sizeof x);
or with the ever-dangerous simple casting (which is undefined behavior, and crashes on numerous systems):
或者使用危险的简单铸件(这是未定义的行为,并在许多系统上崩溃):
char *ch = (unsigned char *)&x;
#6
2
You just need to extract those bytes using bitwise & operator
. OxFF
is a hexadecimal mask to extract one byte. Please look at various bit operations here - http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/
您只需要使用位和操作符来提取这些字节。OxFF是一个十六进制的掩码,用来提取一个字节。请查看这里的各种操作:http://www.catonmat.net/blog/low-level- bit-hacks-absolutelly -必知/。
An example program is as follows:
一个示例程序如下:
#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;
}
Output:
输出:
$ gcc 1.c
$ ./a.out
c[0] = 22
c[1] = 11
i = 1122
$