C struct,union指向struct的指针

时间:2013-08-08 10:56:20

标签: c pointers casting struct unions

我有一个typedeffed结构和一个联合。 union包含结构和单个uint32_t。目标是为foo分配一个与结构中“位”对应的值。

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

typedef struct {
    uint32_t valA :1;
    uint32_t valB :1;
    uint32_t valC :1;
    uint32_t valD :1;
    uint32_t valE :1;
} ValStruct_Type;

typedef union {
    ValStruct_Type valStruct;
    uint32_t valUint;
} ValUnion_Type;

uint32_t foo = 0;


int main(void)
{
    ValStruct_Type Vals;
    Vals.valA = 0x0;
    Vals.valB = 0x1;
    Vals.valC = 0x0;
    Vals.valD = 0x1;
    Vals.valE = 0x1;

    ValStruct_Type *Vals_ptr;
    Vals_ptr = &Vals;

    foo = ((ValUnion_Type *)Vals_ptr)->valUint;

    return 0;
}

foo变成:

Decimal:    4194330
Hex:        0x40001a
Binary:     10000000000000000011010

谁可以准确地解释这里发生的事情(指向结构指针的联合指针,与联盟成员相关?)?

其次:除了第1,3和4位之外,为什么foo的第22位设置?

2 个答案:

答案 0 :(得分:2)

由于未定义的行为,设置了位22。您已经创建了一个从未完全初始化的局部变量,然后设置了5位。剩下的比特是他们碰巧发生的事情,未初始化的本地人就是这种情况。

关于你问题的第一部分......有什么不清楚的?你的问题(union pointer to a struct pointer, defererenced to a union member)似乎已经回答了。将某些内容转换为它已经存在的类型没有任何效果。

答案 1 :(得分:1)

定义联合时,指示编译器为任何适合其任一成员的实例保留足够的内存。

当你输入一个位域时,它被填充到某个字节大小(通常为4或8个字节,但在你的小例子中可能是1个字节)。

由于你只为你的struct分配了足够的内存(用sizeof(ValStruct_Type)检查),然后将它转换为一个占用更多内存的联合,你就会得到未定义的行为。

无论填充的那部分是什么,都会被复制到foo

你所做的大致等于

char a = 0x1a;
int foo = *(int *)&a;

要获得正确的行为

  • 分配联盟
  • 初始化
  • 然后开始设置你的位域。