我一直试图理解位操作如何与C和指针一起工作,但没有运气。这是我的问题。我在内存中有8个字节,需要提取前61位并打印。例如:0000 0000 ..... 0010 0111,我需要提取值32(忽略64位的最后3位。)这在C中是如何工作的?我只有一个指向8字节开头的指针。
uint_64_t* myPointer; // already pointing to start of 8bytes
typedef struct Solve{
uint64_t myBytes: 64; // set a field thats equal to 64 bits
}
struct Solve s1;
s1.myBytes = *myPointer>>3; //failed attempt
printf("Bytes are %" PRIu64 "\n", s1.myBytes); // just prints out 0 when should be 32
如果您打算在清除3个低位的情况下打印64位值,请取值并使用除最低3位设置之外的位掩码执行逻辑AND:
uint64_t myvalue = 0x0123456789abcdefULL;
uint64_t masked_value = myvalue & 0xfffffffffffffff8ULL;
printf("Bytes are %" PRIx64 "\n", masked_value );
输出:
Bytes are 123456789abcde8
您需要清除64位变量中的低位3位。既然你对结构字段值的操作感兴趣,我已经包含了这样的例子。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#define B(x) S_to_binary_(#x)
typedef struct solve{
u_int64_t myBytes: 64; // field that has 64 bits
}Solve;
static inline unsigned long long S_to_binary_(const char *s)
{
unsigned long long i = 0;
while (*s) {
i <<= 1;
i += *s++ - '0';
}
return i;
}
int main(void)
{
u_int64_t mask = ~0; // This will give you 1111...1111
mask = mask<<3; // This will become 1111...1000
Solve * myPointer;
Solve s1; // declare the structure s1
s1.myBytes = B(100111); // init the myBytes to 38 (decimal)
printf("Initial value of s1.myBytes is: %lld\n", s1.myBytes);
myPointer = & s1; // cannot take address of bit-field 'myBytes' directly
myPointer->myBytes = (myPointer->myBytes & mask); // change the value of myBytes
printf("Now value of s1.myBytes is: %lld\n\n", s1.myBytes); // print new value
// more testing
uint64_t myvalue1 = 0x0123456789abcdefULL;
uint64_t myvalue = B(100111);
uint64_t masked_value1 = myvalue1 & mask; // This will clear low 3 bits
uint64_t masked_value = myvalue & mask; // This will clear low 3 bits
printf("Bytes are: %" PRIx64 "\n", masked_value1 );
printf("Value is: %lld\n", masked_value );
return 0;
}
输出:
Initial value of s1.myBytes is: 39
Now value of s1.myBytes is: 32
Bytes are: 123456789abcde8
Value is: 32
如果这些例子可以解决您的问题,请告诉我。