结构体数组与指针是 C++ 中处理复杂数据结构的重要技术。它们允许我们高效地管理和操作多个结构体对象。

结构体数组基础

静态结构体数组

#include <iostream>
#include <string>
#include <iomanip>
 
struct Student {
    int id;
    std::string name;
    int age;
    double gpa;
    
    // 构造函数
    Student(int i = 0, const std::string& n = "", int a = 0, double g = 0.0)
        : id(i), name(n), age(a), gpa(g) {}
    
    // 显示学生信息
    void display() const {
        std::cout << std::setw(4) << id 
                  << std::setw(12) << name 
                  << std::setw(4) << age 
                  << std::setw(6) << std::fixed << std::setprecision(2) << gpa << std::endl;
    }
};
 
int main() {
    std::cout << "=== 静态结构体数组 ===" << std::endl;
    
    // 1. 数组声明和初始化
    Student students[5] = {
        {1001, "张三", 20, 3.75},
        {1002, "李四", 21, 3.82},
        {1003, "王五", 19, 3.91},
        {1004, "赵六", 22, 3.65},
        {1005, "钱七", 20, 3.88}
    };
    
    // 2. 显示所有学生信息
    std::cout << "所有学生信息:" << std::endl;
    std::cout << std::setw(4) << "ID" 
              << std::setw(12) << "姓名" 
              << std::setw(4) << "年龄" 
              << std::setw(6) << "GPA" << std::endl;
    std::cout << std::string(26, '-') << std::endl;
    
    for (int i = 0; i < 5; ++i) {
        students[i].display();
    }
    
    // 3. 使用范围for循环
    std::cout << "\n使用范围for循环:" << std::endl;
    for (const auto& student : students) {
        student.display();
    }
    
    // 4. 修改数组元素
    students[2].gpa = 4.0;
    students[2].age = 20;
    
    std::cout << "\n修改后的学生信息:" << std::endl;
    students[2].display();
    
    // 5. 查找操作
    int searchId = 1003;
    bool found = false;
    for (int i = 0; i < 5; ++i) {
        if (students[i].id == searchId) {
            std::cout << "\n找到学生 ID " << searchId << ":" << std::endl;
            students[i].display();
            found = true;
            break;
        }
    }
    
    if (!found) {
        std::cout << "未找到学生 ID " << searchId << std::endl;
    }
    
    return 0;
}

动态结构体数组

#include <iostream>
#include <string>
#include <memory>
 
struct Product {
    int id;
    std::string name;
    double price;
    int quantity;
    
    Product(int i = 0, const std::string& n = "", double p = 0.0, int q = 0)
        : id(i), name(n), price(p), quantity(q) {}
    
    void display() const {
        std::cout << "ID: " << id 
                  << ", 名称: " << name 
                  << ", 价格: $" << price 
                  << ", 数量: " << quantity << std::endl;
    }
    
    double totalValue() const {
        return price * quantity;
    }
};
 
class ProductManager {
private:
    Product* products;
    int capacity;
    int size;
    
public:
    // 构造函数
    ProductManager(int initial_capacity = 10) 
        : capacity(initial_capacity), size(0) {
        products = new Product[capacity];
        std::cout << "创建产品管理器,容量: " << capacity << std::endl;
    }
    
    // 析构函数
    ~ProductManager() {
        delete[] products;
        std::cout << "销毁产品管理器" << std::endl;
    }
    
    // 拷贝构造函数
    ProductManager(const ProductManager& other) 
        : capacity(other.capacity), size(other.size) {
        products = new Product[capacity];
        for (int i = 0; i < size; ++i) {
            products[i] = other.products[i];
        }
        std::cout << "拷贝产品管理器" << std::endl;
    }
    
    // 赋值操作符
    ProductManager& operator=(const ProductManager& other) {
        if (this != &other) {
            delete[] products;
            
            capacity = other.capacity;
            size = other.size;
            products = new Product[capacity];
            
            for (int i = 0; i < size; ++i) {
                products[i] = other.products[i];
            }
            
            std::cout << "赋值产品管理器" << std::endl;
        }
        return *this;
    }
    
    // 添加产品
    void addProduct(const Product& product) {
        if (size >= capacity) {
            resize();
        }
        products[size++] = product;
    }
    
    // 获取产品
    Product& getProduct(int index) {
        if (index >= 0 && index < size) {
            return products[index];
        }
        throw std::out_of_range("索引超出范围");
    }
    
    // 显示所有产品
    void displayAll() const {
        std::cout << "所有产品 (共 " << size << " 个):" << std::endl;
        for (int i = 0; i < size; ++i) {
            std::cout << "[" << i << "] ";
            products[i].display();
        }
    }
    
    // 计算总价值
    double calculateTotalValue() const {
        double total = 0.0;
        for (int i = 0; i < size; ++i) {
            total += products[i].totalValue();
        }
        return total;
    }
    
    int getSize() const { return size; }
    
private:
    void resize() {
        int new_capacity = capacity * 2;
        Product* new_products = new Product[new_capacity];
        
        for (int i = 0; i < size; ++i) {
            new_products[i] = products[i];
        }
        
        delete[] products;
        products = new_products;
        capacity = new_capacity;
        
        std::cout << "数组扩容到: " << capacity << std::endl;
    }
};
 
int main() {
    std::cout << "=== 动态结构体数组 ===" << std::endl;
    
    ProductManager manager(3);
    
    // 添加产品
    manager.addProduct(Product(101, "笔记本电脑", 999.99, 5));
    manager.addProduct(Product(102, "无线鼠标", 29.99, 20));
    manager.addProduct(Product(103, "机械键盘", 129.99, 8));
    manager.addProduct(Product(104, "显示器", 299.99, 3));  // 触发扩容
    
    manager.displayAll();
    
    // 修改产品
    manager.getProduct(1).quantity = 25;
    manager.getProduct(1).price = 24.99;
    
    std::cout << "\n修改后:" << std::endl;
    manager.displayAll();
    
    std::cout << "\n总价值: $" << manager.calculateTotalValue() << std::endl;
    
    return 0;
}

结构体指针基础

指向结构体的指针

#include <iostream>
#include <string>
 
struct Employee {
    int id;
    std::string name;
    std::string department;
    double salary;
    
    Employee(int i = 0, const std::string& n = "", 
             const std::string& d = "", double s = 0.0)
        : id(i), name(n), department(d), salary(s) {}
    
    void display() const {
        std::cout << "员工 " << id << ": " << name 
                  << " (" << department << ") - $" << salary << std::endl;
    }
    
    void raiseSalary(double percentage) {
        salary *= (1.0 + percentage / 100.0);
    }
};
 
// 通过指针修改员工信息
void updateEmployee(Employee* emp, const std::string& newDept, double newSalary) {
    if (emp) {  // 检查指针是否有效
        emp->department = newDept;
        emp->salary = newSalary;
        std::cout << "更新员工信息: " << emp->name << std::endl;
    }
}
 
// 通过指针显示员工信息
void printEmployee(const Employee* emp) {
    if (emp) {
        emp->display();
    } else {
        std::cout << "无效的员工指针" << std::endl;
    }
}
 
int main() {
    std::cout << "=== 结构体指针基础 ===" << std::endl;
    
    // 1. 创建结构体对象
    Employee emp1(1001, "张三", "开发部", 8000.0);
    Employee emp2(1002, "李四", "测试部", 7000.0);
    
    // 2. 创建指向结构体的指针
    Employee* empPtr1 = &emp1;
    Employee* empPtr2 = &emp2;
    
    std::cout << "原始员工信息:" << std::endl;
    printEmployee(empPtr1);
    printEmployee(empPtr2);
    
    // 3. 通过指针访问成员
    std::cout << "\n通过指针访问:" << std::endl;
    std::cout << "员工1姓名: " << empPtr1->name << std::endl;
    std::cout << "员工1薪资: $" << (*empPtr1).salary << std::endl;  // 等价写法
    
    // 4. 通过指针修改成员
    empPtr1->salary = 8500.0;
    empPtr2->department = "高级测试部";
    
    std::cout << "\n修改后的员工信息:" << std::endl;
    printEmployee(empPtr1);
    printEmployee(empPtr2);
    
    // 5. 使用函数修改
    updateEmployee(empPtr1, "架构部", 12000.0);
    updateEmployee(empPtr2, "质量保证部", 9000.0);
    
    std::cout << "\n函数修改后的员工信息:" << std::endl;
    printEmployee(empPtr1);
    printEmployee(empPtr2);
    
    // 6. 指针重新赋值
    Employee* currentEmp = empPtr1;
    std::cout << "\n当前员工: ";
    printEmployee(currentEmp);
    
    currentEmp = empPtr2;  // 指向另一个员工
    std::cout << "切换后的当前员工: ";
    printEmployee(currentEmp);
    
    // 7. 空指针处理
    Employee* nullPtr = nullptr;
    std::cout << "\n测试空指针:" << std::endl;
    printEmployee(nullPtr);
    updateEmployee(nullPtr, "无效部门", 0.0);
    
    return 0;
}

动态分配结构体

#include <iostream>
#include <string>
#include <vector>
 
struct Book {
    int isbn;
    std::string title;
    std::string author;
    double price;
    bool isAvailable;
    
    Book(int i = 0, const std::string& t = "", const std::string& a = "", 
         double p = 0.0, bool avail = true)
        : isbn(i), title(t), author(a), price(p), isAvailable(avail) {}
    
    void display() const {
        std::cout << "ISBN: " << isbn 
                  << ", 书名: " << title 
                  << ", 作者: " << author 
                  << ", 价格: $" << price 
                  << ", 可借: " << (isAvailable ? "是" : "否") << std::endl;
    }
};
 
class Library {
private:
    std::vector<Book*> books;  // 存储指向书籍的指针
    
public:
    ~Library() {
        // 清理所有动态分配的书籍
        for (Book* book : books) {
            delete book;
        }
        std::cout << "图书馆析构,清理了 " << books.size() << " 本书" << std::endl;
    }
    
    // 添加新书(动态分配)
    void addBook(int isbn, const std::string& title, const std::string& author, double price) {
        Book* newBook = new Book(isbn, title, author, price);
        books.push_back(newBook);
        std::cout << "添加新书: " << title << std::endl;
    }
    
    // 查找书籍
    Book* findBook(int isbn) {
        for (Book* book : books) {
            if (book->isbn == isbn) {
                return book;
            }
        }
        return nullptr;
    }
    
    // 借书
    bool borrowBook(int isbn) {
        Book* book = findBook(isbn);
        if (book && book->isAvailable) {
            book->isAvailable = false;
            std::cout << "成功借阅: " << book->title << std::endl;
            return true;
        } else if (book) {
            std::cout << "书籍已被借出: " << book->title << std::endl;
        } else {
            std::cout << "未找到 ISBN " << isbn << " 的书籍" << std::endl;
        }
        return false;
    }
    
    // 还书
    bool returnBook(int isbn) {
        Book* book = findBook(isbn);
        if (book && !book->isAvailable) {
            book->isAvailable = true;
            std::cout << "成功归还: " << book->title << std::endl;
            return true;
        } else if (book) {
            std::cout << "书籍未被借出: " << book->title << std::endl;
        } else {
            std::cout << "未找到 ISBN " << isbn << " 的书籍" << std::endl;
        }
        return false;
    }
    
    // 显示所有书籍
    void displayAllBooks() const {
        std::cout << "\n图书馆藏书 (共 " << books.size() << "