结构体:结构体定义、成员访问、结构体数组
结构体,说白了就是让你把一堆不同类型的数据打包成一个整体。我刚开始学C++时,觉得这玩意儿不就是个“大变量”嘛,后来做项目才发现,没有结构体,代码简直没法看。
举个例子,你要描述一个学生。有姓名、年龄、分数。没有结构体时,你得定义三个数组:string names[50]、int ages[50]、float scores[50]。维护起来?嗯,那叫一个痛苦。有了结构体,一个 Student 类型就搞定了。
结构体的定义
定义结构体,用 struct 关键字。语法很简单:
struct Student {
string name;
int age;
float score;
}; // 别忘了分号!
这里我定义了一个 Student 结构体,里面有三个成员。你可以把它理解成一张“蓝图”,告诉编译器:以后凡是 Student 类型的变量,都长这样。
结构体变量的声明与初始化
定义好结构体后,就可以声明变量了:
Student stu1; // 声明一个 Student 变量
Student stu2 = {"张三", 20, 88.5}; // 声明并初始化
注意,初始化时顺序要和定义时一致。我见过有人把年龄和分数写反了,结果一个20岁的小伙子突然变成了88.5岁……
C++11 之后,还支持这种写法:
Student stu3 = {.name = "李四", .age = 22, .score = 91.0};
这种指定初始化方式,可读性更好。我个人比较推荐,尤其是成员很多的时候。
成员访问
访问结构体的成员,用点号 .:
stu1.name = "王五";
stu1.age = 19;
stu1.score = 76.5;
cout << stu1.name << " 的分数是 " << stu1.score << endl;
如果是结构体指针,就得用箭头 ->:
Student* p = &stu1;
p->age = 21; // 等价于 (*p).age = 21
结构体数组
结构体数组,就是数组的每个元素都是一个结构体。处理批量数据时,这玩意儿太好用了。
Student class1[3] = {
{"赵六", 18, 92.0},
{"钱七", 19, 85.5},
{"孙八", 20, 78.0}
};
// 遍历数组
for (int i = 0; i < 3; i++) {
cout << class1[i].name << " 年龄: " << class1[i].age << endl;
}
你想想看,如果没有结构体,你要维护三个数组,还要保证下标一一对应。新增一个学生?三个数组都得改。有了结构体数组,一个循环就搞定了。
结构体作为函数参数
结构体可以传给函数。但要注意:默认是值传递,会拷贝整个结构体。如果结构体很大,性能会受影响。
void printStudent(Student s) { // 值传递,拷贝一份
cout << s.name << endl;
}
void printStudentRef(const Student& s) { // 引用传递,不拷贝
cout << s.name << endl;
}
我建议:如果只是读取数据,用 const &。既避免了拷贝,又保证了数据不被修改。
结构体嵌套
结构体里可以嵌套另一个结构体。比如学生有地址信息:
struct Address {
string city;
string street;
int zipCode;
};
struct Student {
string name;
int age;
float score;
Address addr; // 嵌套结构体
};
访问嵌套成员:
Student stu;
stu.addr.city = "北京";
stu.addr.zipCode = 100000;
这种嵌套结构,在描述复杂实体时非常自然。我在做学生管理系统时就用了这种设计,数据组织得很清晰。
结构体与内存对齐
嗯,这里要注意一个细节:结构体的大小不一定等于成员大小之和。因为编译器会做内存对齐。
struct Example1 {
char c; // 1 字节
int i; // 4 字节
}; // 实际大小可能是 8,而不是 5
为什么会这样?因为 CPU 读取对齐的数据更快。编译器会在 char 后面填充 3 个字节,让 int 对齐到 4 字节边界。
知识体系总览
下面这张图,把结构体的核心知识点串起来了:
完整示例:学生成绩管理系统
最后,给一个综合例子。把上面讲的知识点都用上:
#include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int age;
float score;
};
void inputStudent(Student& s) {
cout << "请输入姓名: ";
cin >> s.name;
cout << "请输入年龄: ";
cin >> s.age;
cout << "请输入分数: ";
cin >> s.score;
}
void printStudent(const Student& s) {
cout << s.name << " | 年龄: " << s.age
<< " | 分数: " << s.score << endl;
}
int main() {
Student students[3];
// 输入
for (int i = 0; i < 3; i++) {
cout << "第" << i+1 << "个学生:" << endl;
inputStudent(students[i]);
}
// 输出
cout << "\n学生信息如下:" << endl;
for (int i = 0; i < 3; i++) {
printStudent(students[i]);
}
return 0;
}
这个例子虽然简单,但包含了结构体定义、数组、引用传参、const 修饰等核心用法。你可以在它的基础上扩展,比如增加查找、排序功能。
公众号:蓝海资料掘金营,微信deep3321