C++结构体(struct)知识点详解
编程小白入门指南 – 通俗易懂的大白话解释
结构体是C++中组织相关数据的强大工具,本文将用简单易懂的方式解释所有核心概念
学生信息结构体
int
id
string
name
int
age
float
gpa
结构体可视化
结构体就像一个”数据容器”,可以把多个不同类型的数据打包在一起。
例如,这个”学生信息”结构体包含:
- 学号 (整数类型)
- 姓名 (字符串类型)
- 年龄 (整数类型)
- 平均成绩 (浮点数类型)
使用结构体后,一个学生的所有信息可以作为一个整体处理,不需要分开管理多个变量。
1. 什么是结构体?
结构体(struct)是C++中一种自定义的数据类型,它允许你将多个不同类型的数据组合在一起,形成一个新的复合数据类型。
大白话解释:
想象结构体就像一个”数据盒子”:
- 这个盒子可以装各种不同类型的东西(数据)
- 你可以给盒子里的每个物品贴上标签(成员变量)
- 整个盒子有一个名字(结构体名称)
- 需要时可以创建多个相同的盒子(结构体变量)
为什么需要结构体?
当你要处理一组相关的数据时,比如一个学生的信息(学号、姓名、年龄、成绩),使用结构体可以将这些数据打包在一起,使代码更整洁、更易管理。
2. 如何定义结构体?
使用struct
关键字定义结构体,后面跟着结构体名称和一对花括号{},括号内定义成员变量。
struct Student { // 定义名为Student的结构体
int id; // 学号
string name; // 姓名
int age; // 年龄
float gpa; // 平均成绩
}; // 注意结尾的分号
int id; // 学号
string name; // 姓名
int age; // 年龄
float gpa; // 平均成绩
}; // 注意结尾的分号
注意:结构体定义结尾的分号;
不能省略!
重要细节:
- 结构体定义通常放在main函数外面(全局位置)
- 结构体名称通常首字母大写(约定俗成,非强制)
- 成员变量可以是任意C++数据类型,甚至是其他结构体
3. 创建结构体变量
定义结构体后,就可以像使用基本类型(int, float等)一样创建结构体变量。
创建单个结构体变量:
// 创建Student类型的变量
Student s1; // 名为s1的学生
Student s2; // 名为s2的学生
Student s1; // 名为s1的学生
Student s2; // 名为s2的学生
创建结构体数组:
// 创建包含30个学生的数组
Student class1[30];
Student class1[30];
创建结构体指针:
Student* ptr = &s1; // 指向s1的指针
4. 访问结构体成员
使用点运算符.
访问结构体变量的成员,使用箭头运算符->
访问结构体指针的成员。
访问普通变量成员:
Student s1;
s1.id = 1001; // 设置学号
s1.name = “张三”; // 设置姓名
s1.age = 18; // 设置年龄
s1.gpa = 3.75; // 设置GPA
cout << s1.name; // 输出姓名
cout << s1.gpa; // 输出GPA
s1.id = 1001; // 设置学号
s1.name = “张三”; // 设置姓名
s1.age = 18; // 设置年龄
s1.gpa = 3.75; // 设置GPA
cout << s1.name; // 输出姓名
cout << s1.gpa; // 输出GPA
访问指针成员:
Student s1;
Student* ptr = &s1; // ptr指向s1
ptr->id = 1002; // 相当于s1.id = 1002
ptr->name = “李四”; // 相当于s1.name = “李四”
cout << ptr->age; // 输出年龄
Student* ptr = &s1; // ptr指向s1
ptr->id = 1002; // 相当于s1.id = 1002
ptr->name = “李四”; // 相当于s1.name = “李四”
cout << ptr->age; // 输出年龄
5. 初始化结构体
结构体有多种初始化方式,可以在创建变量时直接初始化。
方式1:按顺序初始化
// 按定义成员的顺序提供值
Student s1 = {1003, “王五”, 19, 3.8};
Student s1 = {1003, “王五”, 19, 3.8};
方式2:指定成员初始化(C++11及以上)
// 明确指定成员赋值,顺序无关
Student s2 {
.id = 1004,
.name = “赵六”,
.age = 20,
.gpa = 3.9
};
Student s2 {
.id = 1004,
.name = “赵六”,
.age = 20,
.gpa = 3.9
};
方式3:创建后逐个赋值
Student s3;
s3.id = 1005;
s3.name = “钱七”;
s3.age = 21;
s3.gpa = 4.0;
s3.id = 1005;
s3.name = “钱七”;
s3.age = 21;
s3.gpa = 4.0;
6. 结构体与函数
结构体可以作为函数参数传递,也可以作为函数返回值。
结构体作为函数参数:
// 打印学生信息的函数
void printStudent(Student s) {
cout << "ID: " << s.id << endl;
cout << "姓名: " << s.name << endl;
cout << "年龄: " << s.age << endl;
cout << "GPA: " << s.gpa << endl;
}
// 调用函数
printStudent(s1);
void printStudent(Student s) {
cout << "ID: " << s.id << endl;
cout << "姓名: " << s.name << endl;
cout << "年龄: " << s.age << endl;
cout << "GPA: " << s.gpa << endl;
}
// 调用函数
printStudent(s1);
结构体作为返回值:
// 创建学生信息的函数
Student createStudent(int id, string name, int age, float gpa) {
Student s;
s.id = id;
s.name = name;
s.age = age;
s.gpa = gpa;
return s; // 返回结构体
}
// 调用函数
Student newStudent = createStudent(1006, “孙八”, 22, 3.95);
Student createStudent(int id, string name, int age, float gpa) {
Student s;
s.id = id;
s.name = name;
s.age = age;
s.gpa = gpa;
return s; // 返回结构体
}
// 调用函数
Student newStudent = createStudent(1006, “孙八”, 22, 3.95);
7. 结构体嵌套
一个结构体中可以包含另一个结构体作为其成员,这称为结构体嵌套。
struct Date {
int year;
int month;
int day;
};
struct Student {
int id;
string name;
Date birthday; // 嵌套Date结构体
float gpa;
};
// 使用嵌套结构体
Student s;
s.id = 1007;
s.name = “周九”;
s.birthday.year = 2003; // 访问嵌套成员
s.birthday.month = 5;
s.birthday.day = 15;
s.gpa = 3.85;
int year;
int month;
int day;
};
struct Student {
int id;
string name;
Date birthday; // 嵌套Date结构体
float gpa;
};
// 使用嵌套结构体
Student s;
s.id = 1007;
s.name = “周九”;
s.birthday.year = 2003; // 访问嵌套成员
s.birthday.month = 5;
s.birthday.day = 15;
s.gpa = 3.85;
8. 结构体与类的区别
在C++中,结构体(struct)和类(class)非常相似,但有一个关键区别:
特性 | 结构体(struct) | 类(class) |
---|---|---|
默认访问权限 | public (公有) | private (私有) |
继承默认权限 | public | private |
常见用途 | 数据集合(纯数据) | 对象(数据+方法) |
用法 | 简单数据打包 | 面向对象编程 |
注意:现代C++中,结构体也可以包含成员函数、构造函数等,与类几乎相同。主要区别仅在于默认访问权限。
结构体使用总结
- 何时使用结构体:当你需要将一组相关的数据组合在一起时
- 优势:提高代码可读性、组织性和可维护性
- 典型应用场景:
- 表示点坐标 (x, y)
- 存储学生/员工信息
- 表示复数 (实部+虚部)
- 游戏开发中的角色属性
- 任何需要组合数据的场景
- 最佳实践:
- 给结构体起一个描述性的名字
- 成员变量名要清晰表达其含义
- 相关函数可以放在结构体内部或外部
- 对于大型对象,考虑使用类(class)