第十一课 结构体与枚举
为了解决更复杂的问题,C++允许我们自定义数据类型。结构体和枚举是最常用的两种自定义类型。
一、结构体(struct)
- 把不同类型的数据组合成一个整体
- 用于描述一个实体
- 结构体是一种自定义的数据类型
- 结构体定义和使用
#include <iostream>
#include <string>
using namespace std;
// 定义结构体
struct Student {
string name; // 姓名
int age; // 年龄
double score; // 成绩
};
int main() {
// 创建结构体变量
Student s1;
// 给成员赋值
s1.name = "Tom";
s1.age = 18;
s1.score = 90.5;
// 访问成员
cout << "姓名:" << s1.name << endl;
cout << "年龄:" << s1.age << endl;
cout << "成绩:" << s1.score << endl;
return 0;
}
- 结构体初始化
#include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int age;
double score;
};
int main() {
// 方式1:创建后逐个赋值
Student s1;
s1.name = "Tom";
s1.age = 18;
s1.score = 90.5;
// 方式2:定义时初始化
Student s2 = {"Lucy", 17, 88.0};
// 方式3:指定成员初始化(C++11)
Student s3 = {.name = "Mike", .age = 19, .score = 95.0};
// 方式4:先定义后初始化
Student s4;
s4 = {"Jack", 20, 92.0};
// 输出验证
cout << s2.name << " " << s2.age << " " << s2.score << endl;
// Lucy 17 88
return 0;
}
- 结构体数组
#include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int age;
double score;
};
int main() {
// 结构体数组
Student students[3] = {
{"Tom", 18, 90.5},
{"Lucy", 17, 88.0},
{"Jack", 19, 92.0}
};
// 遍历输出
for (int i = 0; i < 3; i++) {
cout << students[i].name << " "
<< students[i].age << " "
<< students[i].score << endl;
}
return 0;
}
- 结构体嵌套
#include <iostream>
#include <string>
using namespace std;
struct Date {
int year;
int month;
int day;
};
struct Student {
string name;
Date birthday; // 嵌套结构体
double score;
};
int main() {
Student s;
s.name = "Tom";
s.birthday.year = 2006;
s.birthday.month = 3;
s.birthday.day = 15;
s.score = 90.5;
cout << s.name << " 生日:"
<< s.birthday.year << "-"
<< s.birthday.month << "-"
<< s.birthday.day << endl;
return 0;
}
- 结构体和函数
#include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int age;
double score;
};
// 传递结构体(值传递)
void printStudent1(Student s) {
cout << s.name << " " << s.age << " " << s.score << endl;
}
// 传递结构体指针
void printStudent2(Student *p) {
cout << p->name << " " << p->age << " " << p->score << endl;
}
// 传递结构体引用
void printStudent3(Student &s) {
cout << s.name << " " << s.age << " " << s.score << endl;
}
// 返回结构体
Student createStudent(string name, int age, double score) {
Student s;
s.name = name;
s.age = age;
s.score = score;
return s;
}
int main() {
Student s = {"Tom", 18, 90.5};
printStudent1(s); // 值传递
printStudent2(&s); // 指针传递
printStudent3(s); // 引用传递
Student s2 = createStudent("Lucy", 17, 88.0);
cout << s2.name << " " << s2.age << endl;
return 0;
}
- typedef(给类型起别名)
#include <iostream>
#include <string>
using namespace std;
// 使用typedef给类型起别名
typedef struct Student {
string name;
int age;
double score;
} STU; // STU是Student的别名
// 或者使用using(C++11)
using Score = double;
int main() {
// 使用别名创建变量
STU s1 = {"Tom", 18, 90.5};
Student s2 = {"Lucy", 17, 88.0};
Score score = 95.5; // 等价于 double score
cout << s1.name << " " << score << endl;
return 0;
}
二、枚举(enum)
- 定义一组命名的整型常量
- 提高代码可读性
- 默认从0开始递增
- 常量定义和使用
#include <iostream>
using namespace std;
// 定义常量
const int MAX_NUM = 100;
const double PI = 3.14159;
const string GREETING = "Hello";
int main() {
// 使用常量
cout << "最大值: " << MAX_NUM << endl;
cout << "圆周率: " << PI << endl;
cout << "问候语: " << GREETING << endl;
// 尝试修改常量会报错
// MAX_NUM = 200; // 错误!
return 0;
}
- 枚举定义和使用
#include <iostream>
using namespace std;
// 定义枚举
enum Weekday {
Monday, // 0
Tuesday, // 1
Wednesday, // 2
Thursday, // 3
Friday, // 4
Saturday, // 5
Sunday // 6
};
int main() {
Weekday today = Monday;
cout << today << endl; // 输出0
today = Friday;
cout << today << endl; // 输出4
// 枚举用于判断
if (today == Saturday || today == Sunday) {
cout << "周末休息" << endl;
} else {
cout << "工作日" << endl;
}
return 0;
}
- 枚举指定值
#include <iostream>
using namespace std;
enum Color {
Red = 1, // 指定为1
Green = 2, // 指定为2
Blue = 3 // 指定为3
};
enum Status {
Error = -1, // 负数
Success = 0,
Pending = 1
};
int main() {
Color c = Red;
cout << c << endl; // 1
Status s = Success;
cout << s << endl; // 0
return 0;
}
- 枚举类(C++11)
#include <iostream>
using namespace std;
// 枚举类:更安全,不会污染命名空间
enum class Level {
Low, // 0
Medium, // 1
High // 2
};
enum class ErrorCode : int {
OK = 0,
FileNotFound = 404,
Unknown = 999
};
int main() {
// 使用时需要加作用域
Level l = Level::High;
if (l == Level::High) {
cout << "高优先级" << endl;
}
ErrorCode e = ErrorCode::FileNotFound;
cout << static_cast<int>(e) << endl; // 404,需要转换
return 0;
}
三、结构体和枚举的结合使用
#include <iostream>
#include <string>
using namespace std;
enum class Gender { Male, Female };
struct Person {
string name;
int age;
Gender gender;
};
int main() {
Person p;
p.name = "Tom";
p.age = 20;
p.gender = Gender::Male;
if (p.gender == Gender::Male) {
cout << p.name << "是男性" << endl;
}
return 0;
}
