48 4
《计算机程序设计》
计算机学院计算机研究所编译系统研究室
~/course
~/course/main.cpp
main.cpp
,随堂编程练习的代码请直接在此文件中编辑考考你
阅读下列程序,描述其功能
编程实现
使用C++实现一个信息管理系统,要求如下:
学号 | 姓名 | 性别 | 出生年份 | 专业 |
---|---|---|---|---|
2024001 | 张三 | 男 | 2003 | 航空航天 |
2024002 | 李四 | 女 | 2003 | 计算机 |
2024003 | 王五 | 男 | 2004 | 数学 |
2024004 | 赵六 | 男 | 2003 | 航空航天 |
2024005 | 钱七 | 女 | 2004 | 计算机 |
2024006 | 孙八 | 男 | 2003 | 数学 |
学习目标
运用本次课所学内容,实现学员信息管理系统
考考你
使用多个变量表示学员信息,各信息变量分别是什么类型?
学员信息是一个有机整体,独立变量无法信息之间的联系!
学员信息结构体
明察秋毫
C++中,结构体是实现数据封装与抽象的基本手段
struct
关键字struct
后跟结构体名称(标识符)考考你
结构体的成员变量是否可以是任意类型?包括结构体类型?
结构体的结构体成员
明察秋毫
offsetof.cpp
#include <iostream>
struct Student {
// 4B,4B对齐 | 20B,1B对齐 | 1B,1B对齐 | 4B,4B对齐 | 20B,1B对齐
int id; char name[20]; char sex; int birth; char major[20];
};
int main() {
Student s;
std::cout << sizeof(Student) << ' ' << alignof(Student) << std::endl;
std::cout << offsetof(Student, id) << ' ' << offsetof(Student, name) << ' '
<< offsetof(Student, sex) << ' ' << offsetof(Student, birth) << ' '
<< offsetof(Student, major) << std::endl;
return 0;
}
52 4
0 4 24 28 32
Student
结构体存储布局structinit.cpp
struct Student {
int id; // 4B,4B对齐
char name[16]; // 16B,1B对齐
char sex; // 1B,1B对齐
int birth; // 4B,4B对齐
char major[20]; // 20B,1B对齐
};
int main() {
Student zhangsan = {2024001, "张三", 'M', 2003, "航空航天"}; // 初始化所有成员
Student lisi = {2004002, "李四", 'F'}; // 初始化部分成员,其余默认值(0)
Student wangwu = {.id=2005003, .name="王五", .major="计算机"};// 指定初始化列表,可做部分初始化
Student zhaoliu = {.name="赵六", .id=2006004, .sex='M'}; // 指定初始化列表,但成员顺序必须与定义一致
return 0;
}
code/structinit.cpp: In function ‘int main()’:
code/structinit.cpp:12:57: error: designator order for field ‘Student::id’ does not match declaration order in ‘Student’
12 | Student zhaoliu = {.name="赵六", .id=2006004, .sex='M'}; // 指定初始化列表,但成员顺序必须与定义一致
| ^
考考你
请使用嵌套初始化列表,完成嵌套结构体变量的初始化
.
)memberaccess.cpp
#include <cstring>
#include <iostream>
struct Student {
int id; // 4B,4B对齐
char name[16]; // 16B,1B对齐
char sex; // 1B,1B对齐
int birth; // 4B,4B对齐
char major[20]; // 20B,1B对齐
};
int main() {
Student zhangsan = {2024001, "张三", 'M', 2003, "航空航天"};
std::cout << zhangsan.id << ' ' << zhangsan.major << std::endl;
std::strcpy(zhangsan.major, "计算机");
std::cout << zhangsan.id << ' ' << zhangsan.major << std::endl;
return 0;
}
2024001 航空航天
2024001 计算机
->
)ptrmemberaccess.cpp
#include <cstring>
#include <iostream>
struct Student {
int id; // 4B,4B对齐
char name[16]; // 16B,1B对齐
char sex; // 1B,1B对齐
int birth; // 4B,4B对齐
char major[20]; // 20B,1B对齐
};
int main() {
Student zhangsan = {2024001, "张三", 'M', 2003, "航空航天"};
Student *p = &zhangsan;
std::cout << p->id << ' ' << p->major << std::endl;
std::strcpy(p->major, "计算机");
std::cout << p->id << ' ' << p->major << std::endl;
return 0;
}
2024001 航空航天
2024001 计算机
考考你
对象成员运算符(.
)与指针成员运算符(->
)的关系是什么?
p
指向结构体变量s
,即p == &s
,则下列表达式完全等价
s.id
p->id
(*p).id
structinfunc.cpp
#include <cstring>
#include <iostream>
struct Student {
int id; char name[16]; char sex; int birth; char major[20];
};
Student resetName(Student s, const char *name) {
strcpy(s.name, name);
return s;
}
int main() {
Student zhangsan = {2024001, "张三", 'M', 2003, "航空航天"};
Student lisi = resetName(zhangsan, "李四");
return 0;
}
考考你
结构体变量zhangsan
、lisi
以及函数resetName
的参数s
,是否对应内存中同一个结构体变量?
void resetName(Student &s, const char *name)
void resetName(Student &s, const char *name)
考考你
能否通过引用或指针返回结构体以避免拷贝?
returnptr.cpp
#include <cstring>
#include <iostream>
struct Student {
int id; char name[16]; char sex; int birth; char major[20];
};
Student *resetName(Student s, const char *name) {
strcpy(s.name, name);
return &s;
}
int main() {
Student zhangsan = {2024001, "张三", 'M', 2003, "航空航天"};
Student *lisi = resetName(zhangsan, "李四");
std::cout << lisi->name << std::endl;
return 0;
}
code/returnptr.cpp: In function ‘Student* resetName(Student, const char*)’:
code/returnptr.cpp:8:10: warning: address of local variable ‘s’ returned [-Wreturn-local-addr]
8 | return &s;
| ^~
code/returnptr.cpp:6:28: note: declared here
6 | Student *resetName(Student s, const char *name) {
| ~~~~~~~~^
/bin/bash: line 1: 250724 Segmentation fault (core dumped) ./code/returnptr 2>&1
returnnewptr.cpp
#include <cstring>
#include <iostream>
struct Student {
int id; char name[16]; char sex; int birth; char major[20];
};
Student *resetName(Student s, const char *name) {
strcpy(s.name, name);
Student *p = new Student;
*p = s;
return p;
}
int main() {
Student zhangsan = {2024001, "张三", 'M', 2003, "航空航天"};
Student *lisi = resetName(zhangsan, "李四");
std::cout << lisi->name << std::endl;
delete lisi;
return 0;
}
structarray.cpp
#include <cstring>
#include <iostream>
struct Student {
int id; char name[16]; char sex; int birth; char major[20];
};
const int MAX_STUDENTS = 100;
static Student students[MAX_STUDENTS];
int main() {
for (int i = 0; i < MAX_STUDENTS; i++) {
students[i].id = 2024000 + i;
std::cin >> students[i].name >> students[i].sex >> students[i].birth >> students[i].major;
}
int id = 0;
std::cin >> id;
for (int i = 0; i < MAX_STUDENTS; i++) {
if (students[i].id == id) {
std::cout << students[i].name << " " << students[i].sex << " " << students[i].birth << " " << students[i].major << std::endl;
break;
}
}
return 0;
}
功能 | 函数签名 | 说明 |
---|---|---|
查 | Student *find(int id) |
根据学号查找学员 |
改 | Student *update(int id, const char* major) |
修改学员专业 |
增 | Student *add(Student &s) |
新增学员信息 |
删 | Student *remove(int id) |
删除学员信息 |
学员管理系统
#include <cstring>
#include <iostream>
struct Student { int id; char name[16]; char sex; int birth; char major[20]; };
const int MAX_STUDENTS = 100;
static Student students[MAX_STUDENTS];
Student *find(int id);
Student *update(int id, const char* major);
Student *add(Student &s);
Student *remove(int id);
nullptr
nullptr
nullptr
nullptr
--- config: look: handDrawn themeVariables: fontSize: 20px --- mindmap 结构体 结构体的定义与初始化 结构体定义 结构体内存布局 结构体初始化 使用结构体 访问成员变量 对象成员运算符 指针成员运算符 结构体与函数 结构体作为函数参数 返回结构体 结构体数组 学员信息管理系统
学习目标
计算机程序设计