对char指针进行位操作



谁能帮我理解这段代码中操作的目的:

struct mystruct {
char c;
long int i32;
int i16;
} s;
unsigned char *p = buf;
fread(buf, 7, 1, fp);
s.c = *p++;
s.i32 = (long)*p++ << 24;
s.i32 |= (long)*p++ << 16;
s.i32 |= (unsigned)(*p++ << 8);
s.i32 |= *p++;
s.i16 = *p++ << 8;
s.i16 |= *p++;

基本上,它似乎试图使用char指针解包变量。但是我不理解与long int相关的代码,特别是以下代码:

s.i32 = (long)*p++ << 24;
s.i32 |= (long)*p++ << 16;
s.i32 |= (unsigned)(*p++ << 8);
s.i32 |= *p++;

该代码读取一个32位带符号的大端整数,并通过将每个字节移动到它所属的位置将其转换为机器格式。

代码也假设CHAR_BITS == 8,但这对大多数arch来说是合理的。

参见:https://en.cppreference.com/w/cpp/types/endian和https://en.cppreference.com/w/cpp/numeric/byteswap了解如何在将来做得更好。

在POSIX下,可以从<arpa/inet.h>使用ntohl

让我们来分析一下

*p++ // read a byte pointed to by a pointer and increment the pointer
(long)*p++ // cast that byte to a long
(long)*p++ << 24 // shift the bits of the long left (up) by 24 bits
s.i32 = (long)*p++ << 24; // assign the shifted bits to s.i32

所以整个过程取了一个字节,并把它放在32位整数的24到31位(最高的8位)上。

下一步

*p++ // read a byte pointed to by a pointer and increment the pointer
(long)*p++ // cast that byte to a long
(long)*p++ << 16 // shift the bits of the long left (up) by 16 bits
s.i32 |= (long)*p++ << 16; // combine the shifted bits with the existing contents of s.i32

因此,这一步读取了另一个字节,并将其放置在32位整数的16位到23位。因此,我们现在已经读取了32位整数的第16到31位。

我相信你可以自己解决剩下的问题。基本上,它只完成32位整数的0到15位。

相关内容

  • 没有找到相关文章

最新更新