GESP C++ 4 级 · 知识点

结构体

GESP C++ 四级要求掌握结构体的定义与使用,能用结构体组织相关的多个字段,并按某个字段比较、排序。结构体是把「一条记录」当成整体处理的基础工具。

对应知识域:结构体相关真题 4 套

本页为本站原创整理,例题与解析均由本站编写,不取自任何题库原题;考试范围以 CCF 官方公布为准,本平台不是 GESP 官方平台。

考纲要求

  • 掌握结构体的定义语法,把不同类型的数据组合成一个整体。
  • 会用点运算符访问成员,能定义结构体变量、结构体数组并初始化。
  • 能对结构体数组按某个成员排序或查找。
  • 理解结构体变量之间可以整体赋值,但比较需要逐成员进行。

典型题型

  • 定义学生结构体并读入若干学生信息。
  • 按成绩排序或查找最高分学生。
  • 判断结构体变量赋值与比较的行为。

常见错误

  • 结构体定义末尾漏写分号,编译报错。
  • 用等于运算符直接比较两个结构体变量,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 引用传递,需要修改时用引用传递。

结构体可以嵌套吗?

可以。结构体的成员本身也可以是另一个结构体,访问时逐层使用点运算符即可。

本级别其他知识点

官方依据