结构体数组与指针是 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() << "