Day 06 C++入门 之 结构体
Day 06 C++入门 之 结构体
一、结构体的基本概念
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。是一些类型集合组成的一个大类型家庭。
在这个结构体中可以包含多个类型的变量,比如学生类型可以包含学号、姓名、性别、成绩等。里面的学号等叫做这个结构体的成员变量,使用成员变量用:**结构体名.成员名;**或者 结构体指针- > 成员名。
二、结构体的定义和使用
1. 定义结构体语法:struct 结构体名 {结构体成员列表}
// 创建一个学生的数据类型(结构体类型)
struct Student
{
int num;// 成员1-学号
string name;// 成员2-姓名;
int age; // 成员3-年龄
int score;// 成员4-成绩
};
这个结构体的数据类型为:struct Student
2. 通过结构体创建变量的方式有三种:
- struct 结构体名 变量名,稍后单独进行赋值
- struct 结构体名 变量名 = { 成员1值,成员2值…},在创建变量的时候就进行赋值了
- 定义结构体的时候顺便创建变量,有时候找不到,一般不推荐使用。
// 1. struct 结构体名 变量名
struct Student S1;// 创建学生变量1-学生1号
S1.num = 01;// 给成员变量赋值
S1.name = "李四";
S1.age = 20;
S1.score = 77;
// 2. struct 结构体名 变量名 = { 成员1值,成员2值...}
struct Student S2 = {02,"张三",20,88};
// 3. 定义结构体的时候顺便创建变量
struct Student
{
int num;// 成员1-学号
string name;// 成员2-姓名;
int age; // 成员3-年龄
int score;// 成员4-成绩
}S3;
S3.num = 03;// 给成员变量赋值
S3.name = "懒羊羊";
S3.age = 7;
S3.score = 100;
在C++中,结构体创建变量时,struct 关键字可以省略,但定义不可以省略。通过字符 “ . ” 访问成员
三、结构体数组
作用:将自定义的结构体放入到数组中方便维护。即这个数组的每一个元素都是一个结构体。
语法:struct 结构体名 数组名 [ 元素个数 ] = {{结构体1},{结构体2},{结构体3}… };
// 结构体定义
struct Student
{
int num;// 成员1-学号
string name;// 成员2-姓名;
int age; // 成员3-年龄
int score;// 成员4-成绩
};
// 创建一个结构体数组
struct Student A[3] =
{
{01,"张三",20,88},
{02,"李四",20,66},
{03,"懒羊羊",7,100}
};
// 给结构体数组的元素进行赋值
A[1].name = "喜羊羊";
结构体数组先是一个数组,所以访问的时候通过下标进行索引,其次内部元素是一个结构体,访问内部的成员变量就用 . 进行访问、赋值等操作。
四、结构体指针
作用:通过指针访问结构体中的成员;利用操作符 “ -> ”可以通过结构体指针访问结构体的成员变量。
//创建结构体
...
//创建结构体变量
struct Student S5 = {05,"沸羊羊",20,88};
//通过指针指向结构体变量
struct Student* p = &S5;//创建变量时,关键字struct可以省略,写成Student* p = &s5
// 通过指针访问
p->name = "暖羊羊";
结构体变量本身是一个变量,所以用指针指向时,要用取地址符 &。
五、结构体嵌套结构体
作用:一个结构体的成员可以是另一个结构体。
比如:老师本身可以是一个结构体(编号、年龄、名字、所带学生),学生也是一个结构体
//定义学生的结构体
struct Student
{
int num;// 成员1-学号
string name;// 成员2-姓名;
int age; // 成员3-年龄
int score;// 成员4-成绩
};
//定义老师的结构体
struct teacher
{
int num;
int age;
string name;
struct Studen s1;//这里要使用学生的结构体,所以要将学生的结构体写在前面
};
//使用
teacher t1;
t1.s1.num =7;//成员变量也是一个结构体,结构体引用成员用 . 来访问,逐层访问即可
成员变量也是一个结构体,结构体引用成员用 . 来访问,逐层访问即可
六、结构体做函数参数
作用:将结构体作为参数向函数中传递。传递方式有两种:值传递、址传递
//将学生传入到一个参数中,进行打印
struct Student
{
int num;// 成员1-学号
string name;// 成员2-姓名;
int age; // 成员3-年龄
int score;// 成员4-成绩
};
//1. 值传递
void Print1(struct Student s)
{
cout<<s.name<<endl;
}
//2. 址传递
void Print2(struct Student* s)
{
cout<< s->name<<endl;
}
//主函数main()中
struct Student s6 = {06,"美羊羊",20,88};
Print1(s6);
Print2(&s6);
自定义的函数要写在主函数之外,但是定义的结构体可以写在主函数中也可以写在主函数之外,但是二者的定义一定要写在调用之前。
注意:值传递中,形参的修改不影响实参;址传递中,形参的改变会影响实参,形参改变,实参也会改变。
七、结构体中 const 使用场景
作用:用const来防止误操作。值传递不会影响,但是址传递会影响。
void Print2(const struct Student* s)//加const,就是只读不写
{
cout<< s->name<<endl;
}
struct Student
{
int num;// 成员1-学号
string name;// 成员2-姓名;
int age; // 成员3-年龄
int score;// 成员4-成绩
};
struct Student s7 = {07,"小灰灰",3,88};
//通过函数打印信息
Print2(&s7);
值传递是进行拷贝赋值的,一般会占用空间,造成浪费,所以更推荐址传递,这样就减少了很多空间的浪费,但是要注意误操作(不小心改值),这个时候就可以用const来防止误操作,在函数定义时的参数列表中加上const。
例子1:
每名老师带5个学生,总共3个老师,设计学生和老师的结构体,老师(姓名、5个学生的数组),学生(姓名、成绩)。创建数组存放3名老师,通过函数给每个老师及其所带的学生的成绩赋值,最终打印出老师数据以及老师所带学生的数据。
#include<iostream>
using namespace std;
#include <string>
#include <ctime>
//创建学生的结构体
struct Student
{
string sName;
int score;
};
//创建老师的结构体
struct teacher
{
string tName;
struct Student sA[5];
};
//信息赋值
void giving(struct teacher B[], int n)
{
string nameSeed = "ABCDE";
//给老师赋值
for (int i = 0; i < n; i++)
{
B[i].tName = "teacher_";
B[i].tName += nameSeed[i];//string类型可以通过加法拼接
//给学生赋值
for (int j = 0; j < 5; j++)
{
B[i].sA[j].sName = "Student_";
B[i].sA[j].sName += nameSeed[j];
//int random = rand()%60+40;//0+40~59+40
int random = rand()%61+40;//0+40~60+40
B[i].sA[j].score = random;
}
}
}
//打印信息函数
void print1(struct teacher B[], int n)
{
for (int i = 0; i < n; i++)
{
cout << B[i].tName << endl;
for (int j = 0; j < 5; j++)
{
//\t,转义字符,让学生的缩进一下
cout <<"\t"<< B[i].sA[j].sName << " " << B[i].sA[j].score << endl;
}
}
}
int main()
{
//随机数种子
srand((unsigned int)time(NULL));//让随机数每次都不一样
//创建3个老师的数组
struct teacher A[3];
int len = sizeof(A) / sizeof(A[0]);
//通过函数给老师赋值以及给学生赋值
giving(A, len);//数组名是一个地址
//打印老师及所带学生的信息
print1(A,len);
system("pause");
return 0;
}
数组名是一个地址,是一个变量,表示传的是地址,是址传递,形参的改变就是实参的改变

例子2:
设计一个羊村结构体,羊村(姓名,年龄,性别),创建结构体数组,数组中存放5名羊羊,通过冒泡排序,将数组中的羊羊们按照年龄进行升序排序,最终打印排序后的结果。
//定义结构体
struct goat
{
string name;
int age;
string sex;
};
//排序函数
void bubbleSort( struct goat A[], int n)
{
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (A[j].age > A[j + 1].age)
{
struct goat temp = A[j];
A[j] = A[j + 1];
A[j + 1] = temp;
}
}
}
}
int main()
{
//创建变量并赋值
struct goat B[5] =
{
{"沸羊羊",13,"男"},
{"懒羊羊",10,"男"},
{"喜羊羊",13,"男"},
{"美羊羊",12,"女"},
{"暖羊羊",13,"女"},
};
//计算数组长度
int len = sizeof(B) / sizeof(B[0]);
cout << "排序前" << endl;
for (int i = 0; i < len; i++)
{
cout << B[i].name << " " << B[i].age << " " << B[i].sex << endl;
};
//调用函数进行排序
bubbleSort(B, len);
cout << "排序后" << endl;
for (int i = 0; i < len; i++)
{
cout << B[i].name << " " << B[i].age << " " << B[i].sex << endl;
};
system("pause");
return 0;
}
更多推荐
所有评论(0)