C&C++快速入门

16、结构体联合体与枚举

1、课程目标

  • 掌握结构体的定义和使用
  • 理解内存对齐和填充
  • 掌握联合体和枚举类型
  • 了解位域的使用

2、名词解释

术语 说明
结构体 自定义的复合数据类型
联合体 成员共享内存的数据类型
枚举 命名的整数常量集合
内存对齐 按特定边界放置数据
填充字节 为对齐添加的字节
位域 按位存储的结构体成员

3、代码实现

1. 结构体基础

#include <stdio.h>
#include <string.h>

// 结构体定义
struct Person {
    char name[32];
    int age;
    float height;
};

// typedef简化
typedef struct {
    int x;
    int y;
} Point;

int main() {
    printf("=== 结构体 ===\n\n");
    
    // 初始化
    struct Person p1 = {"Alice", 25, 165.5f};
    Point pt = {100, 200};
    
    // 访问成员
    printf("姓名: %s\n", p1.name);
    printf("年龄: %d\n", p1.age);
    printf("坐标: (%d, %d)\n", pt.x, pt.y);
    
    // 结构体指针
    struct Person* pp = &p1;
    printf("\n通过指针: %s, %d\n", pp->name, pp->age);
    
    // 结构体大小
    printf("\nsizeof(Person) = %d\n", (int)sizeof(struct Person));
    
    return 0;
}

2. 内存对齐

#include <stdio.h>

#pragma pack(push, 1)  // 1字节对齐
struct Packed {
    char a;
    int b;
    char c;
};
#pragma pack(pop)

struct Aligned {
    char a;
    int b;
    char c;
};

int main() {
    printf("=== 内存对齐 ===\n\n");
    
    printf("Packed大小: %d\n", (int)sizeof(struct Packed));   // 6
    printf("Aligned大小: %d\n", (int)sizeof(struct Aligned)); // 12
    
    return 0;
}

3. 联合体

#include <stdio.h>

union Data {
    int i;
    float f;
    char bytes[4];
};

int main() {
    printf("=== 联合体 ===\n\n");
    
    union Data d;
    d.i = 0x41424344;  // "DCBA"
    
    printf("大小: %d\n", (int)sizeof(d));
    printf("整数: 0x%08X\n", d.i);
    printf("字节: %c %c %c %c\n", 
           d.bytes[0], d.bytes[1], d.bytes[2], d.bytes[3]);
    
    return 0;
}

4. 枚举

#include <stdio.h>

typedef enum {
    STATUS_OK = 0,
    STATUS_ERROR = -1,
    STATUS_PENDING = 1,
    STATUS_TIMEOUT = 2
} Status;

const char* GetStatusName(Status s) {
    switch (s) {
        case STATUS_OK: return "OK";
        case STATUS_ERROR: return "Error";
        case STATUS_PENDING: return "Pending";
        case STATUS_TIMEOUT: return "Timeout";
        default: return "Unknown";
    }
}

int main() {
    printf("=== 枚举 ===\n\n");
    
    Status s = STATUS_OK;
    printf("状态: %s (%d)\n", GetStatusName(s), s);
    
    s = STATUS_TIMEOUT;
    printf("状态: %s (%d)\n", GetStatusName(s), s);
    
    return 0;
}

5、课后作业

5.1、作业1:实现链表节点

定义一个链表节点结构体并实现基本操作。

5.2、作业2:使用联合体解析IP地址

将DWORD类型的IP地址解析为4个字节。