考纲要求
- 掌握结构体的定义语法,把不同类型的数据组合成一个整体。
- 会用点运算符访问成员,能定义结构体变量、结构体数组并初始化。
- 能对结构体数组按某个成员排序或查找。
- 理解结构体变量之间可以整体赋值,但比较需要逐成员进行。
典型题型
- 定义学生结构体并读入若干学生信息。
- 按成绩排序或查找最高分学生。
- 判断结构体变量赋值与比较的行为。
常见错误
- 结构体定义末尾漏写分号,编译报错。
- 用等于运算符直接比较两个结构体变量,C++ 不允许这样比较。
- 排序时只交换某个成员,导致字段之间的对应关系被打乱。
- 访问成员用错运算符,把点写成箭头,或对普通变量使用箭头。
深入理解
结构体把一条记录打包
描述一个学生需要姓名、学号、成绩三个字段时,用三个平行数组容易错位,用结构体就自然了:
struct Student {
string name;
int id;
double score;
};
Student s = {"Tom", 1, 92.5};
cout << s.name << s.score;注意定义结构体时末尾的 ; 不能省,这是最常见的编译错误之一。访问成员用 .;如果有指向结构体的指针,用 ->,p->name 等价于 (*p).name。
结构体数组与整体操作
Student a[100]; 定义一个结构体数组,a[i].score 访问第 i 个学生的成绩。两个同类型结构体可以直接赋值 s1 = s2,会逐个成员复制;可以直接比较吗?不行——C++ 没有为结构体自动生成 ==,要比较得自己写函数或者逐字段比较。
结构体之间也不能直接用 < 排序。用 sort 时必须提供比较规则,例如按成绩从高到低、成绩相同按学号从小到大:
bool cmp(const Student &a, const Student &b) {
if (a.score != b.score) return a.score > b.score;
return a.id < b.id;
}为什么排序规则要写成两段
上面 cmp 的第二行是「主关键字相同再比次关键字」。如果只写 return a.score > b.score;,成绩相同的学生顺序就不确定了,而题目常常要求「成绩相同按学号升序」。两段式写法的模板是:主关键字不同时按主关键字决定,相同时才看次关键字。
参数写成 const Student & 是固定习惯:& 避免拷贝整个结构体,const 保证比较过程不会改数据。写成长传值也能通过编译,但数据量大时会明显变慢。
自编例题
按总分排序结构体数组
有 n 名学生,每人有编号和三科成绩,按总分从高到低输出编号。
struct Student { int id, a, b, c; } s[1005];
sort(s, s + n, [](const Student &x, const Student &y) {
return x.a + x.b + x.c > y.a + y.b + y.c;
});
for (int i = 0; i < n; i++) cout << s[i].id << ' ';结构体把编号和三科成绩绑定在一起,排序时整个结构体一起移动,字段之间的对应关系不会乱。比较函数把两名学生的总分相比较,按从大到小排列。如果只排序分数组、再单独找对应编号,就会出现编号与成绩错位的问题。实际考试中也可以用冒泡排序,交换时交换整个结构体变量,效果相同。
相关真题
这块内容在整条路线里的位置:GESP C++ 4 级备考路径。
READY TO START
开始练习
先做一套本级别测评,报告会指出哪些知识点需要重点补;再回到本页对照考纲要求逐条核对,把不确定的条目记下来集中练。
常见问题
结构体和数组有什么区别?
数组要求所有元素类型相同,按位置访问;结构体可以包含不同类型的成员,按名字访问,适合表示一条记录。
结构体能作为函数参数吗?
可以。值传递会复制整个结构体,成员多时建议用 const 引用传递,需要修改时用引用传递。
结构体可以嵌套吗?
可以。结构体的成员本身也可以是另一个结构体,访问时逐层使用点运算符即可。
