第10章 - 结构体和枚举
嗨,朋友!我是长安。
之前我们学习的数据类型(int、double、string等)只能存储单一类型的数据。但在实际开发中,我们经常需要把多个相关的数据组合在一起。
这一章,我们要学习结构体和枚举,它们能帮我们组织复杂的数据!
📦 什么是结构体?
生活中的例子
想象你要记录一个学生的信息:
- 姓名:张三
- 学号:1001
- 年龄:20
- 成绩:95.5
如果用变量存储:
string name = "张三";
int id = 1001;
int age = 20;
double score = 95.5;
这样太零散了!结构体可以把这些数据打包在一起:
struct Student {
int id;
string name;
int age;
double score;
};
🏗️ 定义和使用结构体
基本语法
struct 结构体名 {
数据类型 成员1;
数据类型 成员2;
// ...
};
示例1:定义学生结构体
#include <iostream>
#include <string>
using namespace std;
// 定义结构体
struct Student {
int id;
string name;
int age;
double score;
};
int main() {
// 创建结构体变量
Student stu1;
// 赋值
stu1.id = 1001;
stu1.name = "张三";
stu1.age = 20;
stu1.score = 95.5;
// 输出
cout << "学号:" << stu1.id << endl;
cout << "姓名:" << stu1.name << endl;
cout << "年龄:" << stu1.age << endl;
cout << "成绩:" << stu1.score << endl;
return 0;
}
示例2:结构体初始化
#include <iostream>
#include <string>
using namespace std;
struct Student {
int id;
string name;
int age;
double score;
};
int main() {
// 方法1:定义时初始化
Student stu1 = {1001, "张三", 20, 95.5};
// 方法2:C++11列表初始化
Student stu2{1002, "李四", 21, 88.0};
// 方法3:部分初始化
Student stu3 = {1003, "王五"}; // age和score为默认值
cout << stu1.name << " - " << stu1.score << endl;
cout << stu2.name << " - " << stu2.score << endl;
cout << stu3.name << " - " << stu3.score << endl;
return 0;
}
📚 结构体数组
#include <iostream>
#include <string>
using namespace std;
struct Student {
int id;
string name;
double score;
};
int main() {
// 结构体数组
Student students[3] = {
{1001, "张三", 95.5},
{1002, "李四", 88.0},
{1003, "王五", 92.0}
};
cout << "学生列表:" << endl;
for (int i = 0; i < 3; i++) {
cout << students[i].id << "\t"
<< students[i].name << "\t"
<< students[i].score << endl;
}
return 0;
}
🔗 结构体指针
#include <iostream>
#include <string>
using namespace std;
struct Student {
int id;
string name;
double score;
};
int main() {
Student stu = {1001, "张三", 95.5};
Student* ptr = &stu;
// 方法1:通过解引用访问
cout << (*ptr).name << endl;
// 方法2:使用箭头运算符(推荐)
cout << ptr->name << endl;
cout << ptr->score << endl;
return 0;
}
📤 结构体作为函数参数
值传递
#include <iostream>
#include <string>
using namespace std;
struct Student {
int id;
string name;
double score;
};
void printStudent(Student s) {
cout << s.id << " - " << s.name << " - " << s.score << endl;
}
int main() {
Student stu = {1001, "张三", 95.5};
printStudent(stu);
return 0;
}
引用传递(推荐)
void printStudent(const Student& s) {
cout << s.id << " - " << s.name << " - " << s.score << endl;
}
指针传递
void printStudent(const Student* s) {
cout << s->id << " - " << s->name << " - " << s->score << endl;
}
🔢 什么是枚举?
枚举(enum)是一种用户定义的数据类型,用来定义一组命名的常量。
生活中的例子
星期:
enum Weekday {
MONDAY, // 0
TUESDAY, // 1
WEDNESDAY, // 2
THURSDAY, // 3
FRIDAY, // 4
SATURDAY, // 5
SUNDAY // 6
};
📝 枚举的定义和使用
基本语法
enum 枚举名 {
常量1,
常量2,
常量3
};
示例1:定义星期枚举
#include <iostream>
using namespace std;
enum Weekday {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
};
int main() {
Weekday today = WEDNESDAY;
cout << "今天是:";
switch (today) {
case MONDAY:
cout << "星期一" << endl;
break;
case TUESDAY:
cout << "星期二" << endl;
break;
case WEDNESDAY:
cout << "星期三" << endl;
break;
case THURSDAY:
cout << "星期四" << endl;
break;
case FRIDAY:
cout << "星期五" << endl;
break;
case SATURDAY:
cout << "星期六" << endl;
break;
case SUNDAY:
cout << "星期日" << endl;
break;
}
return 0;
}
示例2:自定义枚举值
#include <iostream>
using namespace std;
enum Color {
RED = 1,
GREEN = 2,
BLUE = 3
};
enum Level {
EASY = 1,
NORMAL = 5,
HARD = 10
};
int main() {
Color myColor = RED;
Level gameLevel = HARD;
cout << "颜色值:" << myColor << endl;
cout << "难度值:" << gameLevel << endl;
return 0;
}
🌟 实战案例
案例1:学生管理系统(使用结构体)
#include <iostream>
#include <string>
using namespace std;
struct Student {
int id;
string name;
int age;
double score;
};
void printStudent(const Student& s) {
cout << "学号:" << s.id << endl;
cout << "姓名:" << s.name << endl;
cout << "年龄:" << s.age << endl;
cout << "成绩:" << s.score << endl;
}
void modifyScore(Student& s, double newScore) {
s.score = newScore;
}
int main() {
Student stu = {1001, "张三", 20, 85.0};
cout << "修改前:" << endl;
printStudent(stu);
modifyScore(stu, 95.0);
cout << "\n修改后:" << endl;
printStudent(stu);
return 0;
}
案例2:图书管理(结构体+枚举)
#include <iostream>
#include <string>
using namespace std;
enum BookStatus {
AVAILABLE, // 可借
BORROWED, // 已借出
LOST // 丢失
};
struct Book {
int id;
string title;
string author;
BookStatus status;
};
void printBook(const Book& book) {
cout << "ID: " << book.id << endl;
cout << "书名: " << book.title << endl;
cout << "作者: " << book.author << endl;
cout << "状态: ";
switch (book.status) {
case AVAILABLE:
cout << "可借" << endl;
break;
case BORROWED:
cout << "已借出" << endl;
break;
case LOST:
cout << "丢失" << endl;
break;
}
}
int main() {
Book books[3] = {
{1001, "C++ Primer", "Stanley B. Lippman", AVAILABLE},
{1002, "Effective C++", "Scott Meyers", BORROWED},
{1003, "The C++ Programming Language", "Bjarne Stroustrup", AVAILABLE}
};
cout << "图书列表:" << endl;
for (int i = 0; i < 3; i++) {
cout << "\n========== 图书 " << (i + 1) << " ==========" << endl;
printBook(books[i]);
}
return 0;
}
案例3:员工工资计算
#include <iostream>
#include <string>
using namespace std;
enum Position {
INTERN, // 实习生
JUNIOR, // 初级
SENIOR, // 高级
MANAGER // 经理
};
struct Employee {
int id;
string name;
Position position;
double baseSalary;
};
double calculateSalary(const Employee& emp) {
double bonus = 0;
switch (emp.position) {
case INTERN:
bonus = emp.baseSalary * 0.0;
break;
case JUNIOR:
bonus = emp.baseSalary * 0.1;
break;
case SENIOR:
bonus = emp.baseSalary * 0.2;
break;
case MANAGER:
bonus = emp.baseSalary * 0.3;
break;
}
return emp.baseSalary + bonus;
}
string getPositionName(Position pos) {
switch (pos) {
case INTERN: return "实习生";
case JUNIOR: return "初级";
case SENIOR: return "高级";
case MANAGER: return "经理";
default: return "未知";
}
}
int main() {
Employee employees[4] = {
{1001, "张三", INTERN, 3000},
{1002, "李四", JUNIOR, 5000},
{1003, "王五", SENIOR, 8000},
{1004, "赵六", MANAGER, 12000}
};
cout << "员工工资表:" << endl;
cout << "ID\t姓名\t职位\t\t基本工资\t实发工资" << endl;
cout << "--------------------------------------------------------" << endl;
for (int i = 0; i < 4; i++) {
cout << employees[i].id << "\t"
<< employees[i].name << "\t"
<< getPositionName(employees[i].position) << "\t\t"
<< employees[i].baseSalary << "\t\t"
<< calculateSalary(employees[i]) << endl;
}
return 0;
}
案例4:嵌套结构体
#include <iostream>
#include <string>
using namespace std;
struct Date {
int year;
int month;
int day;
};
struct Person {
string name;
int age;
Date birthday; // 嵌套结构体
};
void printPerson(const Person& p) {
cout << "姓名:" << p.name << endl;
cout << "年龄:" << p.age << endl;
cout << "生日:" << p.birthday.year << "年"
<< p.birthday.month << "月"
<< p.birthday.day << "日" << endl;
}
int main() {
Person person = {
"张三",
20,
{2004, 5, 15}
};
printPerson(person);
return 0;
}
🎯 小结
| 概念 | 说明 | 示例 |
|---|---|---|
| 结构体定义 | 组合多个数据 | struct Student { ... }; |
| 结构体变量 | 创建实例 | Student stu; |
| 成员访问 | 使用点运算符 | stu.name |
| 指针访问 | 使用箭头运算符 | ptr->name |
| 枚举定义 | 定义常量集合 | enum Color { RED, GREEN }; |
| 枚举使用 | 作为类型使用 | Color c = RED; |
重要提醒:
- ✅ 结构体可以包含任意类型的成员
- ✅ 推荐使用const引用传递结构体
- ✅ 枚举值默认从0开始
- ✅ 枚举可以自定义值
💪 练习题
- 定义一个矩形结构体(包含长和宽),写函数计算面积和周长
- 定义一个日期结构体,写函数判断是否是闰年
- 创建一个商品结构体数组,实现按价格排序
- 使用枚举定义交通信号灯状态,模拟信号灯变化
- 定义一个复数结构体,实现复数的加减运算
点击查看参考答案
题目1 参考答案:
#include <iostream>
using namespace std;
struct Rectangle {
double length;
double width;
};
double getArea(const Rectangle& rect) {
return rect.length * rect.width;
}
double getPerimeter(const Rectangle& rect) {
return 2 * (rect.length + rect.width);
}
int main() {
Rectangle rect = {10.5, 5.2};
cout << "面积:" << getArea(rect) << endl;
cout << "周长:" << getPerimeter(rect) << endl;
return 0;
}
题目4 参考答案:
#include <iostream>
using namespace std;
enum TrafficLight {
RED,
YELLOW,
GREEN
};
void printLight(TrafficLight light) {
switch (light) {
case RED:
cout << "红灯 - 停止" << endl;
break;
case YELLOW:
cout << "黄灯 - 准备" << endl;
break;
case GREEN:
cout << "绿灯 - 通行" << endl;
break;
}
}
int main() {
TrafficLight light = RED;
for (int i = 0; i < 6; i++) {
printLight(light);
// 切换信号灯
if (light == RED) {
light = GREEN;
} else if (light == GREEN) {
light = YELLOW;
} else {
light = RED;
}
}
return 0;
}
🚀 下一步
太棒了!你已经掌握了结构体和枚举的使用!
下一章,我们要学习文件操作,实现数据的持久化存储!
➡️ 第11章 - 文件操作
