什么是结构体?
结构体(structure,简称 struct)是一种用户自定义的数据类型,用于将多个不同类型的数据组合在一起。它允许在一个单一的单元中存储多个相关的数据项,使代码更具组织性和可读性。
结构体在编程中的应用场景
- 数据组织:将相关的数据组合,如学生信息、坐标点、日期等。
- 传递数据:在函数之间传递多个相关的数据项。
- 复杂数据处理:管理更复杂的数据结构,如链表、树、图等。
结构体的基本使用
定义和声明结构体
在 C++ 中,使用 struct 关键字定义一个结构体。基本语法如下:
struct StructName {
    // 成员变量
    dataType1 member1;
    dataType2 member2;
    // ...
};
示例:定义一个学生结构体
struct Student {
    int id;
    std::string name;
    float grade;
};
创建结构体变量
定义结构体后,可以创建结构体类型的变量。
Student student1;
Student student2;
访问结构体成员
使用点运算符(.)访问结构体成员。
student1.id = 1001;
student1.name = "Alice";
student1.grade = 89.5f;
std::cout << "学生ID: " << student1.id << std::endl;
std::cout << "学生姓名: " << student1.name << std::endl;
std::cout << "学生成绩: " << student1.grade << std::endl;
结构体初始化
可以在创建结构体变量时进行初始化。
方法一:直观初始化
Student student3 = {1002, "Bob", 92.0f};
方法二:逐个赋值
Student student4;
student4.id = 1003;
student4.name = "Charlie";
student4.grade = 85.0f;
方法三:使用自定义构造函数
虽然结构体的主要用途是数据存储,但在 C++ 中,结构体可以像类一样拥有构造函数。
struct Student {
    int id;
    std::string name;
    float grade;
    // 构造函数
    Student(int studentId, std::string studentName, float studentGrade) :
        id(studentId), name(studentName), grade(studentGrade) {}
};
// 使用构造函数初始化
Student student5(1004, "Daisy", 95.0f);
结构体与类的比较
在 C++ 中,struct 和 class 有很多相似之处,但也有一些关键区别。
类与结构体的相似之处
- 都可以包含成员变量和成员函数。
- 都支持访问控制(public、protected、private)。
- 都可以使用继承和多态。
类与结构体的区别
默认访问控制
- 结构体(struct):默认成员访问权限为 public。
- 类(class):默认成员访问权限为 private。
例子
struct StructExample {
    int x; // 默认 public
};
class ClassExample {
    int y; // 默认 private
};
用途习惯
- 结构体(struct):通常用于纯数据结构,主要存储数据,成员通常是公开的。
- 类(class):用于包含数据和操作数据的函数,支持更加复杂的封装。
实例比较
struct Point {
    int x;
    int y;
};
class Rectangle {
private:
    int width;
    int height;
public:
    void setDimensions(int w, int h) {
        width = w;
        height = h;
    }
    int area() const {
        return width * height;
    }
    int get_width(){
        return width;
    }
};
int main(){
    Rectangle rt;
    //错误,不能直接访问私有成员
    rt.width;
    //正确,可以通过公有成员函数访问
    rt.get_width();
}
结构体的高级用法
嵌套结构体
结构体可以包含其他结构体作为成员。
示例:嵌套地址结构体
struct Address {
    std::string city;
    std::string street;
    int houseNumber;
};
struct Person {
    std::string name;
    int age;
    Address address; // 嵌套结构体
};
int main() {
    Person person;
    person.name = "Eve";
    person.age = 30;
    person.address.city = "New York";
    person.address.street = "5th Avenue";
    person.address.houseNumber = 101;
    std::cout << person.name << " lives at " 
              << person.address.houseNumber << " " 
              << person.address.street << ", " 
              << person.address.city << std::endl;
    return 0;
}
输出:
Eve lives at 101 5th Avenue, New York
结构体数组
可以创建包含多个结构体的数组,用于存储多个相同类型的数据项。
示例:存储多个学生信息的数组
struct Student {
    int id;
    std::string name;
    float grade;
};
int main() {
    // 创建包含3个学生信息的数组
    Student students[3] = {
        {1001, "Alice", 89.5f},
        {1002, "Bob", 92.0f},
        {1003, "Charlie", 85.0f}
    };
    for (int i = 0; i < 3; ++i) {
        std::cout << "学生ID: " << students[i].id 
                  << ", 姓名: " << students[i].name 
                  << ", 成绩: " << students[i].grade << std::endl;
    }
    return 0;
}
输出:
学生ID: 1001, 姓名: Alice, 成绩: 89.5
学生ID: 1002, 姓名: Bob, 成绩: 92
学生ID: 1003, 姓名: Charlie, 成绩: 85
结构体指针
可以创建指向结构体的指针,并通过指针访问结构体成员。
示例:使用结构体指针
struct Car {
    std::string brand;
    std::string model;
    int year;
};
int main() {
    Car car = {"Toyota", "Camry", 2020};
    Car* carPtr = &car;
    std::cout << "品牌: " << carPtr->brand << std::endl;
    std::cout << "型号: " << carPtr->model << std::endl;
    std::cout << "年份: " << carPtr->year << std::endl;
    return 0;
}
输出:
品牌: Toyota
型号: Camry
年份: 2020
使用 typedef 简化结构体定义
使用 typedef(或 using 关键字)可以为结构体类型创建别名,使代码更简洁。
示例:使用 typedef
typedef struct {
    int id;
    std::string name;
    float grade;
} Student;
// 或者使用 `using`(C++11 及以上)
using Student = struct {
    int id;
    std::string name;
    float grade;
};
应用:
int main() {
    Student s1 = {1004, "Daisy", 95.0f};
    std::cout << "学生ID: " << s1.id 
              << ", 姓名: " << s1.name 
              << ", 成绩: " << s1.grade << std::endl;
    return 0;
}
输出:
学生ID: 1004, 姓名: Daisy, 成绩: 95
5. 结构体中的函数
虽然结构体主要用于存储数据,但在 C++ 中,结构体也可以包含成员函数。这使得结构体更具面向对象的特性。
示例:在结构体中定义成员函数
#include <iostream>
#include <string>
struct Book {
    std::string title;
    std::string author;
    int pages;
    // 成员函数
    void printInfo() const {
        std::cout << "书名: " << title 
                  << ", 作者: " << author 
                  << ", 页数: " << pages << std::endl;
    }
};
int main() {
    Book myBook = {"C++ Primer", "Stanley B. Lippman", 976};
    myBook.printInfo();
    return 0;
}
输出:
书名: C++ Primer, 作者: Stanley B. Lippman, 页数: 976
使用结构体作为函数参数和返回值
传递结构体给函数
struct Point {
    int x;
    int y;
};
// 通过值传递
void printPoint(Point p) {
    std::cout << "Point(" << p.x << ", " << p.y << ")" << std::endl;
}
// 通过引用传递
void movePoint(Point& p, int dx, int dy) {
    p.x += dx;
    p.y += dy;
}
int main() {
    Point p1 = {10, 20};
    printPoint(p1);
    movePoint(p1, 5, -5);
    printPoint(p1);
    return 0;
}
输出:
Point(10, 20)
Point(15, 15)
从函数返回结构体
struct Rectangle {
    int width;
    int height;
};
// 计算面积的结构体
struct Area {
    int value;
};
// 函数返回结构体
Area calculateArea(Rectangle rect) {
    Area area;
    area.value = rect.width * rect.height;
    return area;
}
int main() {
    Rectangle rect = {5, 10};
    Area rectArea = calculateArea(rect);
    std::cout << "矩形面积: " << rectArea.value << std::endl;
    return 0;
}
输出:
矩形面积: 50
6. 示例项目
示例项目:简单学生信息管理系统
这个项目将结合前面的知识点,创建一个简单的学生信息管理系统,允许添加、显示和查找学生信息。
需求分析
- 添加新学生的信息(ID、姓名、成绩)
- 显示所有学生的信息
- 根据学生ID查找学生信息
代码实现
#include <iostream>
#include <vector>
#include <string>
// 定义学生结构体
struct Student {
    int id;
    std::string name;
    float grade;
    // 成员函数打印学生信息
    void printInfo() const {
        std::cout << "学生ID: " << id 
                  << ", 姓名: " << name 
                  << ", 成绩: " << grade << std::endl;
    }
};
// 添加学生
void addStudent(std::vector<Student>& students, int id, const std::string& name, float grade) {
    Student newStudent = {id, name, grade};
    students.push_back(newStudent);
    std::cout << "添加学生成功。" << std::endl;
}
// 显示所有学生
void displayStudents(const std::vector<Student>& students) {
    if (students.empty()) {
        std::cout << "没有学生信息。" << std::endl;
        return;
    }
    std::cout << "所有学生信息:" << std::endl;
    for (const auto& student : students) {
        student.printInfo();
    }
}
// 根据ID查找学生
void findStudentById(const std::vector<Student>& students, int id) {
    for (const auto& student : students) {
        if (student.id == id) {
            std::cout << "找到学生:" << std::endl;
            student.printInfo();
            return;
        }
    }
    std::cout << "未找到ID为 " << id << " 的学生。" << std::endl;
}
int main() {
    std::vector<Student> students;
    int choice;
    do {
        std::cout << "\n===== 学生信息管理系统 =====" << std::endl;
        std::cout << "1. 添加学生" << std::endl;
        std::cout << "2. 显示所有学生" << std::endl;
        std::cout << "3. 根据ID查找学生" << std::endl;
        std::cout << "4. 退出" << std::endl;
        std::cout << "请选择(1-4):";
        std::cin >> choice;
        if (choice == 1) {
            int id;
            std::string name;
            float grade;
            std::cout << "输入学生ID: ";
            std::cin >> id;
            std::cout << "输入学生姓名: ";
            std::cin >> name;
            std::cout << "输入学生成绩: ";
            std::cin >> grade;
            addStudent(students, id, name, grade);
        }
        else if (choice == 2) {
            displayStudents(students);
        }
        else if (choice == 3) {
            int searchId;
            std::cout << "输入要查找的学生ID: ";
            std::cin >> searchId;
            findStudentById(students, searchId);
        }
        else if (choice == 4) {
            std::cout << "退出系统。" << std::endl;
        }
        else {
            std::cout << "无效选择,请重新输入。" << std::endl;
        }
    } while (choice != 4);
    return 0;
}
代码解析
- 结构体定义:定义了一个 Student结构体,包含id、name和grade,并有一个成员函数printInfo来打印学生信息。
- 功能函数:- addStudent:向学生列表中添加一个新的学生。
- displayStudents:显示所有学生的信息。
- findStudentById:根据学生ID查找并显示学生信息。
 
- 用户交互:使用 do-while循环和switch-case来处理用户的选择,实现添加、显示和查找学生信息的功能。
运行示例
===== 学生信息管理系统 =====
1. 添加学生
2. 显示所有学生
3. 根据ID查找学生
4. 退出
请选择(1-4):1
输入学生ID: 1001
输入学生姓名: Alice
输入学生成绩: 89.5
添加学生成功。
===== 学生信息管理系统 =====
1. 添加学生
2. 显示所有学生
3. 根据ID查找学生
4. 退出
请选择(1-4):1
输入学生ID: 1002
输入学生姓名: Bob
输入学生成绩: 92.0
添加学生成功。
===== 学生信息管理系统 =====
1. 添加学生
2. 显示所有学生
3. 根据ID查找学生
4. 退出
请选择(1-4):2
所有学生信息:
学生ID: 1001, 姓名: Alice, 成绩: 89.5
学生ID: 1002, 姓名: Bob, 成绩: 92
===== 学生信息管理系统 =====
1. 添加学生
2. 显示所有学生
3. 根据ID查找学生
4. 退出
请选择(1-4):3
输入要查找的学生ID: 1001
找到学生:
学生ID: 1001, 姓名: Alice, 成绩: 89.5
===== 学生信息管理系统 =====
1. 添加学生
2. 显示所有学生
3. 根据ID查找学生
4. 退出
请选择(1-4):4
退出系统。
 
       
      