结构体:属于用户自定义的数据类型,允许用户存储不同的数据类型;
结构体定义和使用
通过结构体创建变量的方式有三种:
- struct 结构体名 变量名
- struct 结构体名 变量名 = { 成员1,成员2...}
- 定义结构体时顺便创建变量
#include <iostream>
#include <string>
using namespace std;
// Step 1、创建学生数据类型---结构体是一些类型集合组成的一个类型
// 定义结构体变量
struct student
{
// 成员列表(属性列表)
string name;
int age;
int score;
}s3; // 第三种 定义结构体时顺便创建变量
int main()
{
// Step 2、通过学生类型创建具体学生(有三种方式创建它)
// 第一种 struct student s1(即struct 结构体名 变量名)
struct student s1;
// 给s1的属性赋值
s1.name = "张三";
s1.age = 17;
s1.score = 100;
cout << " Name: " << s1.name<<" Age: "<< s1.age<<" Score: "<<s1.score<< endl; // 通过.来访问结构体的元素
// 第二种 struct student s2 = { ... }
struct student s2
{
"李四", 18, 99
};
cout << " Name: " << s2.name << " Age: " << s2.age << " Score: " << s2.score << endl;
// 第三种 定义结构体时顺便创建变量(见结构体定义处)
s3.name = "阿三";
s3.age = 17;
s3.score = 100;
cout << " Name: " << s3.name << " Age: " << s3.age << " Score: " << s3.score << endl;
system("pause");
return 0;
}
【注意】:C++中,在定义完结构体后,创建具体的结构体变量时可以不加struct关键字。
结构体数组
作用:将自定义的结构体放入到数组中方便维护
struct 结构体名 数组名[元素个数] = { {...}. {...}, ...{...} }
【注意】在创建结构体变量之前一定要事先定义了相应的结构体。
结构体指针(结构体xx类型的指针)
作用:通过指针来访问结构体中的成员(利用操作符->可以通过结构体指针访问结构体的属性)
#include <iostream>
#include <string>
using namespace std;
struct student
{
// 成员列表(属性列表)
string name;
int age;
int score;
};
int main()
{
// 1、创建结构体变量
struct student s1 = { "qianqian", 18, 90 };
// 2、通过指针指向结构体变量(注意指针类型要和结构体类型一致)
student *p = &s1;
// 3、通过指针访问结构体变量中的数据
cout << "name = :" << p->name << endl; // 通过结构体指针访问结构体变量中的属性需要利用操作符 ->
system("pause");
return 0;
}
结构体嵌套结构体
作用:结构体中的成员可以是另一个结构体
举例:每个老师辅导一个学员,一个老师的结构体中就需要嵌套有一个学生的结构体
#include <iostream>
#include <string>
using namespace std;
struct student
{
// 成员列表(属性列表)
string name;
int age;
int score;
};
struct teacher
{
int id;
string name;
int age;
struct student xiaowang; // 注意:学生的结构体需要写在老师的结构体之前
};
结构体作为函数参数
作用:将结构体作为参数向函数中传递
传递方式有两种:1、值传递(不会改变原来的结构体) 2、地址传递(会改变原来的结构体)
#include <iostream>
#include <string>
using namespace std;
void printStudent(struct student s);
void printStudent_2(struct student *s);
struct student
{
// 成员列表(属性列表)
string name;
int age;
int score;
};
int main()
{
// 结构体做函数参数
// 将学生的结构体传入到一个参数中,打印学生身上的所有信息
struct student s1;
s1.age = 10;
s1.name = "小明";
s1.score = 100;
printStudent(s1);
cout << "值传递后main函数中的打印结果:" << s1.name << endl;
printStudent_2(&s1);
cout << "地址传递后main函数中的打印结果:" << s1.name << endl;
system("pause");
return 0;
}
// 1、值传递(不会改变原来的结构体)
void printStudent(struct student s) // 注意传进来的结构体类型必须是学生student类型
{
s.age = 10;
s.name = "小王";
s.score = 100;
cout << "printStudent函数中的打印结果:" << s.name << endl;
}
// 2、地址传递(会改变原来的结构体)
void printStudent_2(struct student *s) // 用指针来保存地址,注意指针类型
{
s->age = 10; // 通过指针来访问结构体元素时用的是操作符 ->
s->name = "小王";
s->score = 100;
cout << "printStudent_2函数中的打印结果:" << s->name << endl;
}
结构体中const的使用场景
作用:用const来防止误操作
#include <iostream>
#include <string>
using namespace std;
struct student
{
// 成员列表(属性列表)
string name;
int age;
int score;
};
void printStudents(const student *s); // 注意这句要写在student结构体之后
int main()
{
// 结构体中const的应用场景(const防止误操作)
// 特别是该结构体很大时,如果用值传递的方式去操作,那么就会造成很大的额外开销
// 所以一般是用 地址传递 加 const的方式来操作
struct student s = { "xiaoming", 19, 99 };
printStudents(&s);
system("pause");
return 0;
}
void printStudents(const student *s) // 将形参改为指针,可以减少内存空间,而且不会复制新的副本
{
//s->age = 100; // 加入const之后,一旦有修改的操作就会报错
cout << "age = :" <<s->age << endl;
}
// const student *s是一个常量指针,即其指向的是一个常量,也即传进来的结构体是一个常量
// const student *s是一个常量指针,即其指向的是一个常量,也即传进来的结构体是一个常量
常量指针见我上一篇文章。