如何在c中操纵整数类型的位?

时间:2013-05-28 11:46:44

标签: c casting bit-manipulation

我写了这个程序:

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

struct A {
  bool a;
  bool b;
  bool c;
  bool d;
};

struct B {
  int a;
};

int main() {
  struct A* pa = malloc( sizeof(struct A) );
  struct B* pb = (struct B*) pa;
  pa->a = 0;
  pa->b = 1;
  pa->c = 0;
  pa->d = 0;

  printf("value of pint is %i\n", pb->a);
  return 0;
}

我希望它打印2(0010)但是输出是256.任何一个云都有助于解释这段代码有什么问题?

5 个答案:

答案 0 :(得分:3)

  

我希望它打印2(0010)但是输出是256.任何一个云都有助于解释这段代码有什么问题?

bool占用至少一个字节。在你的情况下,显然只有一个字节,你的平台是little-endian(8位char)。因此,第二个(最低有效)字节为1,所有其他字节为0,使1*256

请注意,papb的类型惩罚违反了严格的别名。

使用union便携式输入双关语。

答案 1 :(得分:2)

初始化pa后,您有

*pa = { 0x00, 0x01, 0x00, 0x00 }

因为每个bool是一个字节。当你将它转换为int值时,你得到(在小端机器中)*pb

*pb = 0x00000100

显然是256。知道了吗?

如果需要,您可以将struct A定义为:

struct A {
  bool a:1;
  bool b:1;
  bool c:1;
  bool d:1;
};

但是不要将struct A的指针强加到struct B的指针,因为两个结构的大小都是不同的。

这可能对您将来有所帮助:

union A {
    struct {
    bool bit0:1;
    bool bit1:1;
    bool bit2:1;
    bool bit3:1;
    bool bit4:1;
    bool bit5:1;
    bool bit6:1;
    bool bit7:1;
    };
    unsigned char cByte;
};

通过定义,您可以按位或按字节访问它。

答案 2 :(得分:1)

%i打印一个整数。

bool是一个无符号整数类型,足以存储值0和1.

你可以这样打印bool:

printf("%d\n", b);

答案 3 :(得分:1)

您正在以小Endian表示法打印该数字。实际上,你打印的是:

0 * 256^0 + 1 * 256^1 + 0 * 256^2 + 0 * 256^3

如果您决定使用位域(如其他人所建议的那样),则应使用%x以十六进制打印。如果您严格要以二进制打印,则必须使用循环遍历各个位。

答案 4 :(得分:0)

尝试

struct A {
  bool a:1;
  bool b:1;
  bool c:1;
  bool d:1;
};

:1部分强制编译器为每个成员变量分配1位而不是1字节,因此struct A的内存布局看起来像这样(假设小端):

|-byte 1-|-byte 2-|-byte 3-|-byte 3-|
 uuuudcba uuuuuuuu uuuuuuuu uuuuuuuu

其中u捐赠未使用的。当将它转换为整数时,您将得到一个整数视图:

uuuuuuuu uuuuuuuu uuuuuuuu uuuudcba

由于不同编译器实现的位顺序不同,您也可能得到反转结果4(0100)而不是2(0010)