Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何正确地将无符号字符数组转换为uint32\t_C_Casting - Fatal编程技术网

C 如何正确地将无符号字符数组转换为uint32\t

C 如何正确地将无符号字符数组转换为uint32\t,c,casting,C,Casting,因此,我试图将无符号字符的数组转换为uint32\u t,但每次都会得到不同的结果: unsigned char buffer[] = {0x80, 0x00, 0x00, 0x00};; uint32_t num = (uint32_t*)&buffer; 现在,我不断收到这样的警告: 警告:初始化从指针生成整数而不进行强制转换 当我将num更改为*num时,我没有收到警告,但这并不是真正的问题(更新:好吧,现在我想起来这些可能是相关的),因为每次运行代码都会有不同的结果。其次,nu

因此,我试图将
无符号字符的数组转换为
uint32\u t
,但每次都会得到不同的结果:

unsigned char buffer[] = {0x80, 0x00, 0x00, 0x00};;
uint32_t num = (uint32_t*)&buffer;
现在,我不断收到这样的警告:

警告:初始化从指针生成整数而不进行强制转换

当我将
num
更改为
*num
时,我没有收到警告,但这并不是真正的问题(更新:好吧,现在我想起来这些可能是相关的),因为每次运行代码都会有不同的结果。其次,
num
,一旦正确地强制转换,应该是
128
,但是如果我需要更改缓冲区的endianness,我想我可以自己做


谢谢

首先,您想说
num=*(uint32\u t*)&buffer

要更改endianness,您可以使用诸如bswap_32(在linux中,byteswap.h)或OSSwapInt64(在osx中,libkern/OSByteOrder.h)之类的调用。

您尝试过这个吗

num = (uint32_t)buffer[0] << 24 |
      (uint32_t)buffer[1] << 16 |
      (uint32_t)buffer[2] << 8  |
      (uint32_t)buffer[3];

num=(uint32_t)buffer[0]cnicutar的答案是最好的,假设您想要一个特定的固定端点。如果要使用主机endian,请尝试:

uint32_t num;
memcpy(&num, buffer, 4);
或者对cnicutar的答案应用
ntohl
。任何基于类型双关的方法都是错误和危险的。

借用上面的@,我将结构中的3字节大端无符号字符数组转换为小端无符号整数的方法

struct mystruct {
  int stuff;
  int stuff2;
  unsigned char x[3]    // big endian
} 
mystruct z;
unsigned int y  // little endian

memcpy(&y, z->x, 3);
y=be32toh(y<<8);`
struct mystruct{
智力材料;
int stuff 2;
无符号字符x[3]//大端
} 
mystruct z;
无符号整数y//little-endian
memcpy(&y,z->x,3);

y=be32toh(y发出警告是因为
&buffer
生成指向指针的指针。即使没有引用运算符
&
,警告也不会消失,因为强制转换只更改指针类型。指针进一步转换为整数,因此警告也不会消失

如果持久性并不重要,那么在我看来,显而易见的解决办法就是

unsigned char buffer[] = {0x80, 0x00, 0x00, 0x00};
uint32_t num = *(uint32_t *)buffer;

这意味着取消对字符数组的强制转换指针的引用。

假设它是相同的endianess,则联合将是最佳选择

union
{
    uint32_t u32;
    float flt;  
    uin8_T bytes[4];

} converter;
//使用上述联合体

converter.bytes = your_byte_array;
uint32_t u32_output = converter.u32;
float float_output = converter.flt;

…由于对齐问题,这会产生未定义的行为;在某些RISC处理器上,这可能会使程序崩溃。@larsmans如果不显式强制使用单字符打包方案,静态数组不会正确对齐吗?C标准不能保证这一点。事实上,我相信您的示例也违反了别名规则,这意味着即使缓冲区正确对齐,它也可能由于优化而中断。这是一种传统的方式,但它是无效的C.+1,这是一种明智且可移植的方式。假设
buffer
以大端格式保存
uint32\u t
,当然,但OP没有指定。如果您是这样做的话,这不会导致问题吗铸造缓冲器[i],一个8位的量,对于uint32_t?@Foo-Bah:不,将
无符号字符
转换为
uint32_t
没有问题-后一种类型必须至少与前一种类型一样大,因此值将保持不变。非常感谢,这正是我在寻找并尝试使用cast运算符所做的!上面的示例le您正在将num设置为缓冲区数组的地址。您应该使用
uint32\u t num=*(uint32\u t*)buffer;
来获取该数字。这是双重中断的。首先,给定
无符号字符缓冲区[]
uint32\u t num=*(uint32\u t*)buffer;
,因此是未定义的行为。它还可能违反任何对齐限制:“指向对象类型的指针可能会转换为指向其他对象类型的指针。如果生成的指针未与引用类型正确对齐,则行为未定义。”