文章目录
- 1 结构体的基本概念
- 2 结构体定义和使用
-
- 2.1 定义结构体
- 2.2 创建结构体变量
- 3 结构体数组
- 4 结构体指针
- 5 结构体嵌套结构体
- 6 结构体作为函数参数
- 7 结构体中const的使用场景
- 8 结构体案例练习
1 结构体的基本概念
结构体是用户自定义的数据类型(内置数据类型的集合),可存储不同的数据类型。
2 结构体定义和使用
2.1 定义结构体
语法:struct 结构体名 { 结构体成员列表 };
例:struct Person { string name, int age};
2.2 创建结构体变量
创建结构体变量的3种方式:
(1)struct 结构体名 结构体变量名;
先创建结构体变量,再对结构体成员进行赋值(使用.
访问结构体变量的属性,即结构体成员)。
例:
struct Person p;
p.name = "Tom";
p.age = 16;
(2)struct 结构体名 结构体变量名 = { 成员1初始值 , 成员2初始值...};
创建结构体变量时进行初始化。
例:
struct Person p = { "Tom", 16};
(3)定义结构体时即创建变量。
struct Person {
string name,
int age
} person;
注1:C++中,定义结构体时,struct关键字不可省略;创建结构体变量时,struct关键字可省略。
注2:结构体变量使用操作符.
访问结构体成员/属性,即结构体变量x.成员a
。
示例:
//结构体定义
struct Person {
string name;
int age;
} p1; //结构体变量创建方式1
int main() {
//结构体变量创建方式2
struct Person p2;
p2.name = "Tom";
p2.age = 16;
//结构体变量创建方式3
struct Person p3 = { "Jerry", 18};
cout << p2.name << "\t" << p2.age << endl;
cout << p3.name << "\t" << p3.age << endl;
return 0;
}
3 结构体数组
作用:将自定义的结构体变量存储至数组中,即结构体变量的数组,方便进行维护。
语法:struct 结构体名 数组名[元素个数] = { {...} , {...} , ... , {...} }
注1:对比基本数据类型的变量和数组:
基本数据类型变量:int var;
基本数据类型数组:int var[5];
结构体变量:struct Person person;
结构体数组:struct Person persons[5];
注2:定义结构体数组时,struct关键字可省略。
示例:
#include <iostream>
using namespace std;
#include <string>
struct Person {
string name;
int age;
};
int main() {
//1.定义时结构体数组时初始化(可省略struct关键字)
Person persons[3] = { { "Tom", 12}, { "Jerry" , 13} };
//2.修改结构体数组元素
persons[2].name = "Lucy";
persons[2].age = 16;
for (int i = 0; i < sizeof(persons) / sizeof(persons[0]); i++) {
cout << "姓名:" << persons[i].name << ",年龄:" << persons[i].age << endl;
}
return 0;
}
4 结构体指针
作用:利用结构体指针访问或操作结构体成员。
注1:对比基本数据类型的指针:
基本数据类型指针:int *p = &var;
结构体指针:struct Person *p = &person;
//结构体指针类型需与结构体类型相匹配
注2:结构体指针使用操作符
->
访问结构体成员/属性,即结构体指针p -> 成员a
。
注3:定义结构体指针时,struct关键字可省略。
示例:
#include <iostream>
using namespace std;
#include <string>
struct Person {
string name;
int age;
};
int main() {
//1.创建结构体变量
Person person = { "Tom", 12};
//2.创建指向结构体变量的结构体指针(struct关键字可省略)
Person *p = &person;
//使用结构体变量访问成员
cout << "姓名:" << person.name << ",年龄:" << person.age<< endl;
//使用结构体指针访问成员
cout << "姓名:" << p->name << ",年龄:" << p->age << endl;
return 0;
}
5 结构体嵌套结构体
作用: 结构体中可定义其它结构体作为成员,用于解决实际问题。
注:作为结构体成员(被包含)的结构体需预先定义,否则编译器报错:结构体A使用未定义的struct “B”。
示例:每门课程对应一个老师,课程的结构体成员记录老师结构体。
#include <iostream>
using namespace std;
#include <string>
struct teacher {
string name;
int age;
};
struct course {
string courseName;
struct teacher t;
};
int main() {
course c;
c.courseName = "C++";
c.t.name = "老王";
c.t.age = 16;
cout << "课程名:" << c.courseName << ",授课老师:" << c.t.name << ",年龄:" << c.t.age << endl;
return 0;
}
6 结构体作为函数参数
作用:将结构体作为函数的参数进行传递。
传递方式有2种:
(1)值传递:函数参数使用结构体变量接收值(结构体变量)。
(2)地址传递:函数参数使用结构体指针接收地址(结构体变量的地址)。
注1:若不希望修改实参,则使用值传递(函数形参使用
结构体类型
接收结构体变量
的实参)。形参的改变不影响实参。
注2:若希望修改实参,则使用地址传递(函数形参使用结构体指针
接收结构体变量地址
的实参)。形参的改变会影响实参。
示例:
#include <iostream>
#include <string>
using namespace std;
struct Person {
string name;
int age;
};
void func_value(struct Person person) {
person.name = "Jerry";
person.age = 15;
cout << "结构体变量作为函数参数传递:" << person.name << "\t" << person.age << endl;
}
void func_address(struct Person *p) {
p->name = "Lucy";
p->age = 20;
cout << "结构体指针作为函数参数传递:" << p->name << "\t" << p->age << endl;
}
int main(){
struct Person person = { "Tom", 10 };
func_value(person); //Jerry 15
cout << "main函数中的结果:" << person.name << "\t" << person.age << endl; //Tom 10
func_address(&person); //Lucy 20
cout << "main函数中的结果:" << person.name << "\t" << person.age << endl; //Lucy 20
return 0;
}
7 结构体中const的使用场景
作用:使用const可避免数据被修改的误操作(不可写)。
场景:值传递过程有更大的内存开销,会拷贝新的副本(结构体成员越多,内存占用越大)。地址传递过程(形参改为指针)可减少内存空间占用,不会拷贝新的副本且指针类型仅占用4字节;为避免数据被修改等误操作,可使用const关键字将函数形参的指针限定为常量指针,无法进行解引用赋值操作(限定为只读不可写状态)。
注1:对函数参数的结构体指针使用const关键字修饰后,无法通过结构体指针使用操作符
->
修改结构体成员的值(可读不可写
),否则编译器报错:表达式必须是可修改的左值。
注2:const关键字的作用:限定为只读状态,防止修改操作(不可写)。
示例:
struct Person {
string name;
int age;
};
void func_address(const struct Person* p) {
//使用const关键字修饰结构体指针后,不能通过结构体指针修改结构体成员的值
//p->age = 20;
cout << "结构体指针作为函数参数传递:" << p->name << "\t" << p->age << endl;
}
int main() {
struct Person person = { "Tom", 10 };
func_address(&person); //Tom 10
cout << "main函数中的结果:" << person.name << "\t" << person.age << endl; //Tom 10
return 0;
}
8 结构体案例练习
练习:设计学生结构体,包含姓名与成绩,创建结构体数组存储若干名学生;使用冒泡排序实现结构体数组中学生成绩的降序排序。
#include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int score;
};
void bubbleSort(struct Student students[], int length) {
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - i - 1; j++) {
if(students[j].score < students[j + 1].score){ //降序排序
struct Student temp = students[j];
students[j] = students[j + 1];
students[j + 1] = temp;
}
}
}
}
int main() {
//创建学生结构体数组
struct Student stus[3] = {
{ "张三" , 89},
{ "李四" , 68},
{ "王五" , 95}
};
int len = sizeof(stus) / sizeof(stus[0]);
//冒泡排序:实现成绩降序排序
bubbleSort(stus, len);
for (int i = 0; i < len; i++) {
cout << "姓名:" << stus[i].name << ",成绩:" << stus[i].score << endl;
}
return 0;
}