C 嵌套 union 和结构

标签 c struct unions

早上好,我正在尝试提出一种可以在不同应用程序中使用的数据结构,但作为相同类型传递给传输函数, 我目前正在使用 netbeans,但这将被转移到 dspic30f(16 位),

typedef union {

    union {

        struct {
            unsigned bit0 : 1;
            unsigned bit1 : 1;
            unsigned bit2 : 1;
            unsigned bit3 : 1;
            unsigned bit4 : 1;
            unsigned bit5 : 1;
            unsigned bit6 : 1;
            unsigned bit7 : 1;

            unsigned bit8 : 1;
            unsigned bit9 : 1;
            unsigned bit10 : 1;
            unsigned bit11 : 1;

            union {

                struct {
                    unsigned bit12 : 1;
                    unsigned bit13 : 1;
                    unsigned bit14 : 1;
                    unsigned bit15 : 1;
                };
                unsigned char value;
            } lastfour;

        };
        unsigned int value : 16;
    };

    union {

        struct {

            union {

                struct {
                    unsigned bit0 : 1;
                    unsigned bit1 : 1;
                    unsigned bit2 : 1;
                    unsigned bit3 : 1;
                };
                unsigned char value;
            } firstfour;

            unsigned bit4 : 1;
            unsigned bit5 : 1;
            unsigned bit6 : 1;
            unsigned bit7 : 1;

            unsigned bit8 : 1;
            unsigned bit9 : 1;
            unsigned bit10 : 1;
            unsigned bit11 : 1;
            unsigned bit12 : 1;
            unsigned bit13 : 1;
            unsigned bit14 : 1;
            unsigned bit15 : 1;


        };
        unsigned int value : 16;
    };

} foo;

然后我使用以下代码来检查功能。

int main(int argc, char** argv) {

     foo a;
     a.value =0;
     a.lastfour.value = 0xF;

     printf("%d", a.value);

     return (EXIT_SUCCESS);
 }

打印的值为 0,但是由于 union ,我的印象是两个结构共享相同的内存(16 位),因此在将“lastfour”设置为 0xF 之后,“值”现在应该为 0xF000。

任何人都可以就我做错了什么以及为什么“值”不读取包含“lastfour”的同一内存提供一些指导

最佳答案

首先,令我惊讶的是它甚至可以为您编译。您的 foo 类型中有两个匿名 union,并且它们具有重复的成员名称(bit4bit5 等) .).你的代码没有为我编译。您应该为两个 union 提供名称或重命名 bits,以免它们发生冲突。

其次,您的 union firstfourlastfour 最终可能是 8 位,而不是 4 位,因为 char 的最小大小是8 位。那会丢掉你所有的其他位。

第三, union firstfourlastfour 不会从内存中的第 12 位开始。它们将根据您的处理器的需要进行对齐,可能在下一个 2 字节或 4 字节偏移处。尝试在您的函数中打印 sizeof(foo) 。我保证您会看到 4 或 8,而不是您期望的 2。

第四,更大的尺寸是您在测试代码中看到值“0”的原因。前 16 位全为零。您设置的 0xF 要么在接下来的 16 位中,要么可能在接下来的 32 位中,具体取决于您的编译器对齐方式。

这是一个结构布局,应该适用于您正在尝试做的事情。我测试了它,它对我有用。将所有内容打包成 2 个字节。

typedef struct {
    union {
        struct {
            uint16_t firstfour  : 4;
            uint16_t secondfour : 4;
            uint16_t thirdfour  : 4;
            uint16_t lastfour   : 4;
        };
        /* EDIT - Duplicate structure with different member names
           added, in response to a comment below. */
        struct {
            uint16_t nibble1    : 4;
            uint16_t nibble2    : 4;
            uint16_t nibble3    : 4;
            uint16_t nibble4    : 4;
        };
        struct {
            uint16_t bit0  : 1;
            uint16_t bit1  : 1;
            uint16_t bit2  : 1;
            uint16_t bit3  : 1;
            uint16_t bit4  : 1;
            uint16_t bit5  : 1;
            uint16_t bit6  : 1;
            uint16_t bit7  : 1;
            uint16_t bit8  : 1;
            uint16_t bit9  : 1;
            uint16_t bit10 : 1;
            uint16_t bit11 : 1;
            uint16_t bit12 : 1;
            uint16_t bit13 : 1;
            uint16_t bit14 : 1;
            uint16_t bit15 : 1;
        };
        uint16_t value;
    };
} foo;

关于C 嵌套 union 和结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29165588/

相关文章:

c - 如何确定在 C 程序中执行的 x86 机器指令的数量?

c - 如何使 scanf 读取超过 4095 个字符作为输入?

c++ - 将值分配给原子用户定义结构的数组

json - 在字符串中插入一个变量

c++ - 这是 GCC 错误吗?使用 union 初始化结构

c - 以下 C 代码有什么问题 - 结构和指针

c++ - 我在哪里定义代码来释放在 C Python 模块 init 函数中分配的资源?

c++ - Sizeof 舍入对齐,但编译器仍将对象放置在剩余字节中

c++ - 如何为类 union 类编写析构函数

C++:包含类实例的 union 会调用错误的虚函数