0

我写了这个程序:

#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。任何一个云帮助说明这段代码有什么问题?

4

5 回答 5

3

我希望它打印 2 (0010),但输出是 256。任何一个云帮助说明这段代码有什么问题?

Abool占用至少一个字节。在您的情况下,显然恰好是一个字节,并且您的平台是 little-endian (使用 8-bit char)。所以第二个(最低有效)字节为 1,所有其他字节为 0,使得1*256.

请注意,类型双关语通过paandpb违反了严格的别名。

使用 aunion可移植的双关语。

于 2013-05-28T11:49:44.777 回答
2

初始化后pa,你有

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

因为每个布尔值都是一个字节。当您将其类型转换为 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;
};

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

于 2013-05-28T12:02:38.233 回答
1

%i 打印一个整数。

bool 是一个足够大的无符号整数类型,可以存储值 0 和 1。

你可以这样打印一个布尔值:

printf("%d\n", b);
于 2013-05-28T11:50:08.577 回答
1

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

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

如果您决定使用位域(如其他人所建议的那样),您应该使用%x以十六进制打印。如果您严格希望以二进制形式打印,则必须使用遍历各个位的循环来执行此操作。

于 2013-05-28T11:52:14.850 回答
0

尝试

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

部分:1强制编译器为每个成员变量分配 1 位而不是 1 字节,因此结构 A 的内存布局将如下所示(假设小端):

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

在哪里u捐赠未使用的。将其转换为整数时,您将获得以下整数视图:

uuuuuuuu uuuuuuuu uuuuuuuu uuuudcba

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

于 2013-05-28T11:49:20.103 回答