如何将 char 转换为 unsigned int?

发布于 2024-12-11 14:17:12 字数 787 浏览 0 评论 0原文

我有一个字符数组,它实际上用作字节数组,而不是用于存储文本。在数组中,有两个特定字节表示我需要存储到无符号 int 值中的数值。下面的代码解释了设置。

char* bytes = bytes[2];
bytes[0] = 0x0C; // For the sake of this example, I'm 
bytes[1] = 0x88; // assigning random values to the char array.

unsigned int val = ???; // This needs to be the actual numeric 
                        // value of the two bytes in the char array.  
                        // In other words, the value should equal 0x0C88;

我不知道该怎么做。我认为这会涉及到一些指针的转换和重新转换,但我无法让它工作。我怎样才能实现我的最终目标?

更新

谢谢 Martin B 的快速回复,但这不起作用。具体来说,在我的例子中,两个字节是 0x000xbc。显然我想要的是0x000000bc。但我在 unsigned int 中得到的是 0xffffffbc

Martin 发布的代码是我实际的原始代码,只要所有字节都小于 128(即正符号 char 值),它就可以正常工作。

I have a char array that is really used as a byte array and not for storing text. In the array, there are two specific bytes that represent a numeric value that I need to store into an unsigned int value. The code below explains the setup.

char* bytes = bytes[2];
bytes[0] = 0x0C; // For the sake of this example, I'm 
bytes[1] = 0x88; // assigning random values to the char array.

unsigned int val = ???; // This needs to be the actual numeric 
                        // value of the two bytes in the char array.  
                        // In other words, the value should equal 0x0C88;

I can not figure out how to do this. I would assume it would involve some casting and recasting of the pointers, but I can not get this to work. How can I accomplish my end goal?

UPDATE

Thank you Martin B for the quick response, however this doesn't work. Specifically, in my case the two bytes are 0x00 and 0xbc. Obviously what I want is 0x000000bc. But what I'm getting in my unsigned int is 0xffffffbc.

The code that was posted by Martin was my actual, original code and works fine so long as all of the bytes are less than 128 (.i.e. positive signed char values.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

剑心龙吟 2024-12-18 14:17:12
unsigned int val = (unsigned int)(unsigned char)bytes[0] << CHAR_BIT
                   | (unsigned int)(unsigned char)bytes[1];

if sizeof(unsigned int) >= 2 * sizeof(unsigned char) (不是 C 标准保证的)

现在...这里有趣的事情肯定是运算符的顺序(在许多情况下)多年来我只记得+、-、*和/...真为我感到羞耻:-),所以我总是放尽可能多的括号)。 [] 是王道。第二个是(cast)。第三个是 <<,第四个是 |(如果您使用 + 而不是 | ,记住 +<< 更重要,所以你需要括号)

我们显式地将无符号字符转换为无符号整数,因为如果我们不这样做,C会自动将它们提升为签名相反。额外的强制转换避免了一些签名溢出问题,特别是如果此代码被修改为使用 4 个字符而不是 2 个字符。

如果您想减少一些麻烦,我将补充一点:

unsigned int val = (unsigned int)(unsigned char)bytes[0] << CHAR_BIT;
val |= (unsigned int)(unsigned char)bytes[1];
unsigned int val = (unsigned int)(unsigned char)bytes[0] << CHAR_BIT
                   | (unsigned int)(unsigned char)bytes[1];

This if sizeof(unsigned int) >= 2 * sizeof(unsigned char) (not something guaranteed by the C standard)

Now... The interesting things here is surely the order of operators (in many years still I can remember only +, -, * and /... Shame on me :-), so I always put as many brackets I can). [] is king. Second is the (cast). Third is the << and fourth is the | (if you use the + instead of the |, remember that + is more important than << so you'll need brackets)

We explicitly cast the unsigned chars to unsigned ints because if we didn't, C would automatically promote them to signed ints instead. The extra cast avoids some signed overflow headaches, especially if this code ever gets modified to use 4 chars instead of 2.

I'll add that if you want less headaches:

unsigned int val = (unsigned int)(unsigned char)bytes[0] << CHAR_BIT;
val |= (unsigned int)(unsigned char)bytes[1];
晨曦慕雪 2024-12-18 14:17:12
unsigned int val = (unsigned char) bytes[0]<<8 | (unsigned char) bytes[1];
unsigned int val = (unsigned char) bytes[0]<<8 | (unsigned char) bytes[1];
栩栩如生 2024-12-18 14:17:12

字节顺序取决于处理器的字节顺序。您可以执行此操作,这适用于大端或小端机器。 (没有 ntohs 它将在大端上工作):

unsigned int val = ntohs(*(uint16_t*)bytes)

The byte ordering depends on the endianness of your processor. You can do this, which will work on big or little endian machines. (without ntohs it will work on big-endian):

unsigned int val = ntohs(*(uint16_t*)bytes)
懒的傷心 2024-12-18 14:17:12
unsigned int val = bytes[0] << 8 + bytes[1];
unsigned int val = bytes[0] << 8 + bytes[1];
拿命拼未来 2024-12-18 14:17:12

我认为这是比依赖指针别名更好的方法:

union {unsigned asInt; char asChars[2];} conversion;
conversion.asInt = 0;
conversion.asChars[0] = 0x0C;
conversion.asChars[1] = 0x88;
unsigned val = conversion.asInt;

I think this is a better way to go about it than relying on pointer aliasing:

union {unsigned asInt; char asChars[2];} conversion;
conversion.asInt = 0;
conversion.asChars[0] = 0x0C;
conversion.asChars[1] = 0x88;
unsigned val = conversion.asInt;
萌逼全场 2024-12-18 14:17:12

我永远不知道编译器将通过隐式转换在幕后做什么,所以我通常尝试使用显式按位运算。例如:

unsigned int val = 0;
val |= bytes[0]<<8;
val |= bytes[1];

这里我使用按位或,当用于保持值 0 的变量时,它基本上复制了位。
您可以随意修改它来更改字节顺序或您想要执行的任何其他格式。

I never know quite what the compiler is going to do behind the scenes with implicit casting, so I generally try to use explicit bitwise operations. eg:

unsigned int val = 0;
val |= bytes[0]<<8;
val |= bytes[1];

here I'm using the bitwise or, which basically copies the bits in when used on a variable holding the value 0.
You can mess around with this to change endianness or any other formatting you want to do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文