共用体と構造体を使用した C でのビット フィールドの管理

導入

C 言語では、联合体(union) と结构体(struct) は、データのさまざまな表現を処理するために使用できる 2 つの強力なデータ型です。この記事では、共用体と構造体を使用してビット フィールド、特に 16 ビットおよび 32 ビットの符号なし整数を管理する方法について説明します。

連合

ユニオンは、異なるデータ型を同じメモリ位置に格納できるようにする特別なデータ構造です。これは、共用体のすべてのメンバーが同じメモリ空間を共有することを意味します。この例では、UNIO_U16という共用体を定義します。これには、16 ビット符号なし整数を格納するためのメンバーData_u16と、ビットごとのアクセスのための構造体メンバーが含まれていますBits構造体 Bits は、16 ビット整数の各ビットを表す 16 ビット フィールドを定義します。

typedef union 
{
    
    
    uint16_t Data_u16;
    struct  
    {
    
    
        uint16_t Bit0: 1;
        uint16_t Bit1: 1;
        // ...
        uint16_t Bit14: 1;
        uint16_t Bit15: 1;
    } Bits;
} UNIO_U16;

構造体 (構造体)

構造体は、異なるデータ型の複数の変数をカスタム データ型に結合する方法です。この例では、UNIO_U32という共用体を定義します。これには、32 ビット符号なし整数を格納するためのメンバーData_u32と、ビットごとのアクセスのための構造体メンバー Bits が含まれています。構造体 Bits は、32 ビット整数の各ビットを表す 32 ビット フィールドを定義します。

typedef union 
{
    
    
    uint32_t Data_u32;
    struct  
    {
    
    
        uint32_t Bit0: 1;
        uint32_t Bit1: 1;
        // ...
        uint32_t Bit30: 1;
        uint32_t Bit31: 1;
    } Bits;
} UNIO_U32;

共用体と構造体の使用例

共用体と構造体を使用すると、整数のさまざまなビットに簡単にアクセスできます。たとえば、16 ビット整数のビット 0 と 5 は次のコードで設定できます。

	UNIO_U16 u16;
	u16.Bits.Bit0 = 1;
	u16.Bits.Bit5 = 1;
	printf("u16.Data_u16 = %u\n", u16.Data_u16);

同様に、32 ビット整数のビット 0 と 10 を設定することもできます。

	UNIO_U32 u32;
	u32.Bits.Bit0 = 1;
	u32.Bits.Bit10 = 1;
	printf("u32.Data_u32 = %u\n", u32.Data_u32);

よく使用されるUNIO_U8、UNIO_U16、UNIO_U32のリファレンスサンプルコードを定義する

#include <stdio.h>

#if defined(__GNUC__) // GCC编译器
    #if __x86_64__ || __ppc64__ || __aarch64__ || __mips64 || _M_X64 // 64位编译器判断
        typedef unsigned char uint8_t;
        typedef unsigned short uint16_t;
        typedef unsigned int uint32_t;
    #else // 32位编译器
        typedef unsigned char uint8_t;
        typedef unsigned short uint16_t;
        typedef unsigned long uint32_t;
    #endif
#elif defined(_MSC_VER) // Microsoft Visual C++编译器
    #if defined(_WIN64) // 64位编译器判断
        typedef unsigned char uint8_t;
        typedef unsigned short uint16_t;
        typedef unsigned int uint32_t;
    #else // 32位编译器
        typedef unsigned char uint8_t;
        typedef unsigned short uint16_t;
        typedef unsigned long uint32_t;
    #endif
#else
    #error "Unsupported compiler. Please add compiler-specific checks."
#endif


typedef union 
{
    
    
    uint16_t Data_u16;
    struct  
    {
    
    
        uint8_t LowByte;
        uint8_t HighByte;
    } Bytes;
    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;
    } Bits;
} UNIO_U16;

typedef union 
{
    
    
    uint32_t Data_u32;
    struct  
    {
    
    
        uint16_t LowWord;
        uint16_t HighWord;
    } Words;
    
    struct  
    {
    
    
        uint8_t Byte0;
        uint8_t Byte1;
        uint8_t Byte2;
        uint8_t Byte3;
    } Bytes;
    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 Bit16: 1;
        uint16_t Bit17: 1;
        uint16_t Bit18: 1;
        uint16_t Bit19: 1;
        uint16_t Bit20: 1;
        uint16_t Bit21: 1;
        uint16_t Bit22: 1;
        uint16_t Bit23: 1;
        
        uint16_t Bit24: 1;
        uint16_t Bit25: 1;
        uint16_t Bit26: 1;
        uint16_t Bit27: 1;
        uint16_t Bit28: 1;
        uint16_t Bit29: 1;
        uint16_t Bit30: 1;
        uint16_t Bit31: 1;
    } Bits;
} UNIO_U32;

int main()
{
    
    
    UNIO_U16 u16;
    u16.Bits.Bit0 = 1;
    u16.Bits.Bit5 = 1;
    printf("u16.Data_u16 = %u\n", u16.Data_u16);

    UNIO_U32 u32;
    u32.Bits.Bit0 = 1;
    u32.Bits.Bit10 = 1;
    printf("u32.Data_u32 = %u\n", u32.Data_u32);

    return 0;
}

在上述代码中,我们定义了 UNIO_U16 和 UNIO_U32 两个联合体,每个联合体包含一个用于存储整数的成员(Data_u16 和 Data_u32) 以及一个用于按位访问的 Bits 结构体成员。可以根据需要设置每个位的值,并使用 printf 输出整数值。 注意在联合体中,各个成员共享同一段内存空间,因此根据对不同成员的赋值,联合体中存储的整数值也会发生相应的变化。

結論は

ユニオンと構造体は、C でデータを操作するための強力なツールです。ユニオンを使用してさまざまなタイプのデータを格納し、構造体を使用してビットフィールドを管理することで、データをより柔軟かつ効率的に操作できます。この手法は、組み込みシステムやハードウェア関連のプログラミング タスクを扱う場合に特に役立ちます。

おすすめ

転載: blog.csdn.net/qq_44330858/article/details/131842660