目录
[1. 普通结构体](#1. 普通结构体)
[1.1 显示声明结构体变量](#1.1 显示声明结构体变量)
[1.2 直接声明结构体变量](#1.2 直接声明结构体变量)
[1.3 typedef在结构体中的作用](#1.3 typedef在结构体中的作用)
[2. 结构体的嵌套](#2. 结构体的嵌套)
[3. 结构体数组](#3. 结构体数组)
[4. 指向结构体的指针](#4. 指向结构体的指针)
[4.1 静态分配](#4.1 静态分配)
[4.2 动态分配](#4.2 动态分配)
[1. 学生数据库](#1. 学生数据库)
[2. 书籍信息](#2. 书籍信息)
一、实验要求
-
能够理解结构体的定义和基本概念。
-
熟练掌握结构体的初始化、访问和应用,包括数组的使用。
-
理解结构体与指针的关系,能够使用指针访问结构体成员。
二、实验原理
1. 普通结构体
cpp
struct 结构体名称 {
// 成员变量定义
};
1.1 显示声明结构体变量
在结构体定义之后,显式声明结构体变量。
例如
cpp
struct Person {
char name[20];
int age;
};
struct Person person1; // 显式声明结构体变量
最后一行代码创建了结构体的实例化person1
eg:
cpp
#define _CRT_SECURE_NO_WARNINGS //消除strcpy带来的警告
#include<iostream>
using namespace std;
struct Person {
char name[20];
int age;
};
int main() {
struct Person person1,person2; // 显式声明结构体变量
person1 = { "xiaoming",18 };
//或者用下面这种方式赋值
strcpy(person2.name, "xiaofang");//直接复制进去
person2.age = 19;
cout << person1.name << " " << person1.age << endl;
cout << person2.name << " " << person2.age << endl;
return 0;
}
结果
分析
1.#define _CRT_SECURE_NO_WARNINGS:
这是一个预处理指令,用于在编译时禁用某些与安全性检查相关的警告,主要用于 Microsoft Visual Studio 编译器。在此例中,用于消除 strcpy 可能引发的安全性警告。
2.struct Person:
定义了一个结构体 Person,包含一个名为 name 的字符数组和一个名为 age 的整数。
3.main 函数:
创建了两个 Person 结构体变量 person1 和 person2。
person1 使用了类似于初始化列表的方式直接赋值,这在 C++11 及以后的标准中是合法的。
person2 使用了 strcpy 函数将字符串 "xiaofang" 复制到 name 成员中,并通过直接赋值给 age 进行赋值。
1.2 直接声明结构体变量
在结构体定义的同时直接声明结构体变量。
例如
cpp
struct Point {
int x;
int y;
} p1, p2; // 直接声明结构体变量 p1 和 p2
定义结构体Point的同时实例化p1,p2
对其赋值
cpp
#include<iostream>
using namespace std;
struct Point {
int x;
int y;
} p1, p2; // 直接声明结构体变量 p1 和 p2
int main() {
p1 = { 3,4 };
p2 = { 5,6 };
cout << p1.x <<" "<< p1.y << endl;
cout << p2.x << " " << p2.y << endl;
return 0;
}
p1,p2是全局变量
使用直接声明结构体变量的好处就是简单且可以声明全局变量
1.3 typedef在结构体中的作用
typedef
是 C 语言中用来给数据类型取别名的关键字。在结构体的定义中,使用 typedef
可以简化对结构体类型的引用。
不使用typedef:
cpp
struct Point {
int x;
int y;
};
struct Point p1;
使用typedef:
cpp
typedef struct {
int x;
int y;
} Point;
Point p1;
一个是定义简单,实例化复杂些,一个是定义麻烦,实例化简单些
由于结构体只用定义一次,而结构体可能需要多次实例化,建议用typedef struct定义结构体
2. 结构体的嵌套
在结构体中嵌套其他结构体,形成复合结构体。
cpp
struct 结构体A {
// 成员变量定义
struct 结构体B {
// 成员变量定义
} 变量名B;
};
上述代码在结构体A中定义了一个结构体B,并实例化B
eg:
cpp
struct A {
struct B {
int year;
}student;
int grade;
}xiaoming,xiaofang;
- 定义了一个结构体
A
,其中嵌套了一个结构体B
。结构体B
包含一个整数成员year
。结构体A
包含了一个名为student
的B
类型的成员和一个整数成员grade
。- 同时在全局范围内声明了两个结构体变量
xiaoming
和xiaofang。
通过结构体的嵌套,可以建立更复杂和层次化的数据结构,使得代码更具可读性和可维护性。
对其实例化:
cpp
#include<iostream>
using namespace std;
struct A {
struct B {
int year;
}student;
int grade;
}xiaoming,xiaofang;
int main() {
xiaoming = {{19},93 };
xiaofang.student.year = 18;
xiaofang.grade = 94;
return 0;
}
分析
在
main
函数中,通过初始化列表为xiaoming
赋值。xiaofang
的student.year
和grade
成员分别被单独赋值。切记不能在嵌套中用typedef struct定义结构体!!!
3. 结构体数组
定义数组,每个元素是一个结构体。
即用已定义的结构体来声明一个结构体数组。
cpp
struct 结构体名称 数组名[大小];
例如
cpp
#include<iostream>
using namespace std;
struct Person {
char name[20];
int age;
};
int main() {
struct Person person[3]{ {"xiaofang",17},{"xiaoming",18},{"xiaokai",19} };
for (int i = 0; i < 3; i++) {
cout << person[i].age <<" " <<person[i].name << endl;
}
return 0;
}
结果为
分析
对person数组中的每个元素赋值时要用"{}"
4. 指向结构体的指针
使用指针访问结构体的成员。
cpp
struct 结构体名称 *指针名;
原理类似上一篇文章中的指针
https://mp.csdn.net/mp_blog/creation/editor/135313150
4.1 静态分配
eg:
cpp
#include<iostream>
using namespace std;
struct Person {
char name[20];
int age;
};
int main() {
struct Person person1 = { "Alice", 25 }; // 定义结构体变量
struct Person* ptrPerson = &person1; // 定义指向结构体的指针
cout << ptrPerson->age << " " << ptrPerson->name;
return 0;
}
结果为
需要强调的一点是使用指针时访问结构体的成员,可以使用箭头运算符**"->"****,不能用"."。**
4.2 动态分配
使用 new
运算符动态分配结构体内存,并返回指向该内存的指针。
例如:
cpp
struct Person *ptrPerson2 = new Person;
使用 delete
运算符释放通过 new
分配的结构体内存。
例如:
cpp
delete ptrPerson2;
三、实验内容
1. 学生数据库
定义一个名为 Student 的结构体,用于存储学生信息。结构体应包含以下成员:
rollNumber(整数)
name(最大长度为50的字符串)
marks(浮点数)
编写一个程序,声明一个包含5个 Student 结构体的数组,为每个学生输入信息,然后打印每个学生的详细信息。
代码
cpp
#include<iostream>
using namespace std;
typedef struct Student {
int rollNumber;
char name[50];
float marks;
};
int main() {
Student student[5];
for (int i = 0; i < 5; i++) {
cin >> student[i].rollNumber >> student[i].name >> student[i].marks;
}
for (int i = 0; i < 5; i++) {
cout << student[i].rollNumber<<" " << student[i].name <<" " << student[i].marks<<endl;
}
return 0;
}
截图
分析
这段代码定义了一个名为
Student
的结构体,用于存储学生的信息,包括学号 (rollNumber
)、姓名 (name
) 和成绩 (marks
)。然后,在main
函数中,它声明了一个包含5个Student
结构体的数组student
。接下来,通过一个循环,程序从用户输入中获取每个学生的信息,包括学号、姓名和成绩。最后,通过另一个循环,程序将每个学生的信息输出到标准输出。
2. 书籍信息
代码
cpp
#include<iostream>
using namespace std;
typedef struct Book {
char title[100];
char author[50];
float price;
int publishedYear;
};
int main() {
Book book[3];
int index = 0;
float max_price = 0;
for (int i = 0; i < 3; i++) {
cin >> book[i].title >> book[i].author >> book[i].price>> book[i].publishedYear;
}
for (int i = 0; i < 3; i++) {
if (book[i].price > max_price) {
max_price = book[i].price;
index = i;
}
cout << book[i].title <<" " << book[i].author <<" " << book[i].price << " "<<book[i].publishedYear << endl;
}
cout <<"最贵的书籍为"<< book[index].title;
return 0;
}
截图
分析
这段代码定义了一个名为
Book
的结构体,用于存储书籍的信息,包括书名 (title
)、作者 (author
)、价格 (price
) 和出版年份 (publishedYear
)。然后,在main
函数中,它声明了一个包含3个Book
结构体的数组book
。通过两个循环,程序从用户输入中获取每本书的信息,包括书名、作者、价格和出版年份。同时,它找到了价格最高的书籍,并记录了其索引。最后,通过循环输出每本书的信息,并额外输出价格最高的书籍的标题。