C语言 如何将无符号字符数组正确转换为 uint32_t

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7059299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:23:49  来源:igfitidea点击:

How to properly convert an unsigned char array into an uint32_t

ccasting

提问by omninonsense

So, I'm trying to convert an array of unsigned chars into an uint32_t, but keep getting different results each time:

因此,我试图将unsigned chars数组转换为s uint32_t,但每次都会得到不同的结果:

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

Now, I keep getting this warning:

现在,我不断收到此警告:

warning: initialization makes integer from pointer without a cast

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

When I change numto *numi don't get that warning, but that's not actually the real problem (UPDATE:well, those might be related now that I think of it.), because every time I run the code there is different results. Secondly the num, once it's cast properly, should be 128, but If I need to change the endianness of the buffer I could manage to do that myself, I think.

当我更改为时num*num我没有收到该警告,但这实际上并不是真正的问题(更新:好吧,现在我想到这些可能是相关的。),因为每次运行代码时都会有不同的结果。其次num,一旦正确投射,应该是128,但是如果我需要更改缓冲区的字节序,我可以自己设法做到这一点,我认为.

Thanks!

谢谢!

回答by cnicutar

Did you try this ?

你试过这个吗?

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

This way you control endianness and whatnot.

这样你就可以控制字节序等等。

It's really not safe to cast a charpointer and interpret it as anything bigger. Some machines expect pointers to integers to be aligned.

投射一个char指针并将其解释为更大的东西真的是不安全的。一些机器希望指向整数的指针对齐。

回答by R.. GitHub STOP HELPING ICE

cnicutar's answer is the best assuming you want a particular fixed endianness. If you want host endian, try:

假设你想要一个特定的固定字节序,cnicutar 的答案是最好的。如果您想要主机端,请尝试:

uint32_t num;
memcpy(&num, buffer, 4);

or apply ntohlto cnicutar's answer. Any method based on type punning is wrong and dangerous.

或适用ntohl于 cnicutar 的回答。任何基于类型双关的方法都是错误且危险的。

回答by Foo Bah

First, you want to say num = *(uint32_t *)&buffer

首先,你想说 num = *(uint32_t *)&buffer

To change endianness, you can use a call like bswap_32 (in linux, byteswap.h) or OSSwapInt64 (in osx, libkern/OSByteOrder.h)

要更改字节顺序,您可以使用 bswap_32(在 linux 中,byteswap.h)或 OSSwapInt64(在 osx 中,libkern/OSByteOrder.h)之类的调用

回答by Else

The warning was issued because &bufferyields a pointer to pointer. Even without the reference operator &the warning wouldn't have disappeared because the casting changes only the pointer type. The pointer is further converted to integer and therefore the warning.

发出警告是因为&buffer产生了一个指向指针的指针。即使没有引用运算符&,警告也不会消失,因为转换仅更改指针类型。指针被进一步转换为整数,因此是警告。

If endianness is not important, the obvious solution seems to me

如果字节序不重要,那么明显的解决方案在我看来

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

which means dereferencing the casted pointer to the char array.

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

回答by makermarc

Borrowing from @Mr. R.above, my approach for converting a 3 byte big endian unsigned char array within a structure to a little endian unsigned int...

借用上面的@ Mr. R.,我将结构中的 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);`