每日一个C语言知识:C 结构体

C语言结构体详解

1. 什么是结构体?

结构体是一种用户定义的数据类型,它允许我们将多个不同类型的数据项组合成一个单一的复合数据类型。结构体是C语言中实现面向对象编程思想的基础。

结构体的主要用途

  • 组织相关数据
  • 创建复杂的数据结构
  • 实现面向对象的概念
  • 提高代码的可读性和可维护性

2. 结构体的基本概念

C语言结构体 结构体定义 结构体变量 结构体数组 结构体指针 嵌套结构体 成员变量 数据类型组合 声明和初始化 成员访问 多个结构体实例 动态内存分配 函数参数传递 复杂数据结构


3. 结构体的定义和声明

基本结构体定义
c 复制代码
#include <stdio.h>
#include <string.h>

// 定义结构体类型
struct Student {
    char name[50];
    int age;
    float score;
    char grade;
};  // 注意:这里需要分号

// 定义结构体类型并声明变量
struct Point {
    int x;
    int y;
} point1, point2;  // 同时声明变量

// 使用typedef简化结构体类型名
typedef struct {
    char title[100];
    char author[50];
    float price;
    int pages;
} Book;

int main() {
    printf("=== 结构体定义和声明 ===\n");
    
    // 声明结构体变量
    struct Student student1;
    Book book1;
    
    // 初始化结构体成员
    strcpy(student1.name, "张三");
    student1.age = 20;
    student1.score = 85.5;
    student1.grade = 'B';
    
    strcpy(book1.title, "C语言程序设计");
    strcpy(book1.author, "李四");
    book1.price = 59.9;
    book1.pages = 350;
    
    // 访问结构体成员
    printf("学生信息:\n");
    printf("姓名: %s\n", student1.name);
    printf("年龄: %d\n", student1.age);
    printf("分数: %.1f\n", student1.score);
    printf("等级: %c\n", student1.grade);
    
    printf("\n图书信息:\n");
    printf("书名: %s\n", book1.title);
    printf("作者: %s\n", book1.author);
    printf("价格: %.2f\n", book1.price);
    printf("页数: %d\n", book1.pages);
    
    return 0;
}
结构体的初始化方式
c 复制代码
#include <stdio.h>
#include <string.h>

// 定义结构体
typedef struct {
    char name[50];
    int id;
    float salary;
    char department[30];
} Employee;

int main() {
    printf("=== 结构体初始化方式 ===\n");
    
    // 方式1:声明后逐个初始化
    Employee emp1;
    strcpy(emp1.name, "王五");
    emp1.id = 1001;
    emp1.salary = 8000.0;
    strcpy(emp1.department, "技术部");
    
    // 方式2:声明时初始化(按定义顺序)
    Employee emp2 = {"李四", 1002, 7500.0, "市场部"};
    
    // 方式3:指定成员初始化(C99标准)
    Employee emp3 = {
        .name = "赵六",
        .department = "财务部",
        .id = 1003,
        .salary = 9000.0
    };
    
    // 方式4:部分初始化(未指定的成员自动初始化为0)
    Employee emp4 = {.name = "钱七", .id = 1004};
    
    // 显示员工信息
    Employee employees[] = {emp1, emp2, emp3, emp4};
    int count = sizeof(employees) / sizeof(employees[0]);
    
    printf("员工列表:\n");
    printf("%-10s %-8s %-10s %-12s\n", "姓名", "工号", "工资", "部门");
    printf("--------------------------------------------\n");
    
    for (int i = 0; i < count; i++) {
        printf("%-10s %-8d %-10.2f %-12s\n",
               employees[i].name,
               employees[i].id,
               employees[i].salary,
               employees[i].department);
    }
    
    return 0;
}

4. 结构体数组

基本结构体数组操作
c 复制代码
#include <stdio.h>
#include <string.h>

// 定义学生结构体
typedef struct {
    char name[50];
    int student_id;
    float grades[3];  // 三门课程成绩
    float average;
} Student;

// 函数声明
void inputStudent(Student *student);
void calculateAverage(Student *student);
void printStudent(const Student *student);
void printAllStudents(const Student students[], int count);

int main() {
    printf("=== 结构体数组操作 ===\n");
    
    const int STUDENT_COUNT = 3;
    Student students[STUDENT_COUNT];
    
    // 输入学生信息
    printf("请输入%d个学生的信息:\n", STUDENT_COUNT);
    for (int i = 0; i < STUDENT_COUNT; i++) {
        printf("\n学生 %d:\n", i + 1);
        inputStudent(&students[i]);
        calculateAverage(&students[i]);
    }
    
    // 显示所有学生信息
    printf("\n=== 学生信息汇总 ===\n");
    printAllStudents(students, STUDENT_COUNT);
    
    // 查找平均分最高的学生
    int top_index = 0;
    for (int i = 1; i < STUDENT_COUNT; i++) {
        if (students[i].average > students[top_index].average) {
            top_index = i;
        }
    }
    
    printf("\n=== 优秀学生 ===\n");
    printf("平均分最高的学生:\n");
    printStudent(&students[top_index]);
    
    return 0;
}

// 输入学生信息
void inputStudent(Student *student) {
    printf("姓名: ");
    scanf("%s", student->name);
    printf("学号: ");
    scanf("%d", &student->student_id);
    printf("三门课程成绩: ");
    scanf("%f %f %f", 
          &student->grades[0], 
          &student->grades[1], 
          &student->grades[2]);
}

// 计算平均分
void calculateAverage(Student *student) {
    float sum = 0;
    for (int i = 0; i < 3; i++) {
        sum += student->grades[i];
    }
    student->average = sum / 3;
}

// 打印单个学生信息
void printStudent(const Student *student) {
    printf("姓名: %s\n", student->name);
    printf("学号: %d\n", student->student_id);
    printf("成绩: %.1f, %.1f, %.1f\n", 
           student->grades[0], student->grades[1], student->grades[2]);
    printf("平均分: %.2f\n", student->average);
}

// 打印所有学生信息
void printAllStudents(const Student students[], int count) {
    printf("%-10s %-8s %-15s %-8s\n", 
           "姓名", "学号", "成绩", "平均分");
    printf("----------------------------------------\n");
    
    for (int i = 0; i < count; i++) {
        printf("%-10s %-8d %.1f,%.1f,%.1f %-8.2f\n",
               students[i].name,
               students[i].student_id,
               students[i].grades[0],
               students[i].grades[1],
               students[i].grades[2],
               students[i].average);
    }
}

5. 结构体指针

结构体指针的基本操作
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义产品结构体
typedef struct {
    int id;
    char name[50];
    float price;
    int stock;
} Product;

// 函数声明
void printProduct(const Product *product);
void updatePrice(Product *product, float new_price);
void restock(Product *product, int quantity);
Product* createProduct(int id, const char *name, float price, int stock);

int main() {
    printf("=== 结构体指针操作 ===\n");
    
    // 创建结构体变量
    Product product1 = {1, "笔记本电脑", 5999.0, 10};
    
    // 创建结构体指针
    Product *ptr = &product1;
    
    printf("通过变量访问:\n");
    printProduct(&product1);
    
    printf("\n通过指针访问:\n");
    printProduct(ptr);
    
    // 通过指针修改结构体成员
    printf("\n=== 修改产品信息 ===\n");
    updatePrice(ptr, 5499.0);
    restock(ptr, 5);
    
    printf("修改后的产品信息:\n");
    printProduct(ptr);
    
    // 动态创建结构体
    printf("\n=== 动态创建结构体 ===\n");
    Product *dynamic_product = createProduct(2, "智能手机", 2999.0, 20);
    if (dynamic_product != NULL) {
        printProduct(dynamic_product);
        free(dynamic_product);  // 释放内存
    }
    
    return 0;
}

// 打印产品信息
void printProduct(const Product *product) {
    printf("产品ID: %d\n", product->id);
    printf("产品名称: %s\n", product->name);
    printf("价格: ¥%.2f\n", product->price);
    printf("库存: %d\n", product->stock);
}

// 更新价格
void updatePrice(Product *product, float new_price) {
    product->price = new_price;
    printf("价格已更新为: ¥%.2f\n", new_price);
}

// 补货
void restock(Product *product, int quantity) {
    product->stock += quantity;
    printf("已补货 %d 件,当前库存: %d\n", quantity, product->stock);
}

// 动态创建产品
Product* createProduct(int id, const char *name, float price, int stock) {
    Product *product = (Product*)malloc(sizeof(Product));
    if (product != NULL) {
        product->id = id;
        strcpy(product->name, name);
        product->price = price;
        product->stock = stock;
    }
    return product;
}
结构体指针与数组
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STUDENTS 5

typedef struct {
    char name[50];
    int score;
} Student;

// 函数声明
void initializeStudents(Student *students, int count);
void sortStudentsByScore(Student *students, int count);
void printStudents(const Student *students, int count);

int main() {
    printf("=== 结构体指针与数组 ===\n");
    
    Student students[MAX_STUDENTS];
    Student *ptr = students;  // 指向数组的指针
    
    // 初始化学生数据
    initializeStudents(ptr, MAX_STUDENTS);
    
    printf("排序前:\n");
    printStudents(ptr, MAX_STUDENTS);
    
    // 按成绩排序
    sortStudentsByScore(ptr, MAX_STUDENTS);
    
    printf("\n按成绩排序后:\n");
    printStudents(ptr, MAX_STUDENTS);
    
    // 使用指针遍历数组
    printf("\n使用指针遍历:\n");
    printf("%-15s %-10s\n", "姓名", "成绩");
    printf("---------------------\n");
    
    Student *current = students;
    for (int i = 0; i < MAX_STUDENTS; i++) {
        printf("%-15s %-10d\n", current->name, current->score);
        current++;  // 移动到下一个结构体
    }
    
    return 0;
}

// 初始化学生数据
void initializeStudents(Student *students, int count) {
    const char *names[] = {"张三", "李四", "王五", "赵六", "钱七"};
    const int scores[] = {85, 92, 78, 65, 88};
    
    for (int i = 0; i < count; i++) {
        strcpy(students[i].name, names[i]);
        students[i].score = scores[i];
    }
}

// 按成绩排序(冒泡排序)
void sortStudentsByScore(Student *students, int count) {
    for (int i = 0; i < count - 1; i++) {
        for (int j = 0; j < count - i - 1; j++) {
            if (students[j].score < students[j + 1].score) {
                // 交换结构体
                Student temp = students[j];
                students[j] = students[j + 1];
                students[j + 1] = temp;
            }
        }
    }
}

// 打印学生信息
void printStudents(const Student *students, int count) {
    printf("%-15s %-10s\n", "姓名", "成绩");
    printf("---------------------\n");
    
    for (int i = 0; i < count; i++) {
        printf("%-15s %-10d\n", students[i].name, students[i].score);
    }
}

6. 结构体与函数

结构体作为函数参数
c 复制代码
#include <stdio.h>
#include <math.h>

// 定义二维点结构体
typedef struct {
    double x;
    double y;
} Point;

// 定义矩形结构体
typedef struct {
    Point top_left;
    Point bottom_right;
} Rectangle;

// 函数声明
double calculateDistance(const Point *p1, const Point *p2);
double calculateArea(const Rectangle *rect);
void printPoint(const Point *point);
void printRectangle(const Rectangle *rect);
void movePoint(Point *point, double dx, double dy);
void scaleRectangle(Rectangle *rect, double factor);

int main() {
    printf("=== 结构体与函数 ===\n");
    
    // 创建点
    Point p1 = {0, 0};
    Point p2 = {3, 4};
    
    printf("点坐标:\n");
    printPoint(&p1);
    printPoint(&p2);
    
    // 计算两点距离
    double distance = calculateDistance(&p1, &p2);
    printf("两点距离: %.2f\n", distance);
    
    // 创建矩形
    Rectangle rect = {{1, 1}, {4, 3}};
    
    printf("\n矩形信息:\n");
    printRectangle(&rect);
    
    // 计算矩形面积
    double area = calculateArea(&rect);
    printf("矩形面积: %.2f\n", area);
    
    // 移动点
    printf("\n=== 移动点 ===\n");
    movePoint(&p1, 2, 3);
    printPoint(&p1);
    
    // 缩放矩形
    printf("\n=== 缩放矩形 ===\n");
    scaleRectangle(&rect, 1.5);
    printRectangle(&rect);
    area = calculateArea(&rect);
    printf("缩放后面积: %.2f\n", area);
    
    return 0;
}

// 计算两点距离
double calculateDistance(const Point *p1, const Point *p2) {
    double dx = p1->x - p2->x;
    double dy = p1->y - p2->y;
    return sqrt(dx * dx + dy * dy);
}

// 计算矩形面积
double calculateArea(const Rectangle *rect) {
    double width = fabs(rect->bottom_right.x - rect->top_left.x);
    double height = fabs(rect->bottom_right.y - rect->top_left.y);
    return width * height;
}

// 打印点坐标
void printPoint(const Point *point) {
    printf("点: (%.2f, %.2f)\n", point->x, point->y);
}

// 打印矩形信息
void printRectangle(const Rectangle *rect) {
    printf("矩形: 左上角(%.2f, %.2f), 右下角(%.2f, %.2f)\n",
           rect->top_left.x, rect->top_left.y,
           rect->bottom_right.x, rect->bottom_right.y);
}

// 移动点
void movePoint(Point *point, double dx, double dy) {
    point->x += dx;
    point->y += dy;
    printf("点移动到: (%.2f, %.2f)\n", point->x, point->y);
}

// 缩放矩形
void scaleRectangle(Rectangle *rect, double factor) {
    // 计算中心点
    double center_x = (rect->top_left.x + rect->bottom_right.x) / 2;
    double center_y = (rect->top_left.y + rect->bottom_right.y) / 2;
    
    // 缩放
    rect->top_left.x = center_x + (rect->top_left.x - center_x) * factor;
    rect->top_left.y = center_y + (rect->top_left.y - center_y) * factor;
    rect->bottom_right.x = center_x + (rect->bottom_right.x - center_x) * factor;
    rect->bottom_right.y = center_y + (rect->bottom_right.y - center_y) * factor;
    
    printf("矩形缩放 %.1f 倍\n", factor);
}
结构体作为函数返回值
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义复数结构体
typedef struct {
    double real;
    double imag;
} Complex;

// 函数声明
Complex createComplex(double real, double imag);
Complex addComplex(const Complex *c1, const Complex *c2);
Complex multiplyComplex(const Complex *c1, const Complex *c2);
void printComplex(const Complex *c);
Complex* createComplexArray(int size);

int main() {
    printf("=== 结构体作为函数返回值 ===\n");
    
    // 创建复数
    Complex c1 = createComplex(3, 4);
    Complex c2 = createComplex(1, -2);
    
    printf("复数1: ");
    printComplex(&c1);
    printf("复数2: ");
    printComplex(&c2);
    
    // 复数加法
    Complex sum = addComplex(&c1, &c2);
    printf("加法结果: ");
    printComplex(&sum);
    
    // 复数乘法
    Complex product = multiplyComplex(&c1, &c2);
    printf("乘法结果: ");
    printComplex(&product);
    
    // 创建复数数组
    printf("\n=== 复数数组 ===\n");
    int array_size = 3;
    Complex *complex_array = createComplexArray(array_size);
    
    if (complex_array != NULL) {
        for (int i = 0; i < array_size; i++) {
            printf("复数[%d]: ", i);
            printComplex(&complex_array[i]);
        }
        free(complex_array);
    }
    
    return 0;
}

// 创建复数
Complex createComplex(double real, double imag) {
    Complex c;
    c.real = real;
    c.imag = imag;
    return c;
}

// 复数加法
Complex addComplex(const Complex *c1, const Complex *c2) {
    Complex result;
    result.real = c1->real + c2->real;
    result.imag = c1->imag + c2->imag;
    return result;
}

// 复数乘法
Complex multiplyComplex(const Complex *c1, const Complex *c2) {
    Complex result;
    result.real = c1->real * c2->real - c1->imag * c2->imag;
    result.imag = c1->real * c2->imag + c1->imag * c2->real;
    return result;
}

// 打印复数
void printComplex(const Complex *c) {
    if (c->imag >= 0) {
        printf("%.2f + %.2fi\n", c->real, c->imag);
    } else {
        printf("%.2f - %.2fi\n", c->real, -c->imag);
    }
}

// 创建复数数组
Complex* createComplexArray(int size) {
    Complex *array = (Complex*)malloc(size * sizeof(Complex));
    if (array != NULL) {
        for (int i = 0; i < size; i++) {
            array[i] = createComplex(i + 1, (i + 1) * 0.5);
        }
    }
    return array;
}

7. 嵌套结构体

复杂嵌套结构体
c 复制代码
#include <stdio.h>
#include <string.h>

// 定义地址结构体
typedef struct {
    char street[100];
    char city[50];
    char state[50];
    char zip_code[20];
} Address;

// 定义联系人结构体
typedef struct {
    char name[50];
    char phone[20];
    char email[100];
} Contact;

// 定义员工结构体(嵌套结构体)
typedef struct {
    int employee_id;
    char name[50];
    char department[50];
    float salary;
    Address address;    // 嵌套地址结构体
    Contact contact;    // 嵌套联系人结构体
} Employee;

// 函数声明
void printAddress(const Address *addr);
void printContact(const Contact *contact);
void printEmployee(const Employee *emp);
void promoteEmployee(Employee *emp, const char *new_dept, float salary_raise);

int main() {
    printf("=== 嵌套结构体 ===\n");
    
    // 创建员工实例
    Employee emp1 = {
        .employee_id = 1001,
        .name = "张三",
        .department = "技术部",
        .salary = 8000.0,
        .address = {
            .street = "科技路123号",
            .city = "北京",
            .state = "北京市",
            .zip_code = "100000"
        },
        .contact = {
            .name = "张三",
            .phone = "13800138000",
            .email = "zhangsan@company.com"
        }
    };
    
    Employee emp2 = {
        1002,
        "李四",
        "市场部",
        7000.0,
        {"商业街456号", "上海", "上海市", "200000"},
        {"李四", "13900139000", "lisi@company.com"}
    };
    
    // 显示员工信息
    printf("员工1信息:\n");
    printEmployee(&emp1);
    
    printf("\n员工2信息:\n");
    printEmployee(&emp2);
    
    // 晋升员工
    printf("\n=== 员工晋升 ===\n");
    promoteEmployee(&emp2, "高级市场部", 2000.0);
    printEmployee(&emp2);
    
    return 0;
}

// 打印地址信息
void printAddress(const Address *addr) {
    printf("地址: %s, %s, %s %s\n", 
           addr->street, addr->city, addr->state, addr->zip_code);
}

// 打印联系人信息
void printContact(const Contact *contact) {
    printf("联系人: %s\n", contact->name);
    printf("电话: %s\n", contact->phone);
    printf("邮箱: %s\n", contact->email);
}

// 打印员工信息
void printEmployee(const Employee *emp) {
    printf("员工ID: %d\n", emp->employee_id);
    printf("姓名: %s\n", emp->name);
    printf("部门: %s\n", emp->department);
    printf("工资: ¥%.2f\n", emp->salary);
    printAddress(&emp->address);
    printContact(&emp->contact);
}

// 晋升员工
void promoteEmployee(Employee *emp, const char *new_dept, float salary_raise) {
    strcpy(emp->department, new_dept);
    emp->salary += salary_raise;
    printf("%s 晋升到 %s,工资增加 ¥%.2f\n", 
           emp->name, new_dept, salary_raise);
}

8. 实际应用示例

示例1:学生成绩管理系统
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_COURSES 5
#define MAX_STUDENTS 100

// 定义课程结构体
typedef struct {
    char course_name[50];
    float score;
    char grade;
} Course;

// 定义学生结构体
typedef struct {
    int student_id;
    char name[50];
    int age;
    Course courses[MAX_COURSES];
    int course_count;
    float gpa;
} Student;

// 函数声明
void initializeStudent(Student *student, int id, const char *name, int age);
void addCourse(Student *student, const char *course_name, float score);
void calculateGPA(Student *student);
char calculateGrade(float score);
void printStudent(const Student *student);
void printAllStudents(Student students[], int count);

int main() {
    printf("=== 学生成绩管理系统 ===\n");
    
    Student students[MAX_STUDENTS];
    int student_count = 0;
    
    // 初始化几个学生
    initializeStudent(&students[student_count], 1001, "张三", 20);
    addCourse(&students[student_count], "数学", 85.5);
    addCourse(&students[student_count], "英语", 92.0);
    addCourse(&students[student_count], "编程", 88.5);
    student_count++;
    
    initializeStudent(&students[student_count], 1002, "李四", 21);
    addCourse(&students[student_count], "数学", 78.0);
    addCourse(&students[student_count], "英语", 85.5);
    addCourse(&students[student_count], "编程", 92.5);
    student_count++;
    
    initializeStudent(&students[student_count], 1003, "王五", 22);
    addCourse(&students[student_count], "数学", 95.0);
    addCourse(&students[student_count], "英语", 89.5);
    addCourse(&students[student_count], "编程", 94.0);
    student_count++;
    
    // 显示所有学生信息
    printf("=== 所有学生信息 ===\n");
    printAllStudents(students, student_count);
    
    // 查找GPA最高的学生
    int top_index = 0;
    for (int i = 1; i < student_count; i++) {
        if (students[i].gpa > students[top_index].gpa) {
            top_index = i;
        }
    }
    
    printf("\n=== GPA最高学生 ===\n");
    printStudent(&students[top_index]);
    
    return 0;
}

// 初始化学生
void initializeStudent(Student *student, int id, const char *name, int age) {
    student->student_id = id;
    strcpy(student->name, name);
    student->age = age;
    student->course_count = 0;
    student->gpa = 0.0;
}

// 添加课程
void addCourse(Student *student, const char *course_name, float score) {
    if (student->course_count < MAX_COURSES) {
        Course *course = &student->courses[student->course_count];
        strcpy(course->course_name, course_name);
        course->score = score;
        course->grade = calculateGrade(score);
        student->course_count++;
        
        // 重新计算GPA
        calculateGPA(student);
    }
}

// 计算GPA
void calculateGPA(Student *student) {
    float total_score = 0;
    for (int i = 0; i < student->course_count; i++) {
        total_score += student->courses[i].score;
    }
    student->gpa = total_score / student->course_count;
}

// 计算等级
char calculateGrade(float score) {
    if (score >= 90) return 'A';
    if (score >= 80) return 'B';
    if (score >= 70) return 'C';
    if (score >= 60) return 'D';
    return 'F';
}

// 打印单个学生信息
void printStudent(const Student *student) {
    printf("学号: %d\n", student->student_id);
    printf("姓名: %s\n", student->name);
    printf("年龄: %d\n", student->age);
    printf("GPA: %.2f\n", student->gpa);
    
    printf("课程成绩:\n");
    printf("%-15s %-10s %-10s\n", "课程名", "分数", "等级");
    printf("---------------------------------\n");
    
    for (int i = 0; i < student->course_count; i++) {
        printf("%-15s %-10.1f %-10c\n",
               student->courses[i].course_name,
               student->courses[i].score,
               student->courses[i].grade);
    }
    printf("\n");
}

// 打印所有学生信息
void printAllStudents(Student students[], int count) {
    for (int i = 0; i < count; i++) {
        printf("学生 %d:\n", i + 1);
        printStudent(&students[i]);
    }
}
示例2:图书馆管理系统
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_BOOKS 1000
#define MAX_BORROWERS 100

// 定义图书结构体
typedef struct {
    int book_id;
    char title[100];
    char author[50];
    char isbn[20];
    int publication_year;
    int is_available;
} Book;

// 定义借阅者结构体
typedef struct {
    int borrower_id;
    char name[50];
    char contact[100];
    int borrowed_books[10];  // 最多借10本书
    int book_count;
} Borrower;

// 定义图书馆结构体
typedef struct {
    Book books[MAX_BOOKS];
    Borrower borrowers[MAX_BORROWERS];
    int book_count;
    int borrower_count;
} Library;

// 函数声明
void initializeLibrary(Library *library);
void addBook(Library *library, const char *title, const char *author, 
             const char *isbn, int year);
void addBorrower(Library *library, const char *name, const char *contact);
void borrowBook(Library *library, int borrower_id, int book_id);
void returnBook(Library *library, int borrower_id, int book_id);
void searchBook(const Library *library, const char *keyword);
void printLibraryStatus(const Library *library);

int main() {
    printf("=== 图书馆管理系统 ===\n");
    
    Library library;
    initializeLibrary(&library);
    
    // 添加一些图书
    addBook(&library, "C语言程序设计", "谭浩强", "978-7-04-123456", 2010);
    addBook(&library, "数据结构", "严蔚敏", "978-7-04-123457", 2011);
    addBook(&library, "算法导论", "Thomas Cormen", "978-7-04-123458", 2012);
    addBook(&library, "深入理解计算机系统", "Randal Bryant", "978-7-04-123459", 2016);
    
    // 添加一些借阅者
    addBorrower(&library, "张三", "zhangsan@email.com");
    addBorrower(&library, "李四", "lisi@email.com");
    
    // 显示图书馆状态
    printf("=== 图书馆初始状态 ===\n");
    printLibraryStatus(&library);
    
    // 借书操作
    printf("\n=== 借书操作 ===\n");
    borrowBook(&library, 1, 1);  // 张三借C语言程序设计
    borrowBook(&library, 1, 2);  // 张三借数据结构
    borrowBook(&library, 2, 3);  // 李四借算法导论
    
    printf("\n=== 借书后状态 ===\n");
    printLibraryStatus(&library);
    
    // 还书操作
    printf("\n=== 还书操作 ===\n");
    returnBook(&library, 1, 1);  // 张三还C语言程序设计
    
    printf("\n=== 还书后状态 ===\n");
    printLibraryStatus(&library);
    
    // 搜索图书
    printf("\n=== 搜索图书 ===\n");
    searchBook(&library, "C语言");
    
    return 0;
}

// 初始化图书馆
void initializeLibrary(Library *library) {
    library->book_count = 0;
    library->borrower_count = 0;
}

// 添加图书
void addBook(Library *library, const char *title, const char *author, 
             const char *isbn, int year) {
    if (library->book_count < MAX_BOOKS) {
        Book *book = &library->books[library->book_count];
        book->book_id = library->book_count + 1;
        strcpy(book->title, title);
        strcpy(book->author, author);
        strcpy(book->isbn, isbn);
        book->publication_year = year;
        book->is_available = 1;
        library->book_count++;
        
        printf("添加图书: 《%s》- %s\n", title, author);
    }
}

// 添加借阅者
void addBorrower(Library *library, const char *name, const char *contact) {
    if (library->borrower_count < MAX_BORROWERS) {
        Borrower *borrower = &library->borrowers[library->borrower_count];
        borrower->borrower_id = library->borrower_count + 1;
        strcpy(borrower->name, name);
        strcpy(borrower->contact, contact);
        borrower->book_count = 0;
        library->borrower_count++;
        
        printf("添加借阅者: %s (%s)\n", name, contact);
    }
}

// 借书
void borrowBook(Library *library, int borrower_id, int book_id) {
    // 查找借阅者
    Borrower *borrower = NULL;
    for (int i = 0; i < library->borrower_count; i++) {
        if (library->borrowers[i].borrower_id == borrower_id) {
            borrower = &library->borrowers[i];
            break;
        }
    }
    
    // 查找图书
    Book *book = NULL;
    for (int i = 0; i < library->book_count; i++) {
        if (library->books[i].book_id == book_id) {
            book = &library->books[i];
            break;
        }
    }
    
    if (borrower == NULL || book == NULL) {
        printf("错误:借阅者或图书不存在!\n");
        return;
    }
    
    if (!book->is_available) {
        printf("错误:图书《%s》已被借出!\n", book->title);
        return;
    }
    
    if (borrower->book_count >= 10) {
        printf("错误:%s 已达到借书上限!\n", borrower->name);
        return;
    }
    
    // 执行借书操作
    book->is_available = 0;
    borrower->borrowed_books[borrower->book_count] = book_id;
    borrower->book_count++;
    
    printf("%s 成功借阅《%s》\n", borrower->name, book->title);
}

// 还书
void returnBook(Library *library, int borrower_id, int book_id) {
    // 查找借阅者
    Borrower *borrower = NULL;
    for (int i = 0; i < library->borrower_count; i++) {
        if (library->borrowers[i].borrower_id == borrower_id) {
            borrower = &library->borrowers[i];
            break;
        }
    }
    
    // 查找图书
    Book *book = NULL;
    for (int i = 0; i < library->book_count; i++) {
        if (library->books[i].book_id == book_id) {
            book = &library->books[i];
            break;
        }
    }
    
    if (borrower == NULL || book == NULL) {
        printf("错误:借阅者或图书不存在!\n");
        return;
    }
    
    // 查找并移除借阅记录
    int found = 0;
    for (int i = 0; i < borrower->book_count; i++) {
        if (borrower->borrowed_books[i] == book_id) {
            // 移动后面的元素向前
            for (int j = i; j < borrower->book_count - 1; j++) {
                borrower->borrowed_books[j] = borrower->borrowed_books[j + 1];
            }
            borrower->book_count--;
            found = 1;
            break;
        }
    }
    
    if (!found) {
        printf("错误:%s 没有借阅《%s》!\n", borrower->name, book->title);
        return;
    }
    
    // 执行还书操作
    book->is_available = 1;
    printf("%s 成功归还《%s》\n", borrower->name, book->title);
}

// 搜索图书
void searchBook(const Library *library, const char *keyword) {
    printf("搜索关键词 '%s' 的结果:\n", keyword);
    printf("%-5s %-30s %-20s %-15s %-10s\n", 
           "ID", "书名", "作者", "ISBN", "状态");
    printf("----------------------------------------------------------------\n");
    
    int found = 0;
    for (int i = 0; i < library->book_count; i++) {
        const Book *book = &library->books[i];
        if (strstr(book->title, keyword) != NULL || 
            strstr(book->author, keyword) != NULL) {
            printf("%-5d %-30s %-20s %-15s %-10s\n",
                   book->book_id,
                   book->title,
                   book->author,
                   book->isbn,
                   book->is_available ? "可借" : "已借出");
            found = 1;
        }
    }
    
    if (!found) {
        printf("未找到相关图书\n");
    }
}

// 打印图书馆状态
void printLibraryStatus(const Library *library) {
    printf("=== 图书信息 ===\n");
    printf("%-5s %-30s %-20s %-15s %-10s\n", 
           "ID", "书名", "作者", "ISBN", "状态");
    printf("----------------------------------------------------------------\n");
    
    for (int i = 0; i < library->book_count; i++) {
        const Book *book = &library->books[i];
        printf("%-5d %-30s %-20s %-15s %-10s\n",
               book->book_id,
               book->title,
               book->author,
               book->isbn,
               book->is_available ? "可借" : "已借出");
    }
    
    printf("\n=== 借阅者信息 ===\n");
    printf("%-5s %-20s %-30s %-15s\n", 
           "ID", "姓名", "联系方式", "借书数量");
    printf("--------------------------------------------------------\n");
    
    for (int i = 0; i < library->borrower_count; i++) {
        const Borrower *borrower = &library->borrowers[i];
        printf("%-5d %-20s %-30s %-15d\n",
               borrower->borrower_id,
               borrower->name,
               borrower->contact,
               borrower->book_count);
        
        if (borrower->book_count > 0) {
            printf("  借阅的图书: ");
            for (int j = 0; j < borrower->book_count; j++) {
                int book_id = borrower->borrowed_books[j];
                for (int k = 0; k < library->book_count; k++) {
                    if (library->books[k].book_id == book_id) {
                        printf("《%s》 ", library->books[k].title);
                        break;
                    }
                }
            }
            printf("\n");
        }
    }
}

9. 结构体的高级特性

结构体位字段
c 复制代码
#include <stdio.h>

// 使用位字段的结构体
typedef struct {
    unsigned int is_active : 1;      // 1位:是否激活
    unsigned int permission : 3;     // 3位:权限级别(0-7)
    unsigned int status : 2;         // 2位:状态(0-3)
    unsigned int reserved : 2;       // 2位:保留位
} Settings;

// 日期结构体(使用位字段节省空间)
typedef struct {
    unsigned int day : 5;    // 5位:日期(1-31)
    unsigned int month : 4;  // 4位:月份(1-12)
    unsigned int year : 12;  // 12位:年份(0-4095)
} CompactDate;

int main() {
    printf("=== 结构体位字段 ===\n");
    
    Settings settings;
    settings.is_active = 1;
    settings.permission = 5;  // 101二进制
    settings.status = 2;      // 10二进制
    settings.reserved = 0;
    
    printf("设置信息:\n");
    printf("是否激活: %d\n", settings.is_active);
    printf("权限级别: %d\n", settings.permission);
    printf("状态: %d\n", settings.status);
    printf("Settings结构体大小: %zu 字节\n", sizeof(settings));
    
    CompactDate date;
    date.day = 15;
    date.month = 8;
    date.year = 2023;
    
    printf("\n日期: %d年%d月%d日\n", date.year, date.month, date.day);
    printf("CompactDate结构体大小: %zu 字节\n", sizeof(date));
    
    // 对比普通日期结构体
    typedef struct {
        int day;
        int month;
        int year;
    } NormalDate;
    
    NormalDate normal_date = {15, 8, 2023};
    printf("普通日期结构体大小: %zu 字节\n", sizeof(normal_date));
    
    return 0;
}

10. 结构体的常见错误和最佳实践

常见错误示例
c 复制代码
#include <stdio.h>
#include <string.h>

typedef struct {
    char name[50];
    int age;
} Person;

int main() {
    printf("=== 结构体常见错误 ===\n");
    
    // ❌ 错误1:结构体比较
    /*
    Person p1 = {"张三", 20};
    Person p2 = {"张三", 20};
    if (p1 == p2) {  // 错误:不能直接比较结构体
        printf("相同\n");
    }
    */
    
    // ✅ 正确:逐个比较成员
    Person p1 = {"张三", 20};
    Person p2 = {"张三", 20};
    if (strcmp(p1.name, p2.name) == 0 && p1.age == p2.age) {
        printf("结构体内容相同\n");
    }
    
    // ❌ 错误2:结构体赋值时忘记字符串复制
    /*
    Person p3;
    p3.name = "李四";  // 错误:数组不能直接赋值
    */
    
    // ✅ 正确:使用strcpy
    Person p3;
    strcpy(p3.name, "李四");
    p3.age = 25;
    printf("正确赋值: %s, %d\n", p3.name, p3.age);
    
    // ❌ 错误3:返回局部结构体变量的地址
    /*
    Person* createPerson() {
        Person p = {"王五", 30};
        return &p;  // 错误:返回局部变量的地址
    }
    */
    
    // ✅ 正确:返回结构体值或使用动态分配
    Person createPerson() {
        Person p = {"王五", 30};
        return p;  // 正确:返回结构体值
    }
    
    Person p4 = createPerson();
    printf("正确返回: %s, %d\n", p4.name, p4.age);
    
    return 0;
}
最佳实践
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// ✅ 好的实践:使用有意义的命名
typedef struct {
    char first_name[50];
    char last_name[50];
    int birth_year;
} EmployeeInfo;

// ✅ 好的实践:提供初始化函数
void initializeEmployee(EmployeeInfo *emp, const char *first, 
                       const char *last, int birth_year) {
    strncpy(emp->first_name, first, sizeof(emp->first_name) - 1);
    emp->first_name[sizeof(emp->first_name) - 1] = '\0';
    
    strncpy(emp->last_name, last, sizeof(emp->last_name) - 1);
    emp->last_name[sizeof(emp->last_name) - 1] = '\0';
    
    emp->birth_year = birth_year;
}

// ✅ 好的实践:提供打印函数
void printEmployee(const EmployeeInfo *emp) {
    printf("姓名: %s %s\n", emp->first_name, emp->last_name);
    printf("出生年份: %d\n", emp->birth_year);
}

// ✅ 好的实践:提供验证函数
int isValidEmployee(const EmployeeInfo *emp) {
    return strlen(emp->first_name) > 0 && 
           strlen(emp->last_name) > 0 && 
           emp->birth_year > 1900;
}

int main() {
    printf("=== 结构体最佳实践 ===\n");
    
    EmployeeInfo emp1;
    initializeEmployee(&emp1, "张", "三", 1990);
    
    if (isValidEmployee(&emp1)) {
        printf("有效员工:\n");
        printEmployee(&emp1);
    } else {
        printf("无效员工数据\n");
    }
    
    // 测试无效数据
    EmployeeInfo emp2;
    initializeEmployee(&emp2, "", "", 1800);
    
    if (!isValidEmployee(&emp2)) {
        printf("\n检测到无效员工数据\n");
    }
    
    return 0;
}

相关推荐
Scott9999HH7 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社8 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海8 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖9 小时前
JDK 26 新特性详解
java·开发语言
马优晨9 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区11 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大12 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai12 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜12 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa12 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio