解码C语言复合数据类型之联合体与枚举

联合体 (Union) - “多功能存储盒”

核心概念

联合体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。所有成员共享同一块内存空间。

内存模型演示

内存地址: 0x1000  0x1001  0x1002  0x1003  0x1004  0x1005  0x1006  0x1007
          ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┐
使用 int:  │  字节0 │  字节1 │  字节2 │  字节3 │       │       │       │       │
          └───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┘

          ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┐
使用 double: │  字节0 │  字节1 │  字节2 │  字节3 │  字节4 │  字节5 │  字节6 │  字节7 │
          └───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┘

基本特征

  • 内存共享:所有成员共用同一内存块
  • 尺寸最大:联合体大小 = 最大成员的大小 + 内存对齐
  • 互斥访问:同一时刻只有一个成员有效
  • 覆盖效应:赋值新成员会覆盖旧成员的值

定义与声明

// 外部定义联合体类型 DataBox(全局可见)
union DataBox {
    int number;      // 整型成员
    char letter;     // 字符型成员
    double value;    // 双精度浮点型成员
    char text[20];   // 字符数组成员
};

int main() {
    // 声明外部定义的 DataBox 类型变量
    union DataBox box;
    // 可以对 box 赋值(示例)
    box.number = 100;         // 赋值整型成员
    printf("box.number = %d\n", box.number);


    // 若需要在 main 内定义新的联合体,需使用不同的类型名(避免冲突)
    union DataBoxInner {  // 新类型名:DataBoxInner(与外部 DataBox 不重复)
        int num;          // 新联合体的整型成员
        char ch;          // 新联合体的字符成员
    } box1, box2;         // 声明新类型的变量 box1、box2

    // 对新联合体变量赋值(示例)
    box1.ch = 'A';        // 给 box1 的字符成员赋值
    printf("box1.ch = %c\n", box1.ch);

    box2.num = 200;       // 给 box2 的整型成员赋值
    printf("box2.num = %d\n", box2.num);


    return 0;
}

操作示例

联合体成员共用同一块内存,但数据有效性取决于赋值操作:未赋值时,内存中是随机数据,任何成员解读都无意义(状态未定义);只有最后一次被赋值的成员,因其数据是按自身类型写入的,才能正确解读内存内容,成为可安全访问的有效成员。

#include <stdio.h>
#include <string.h>
union Data {
    int i;
    float f;
    char str[20];
};

int main() {
    union Data data;

	// 使用整数成员
    data.i = 10;
    printf("data.i : %d\n", data.i);

	// 使用浮点成员(会覆盖整数)
    data.f = 220.5;
    printf("data.f : %.2f\n", data.f);

	// 使用字符串成员(会覆盖浮点数)
	strcpy(data.str, "C Programming");
	printf("data.str : %s\n", data.str);

    return 0;
}

联合体的高级用法:标签联合体 (Tagged Union)

概念

标签联合体 = 类型标签 + 联合体,用于安全地处理多种数据类型。

// 定义数据类型标签
#define TYPE_INT 1
#define TYPE_FLOAT 2
#define TYPE_STRING 3// 标签联合体结构
struct TaggedData {
    int type_tag;// 类型标签,指示当前有效的数据类型
    union {
        int int_data;// 整型数据
        float float_data;// 浮点数据
        char string_data[50];// 字符串数据
	} value;// 联合体存储实际数据
};

完整示例

#include <stdio.h>
#include <string.h>
#define TYPE_INT 1
#define TYPE_FLOAT 2
#define TYPE_STRING 3
struct Variant{
    int type;
    union {
        int i;
        float f;
        char s[20];
    } data;
};

void printVariant(struct Variant v) {
    switch(v.type) {
        case TYPE_INT:
            printf("Integer: %d\n", v.data.i);
            break;
        case TYPE_FLOAT:
            printf("Float: %.2f\n", v.data.f);
            break;
        case TYPE_STRING:
            printf("String: %s\n", v.data.s);
            break;
        default:
            printf("Unknown type\n");
    }
}

int main() {
    struct Variant var;

	// 存储整数
    var.type = TYPE_INT;
    var.data.i = 100;
    printVariant(var);

	// 存储浮点数
    var.type = TYPE_FLOAT;
    var.data.f = 3.14;
    printVariant(var);

	// 存储字符串
    var.type = TYPE_STRING;
    strcpy(var.data.s, "Hello Union");
    printVariant(var);

    return 0;
}

枚举 (Enum) - “有名字的数字”

基本概念

枚举为整数值提供有意义的名称,提高代码可读性和可维护性。

定义与使用

// 定义枚举类型
enum Weekday {
    MONDAY,// 默认为0
    TUESDAY,// 自动加1
    WEDNESDAY,// 2
    THURSDAY,// 3
    FRIDAY,// 4
    SATURDAY,// 5
    SUNDAY// 6
};

// 自定义枚举值
enum Status {
    OFF = 0,
    ON = 1,
    STANDBY = 2
};

// 部分自定义
enum Color {
    RED,// 0
    GREEN = 5,//如果赋值,下一个元素的值会从当前值累加
    BLUE,// 6
    YELLOW = 10
};

枚举变量操作

// 匿名枚举 + typedef 一步定义类型别名
typedef enum { RED, YELLOW, GREEN } TrafficLight;

int main() {
    TrafficLight light = GREEN;  // 直接用简化后的类型名声明变量
    switch(light) {
        case RED:
            printf("Stop!\n");
            break;
        case YELLOW:
            printf("Caution!\n");
            break;
        case GREEN:
            printf("Go!\n");
            break;
        default:
            break;
    }

    printf("RED = %d, GREEN = %d\n", RED, GREEN);

    return 0;
}

核心思想:联合体用于数据存储的多样性,枚举用于代码逻辑的清晰性

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值