我尝试将unsigned long int转换为char 但我收到了一些错误
buffalo
,输出
int main(void)
{
unsigned char pdest[4];
unsigned long l=0xFFFFFFFF;
pdest[0] = l & 0xFF;
pdest[1] = (l >> 8) & 0xFF;
pdest[2] = (l >> 16) & 0xFF;
pdest[3] = (l >> 24) & 0xFF;
unsigned long int l1=0;
l1 |= (pdest[0]);
l1 |= (pdest[1] << 8);
l1 |= (pdest[2] << 16);
l1 |= (pdest[3] << 24);
printf ("%lu",l1);
}
不是4294967295?
如何做到正确?
答案 0 :(得分:0)
阅读本文: https://en.wikipedia.org/wiki/C_data_types
...长无符号整数类型。能够包含至少 [0, 4,294,967,295]范围;
答案 1 :(得分:0)
您应该将最后4行写为:
l1 |= ((unsigned long) pdest[0]);
l1 |= (((unsigned long) pdest[1]) << 8);
l1 |= (((unsigned long) pdest[2]) << 16);
l1 |= (((unsigned long) pdest[3]) << 24);
因为你应该在移位之前将字节转换为unsigned long。
答案 2 :(得分:0)
pdest [3]&lt;&lt; 24的类型为signed int。
将您的代码更改为
unsigned long int l1=0;
l1 |= (pdest[0]);
l1 |= (pdest[1] << 8);
l1 |= (pdest[2] << 16);
l1 |= ((unsigned int)pdest[3] << 24);
答案 3 :(得分:0)
问题在于char的转移。您必须在转换为超过8位的char之前强制转换为unsigned。此外,char的标志将对结果进行进一步的改动。
尝试
unsigned long int l1=0;
l1 |= ((unsigned long)pdest[0]);
l1 |= ((unsigned long)pdest[1] << 8);
l1 |= ((unsigned long)pdest[2] << 16);
l1 |= ((unsigned long)pdest[3] << 24);
注意使用强制转换强制编译器在发生转换之前将char转换为unsigned。
答案 4 :(得分:0)
你的无符号长整数不必是4个字节。
#include <stdio.h>
#include <stdint.h>
int main(void) {
int index;
unsigned char pdest[sizeof(unsigned long)];
unsigned long l=0xFFFFFFFFUL;
for(index = 0; index < sizeof(unsigned long); index++)
{
pdest[index] = l & 0xff;
l >>= 8;
}
unsigned long l1=0;
for(index = 0; index < sizeof(unsigned long); index++)
{
l1 |= (unsigned long)pdest[index] << (8 * index);
}
printf ("%lx\n",l1);
}
答案 5 :(得分:0)
首先,要命名一个32位宽的类型,请使用uint32_t
,而不是unsigned long int
。 unsigned long int
在64位* nix(通常称为LP64)中通常为64位宽,而在Windows(LLP64)中它们是32位。
无论如何,问题在于整数促销。转换级别小于int
或unsigned int
的算术运算的操作数将转换为int
或unsigned int
,无论其范围如何。由于所有unsigned char
代表signed int
s,pdest[3]
转换为signed int
,pdest[3] << 24
的结果也属signed int
类型!现在,如果它具有最高有效位设置,则该位移位到整数的符号位,并且行为符合C标准 undefined 。
然而,海湾合作委员会已为此案定义了行为;在那里,结果只是一个带有2的补码表示的负整数;因此(unsigned char)0xFF << 24
的结果是(int)-16777216
。现在,对于|
操作,需要将其提升为其他操作数的等级,即unsigned
。无符号转换就好像通过重复加或减一个多于最大值(即重复加或减2)直到该值适合该值的范围。由于您的平台上unsigned long
为64位,因此此转换的结果为2 ^ 64 - 16777216或18446744073692774400,它与先前步骤中的位进行了“或”运算。
如何解决?很容易,就在轮班之前,将每个移位的数字转换为uint32_t
。在PRIu32
宏的帮助下打印:
#include <inttypes.h>
...
uint32_t l1=0;
l1 |= (uint32_t)pdest[0];
l1 |= (uint32_t)pdest[1] << 8;
l1 |= (uint32_t)pdest[2] << 16;
l1 |= (uint32_t)pdest[3] << 24;
printf ("%" PRIu32, l1);
答案 6 :(得分:0)
你的代码的问题是unsigned char到int的隐式类型转换,然后是带有符号或操作的带符号扩展的unsigned long,每行的相应值如下所示
l1 |= (pdest[0]); //dec = 255 hex = 0xFF
l1 |= (pdest[1] << 8); //dec = 65535 hex = 0xFFFF
l1 |= (pdest[2] << 16); //dec = 16777215 hex =0xFFFFFF
l1 |= (pdest[3] << 24); //here is the problem
在最后一行pdest[3] << 24 = 0xFF000000
中由于隐式转换为int而等同于-16777216
。对于按位或操作,它再次转换为无符号长整数,其中有符号扩展名在l1 |= (pdest[3] << 24)
中发生,相当于0x0000000000FFFFFF | 0xFFFFFFFFFF000000
。
许多人建议您可以使用显式类型转换,或者您可以使用下面的代码段
l1 = (l1 << 0) | pdest[3];
l1 = (l1 << 8) | pdest[2];
l1 = (l1 << 8) | pdest[1];
l1 = (l1 << 8) | pdest[0];
我希望它能解决你的问题,并为这么大的输出提供理由。