当前位置: 首页 > news >正文

C++——结构体

1,结构体基本概念

结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。像int(整型),浮点型,bool型,字符串型等都是属于系统内置的数据类型。而今天要学习的结构体则是属于我们自定义的一种数据类型

2,结构体定义和使用

语法:struct 结构体名 { 结构体成员列表 };

通过结构体创建变量的方式有三种,struct关键字不可省略:

  • struct 结构体名 变量名
  • struct 结构体名 变量名 = {成员1值,成员2值...}
  • 定义结构体时顺便创建变量
#include<bits/stdc++.h>
using namespace std;
//1,创建学生数据类型 :学生包括(姓名,年龄,分数)
//自定义数据类型,一些类型集合组成的一个类型
//语法  struct 类型名称{ 成员列表 } 
struct Student{//成员列表//姓名string name; //年龄 int age;//成绩 int score;
}s3;//顺便创建结构体变量s3. 
//2,通过学生类型创建具体学生 
int main(){//2.1 struct Student s1Student s1;s1.name="张三";s1.age=18; s1.score=100;cout<<"姓名: "<<s1.name<<"年龄: "<<s1.age<<"成绩: "<<s1.score<<endl; //2.2 struct Student s2={...}Student s2={"李四",19,80};cout<<"姓名: "<<s2.name<<"年龄: "<<s2.age<<"成绩: "<<s2.score<<endl; //2.3 在定义结构体时顺便创建结构体变量 s3.name="王五";s3.age=20;s3.score=90;cout<<"姓名: "<<s3.name<<"年龄: "<<s3.age<<"成绩: "<<s3.score<<endl; 
} 

结构体在具象化的时候,可以通过三种方式创建具体的类型:

  •  struct Student s1
  •  struct Student s2={...}
  •  在定义结构体时顺便创建结构体变量 

3,结构体数组

作用:将自定义的结构体放入到数组中方便维护,也就是数组中的每一个元素都是我们自定义的同一种数据结构类型,也就是结构体。

语法:struct  结构体名 数组名[元素个数]={ {},{},{},...,{} }

示例:

#include<bits/stdc++.h>
using namespace std;
//结构体数组
struct student{string name;int age;int score;
}; 
int main(){struct student stuarry[3]={{"july",18,100},{"miss.li",20,90},{"zhang",21,130}};stuarry[1].name="san";stuarry[1].age=21;stuarry[1].score=100;for(int i=0;i<3;i++){cout<<"姓名:"<<stuarry[i].name<<endl;cout<<"年龄:"<<stuarry[i].age<<endl;cout<<"成绩:"<<stuarry[i].score<<endl;}
}

4,结构体指针

作用:利用指针访问结构体中的成员

  • 利用操作符->可以通过结构体指针访问结构体属性
struct student{string name;int age;int score;
};
int main(){//创建学生结构体变量student s={"zhang",18,100}; //通过指针指向结构体变量student *p=&s;//通过指针访问结构体变量中的数据 p->age=20;cout<<"name= "<<p->name<<"age= "<<p->age<<"score= "<<p->score<<endl; } 

通过上述例子我们可以总结出来:

  • 指针在定义时,指针等号左右的数据结构要对应,int对int,float对float,struct对struct。

  • 指针通过->操作符可以访问成员

5,结构体嵌套结构体     

作用:结构体中的成员可以是另一个结构体

例如:每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体

嵌套示意图:

#include<bits/stdc++.h>
using namespace std;
struct student{string name;int age;int score;
};//定义学生结构体 
struct teacher{int id;string name;int age;student stu;//代表这个老师所带的学生 
};
int main(){teacher t;t.id=1000;t.age=50;t.name="Mr.li";t.stu.age=10;t.stu.name="xiaowang";t.stu.score=60;cout<<"teacher`s name is "<<t.name<<endl;cout<<"teacher`s age is " <<t.age<<endl;cout<<"teacher`s id is "<<t.id<<endl;cout<<"student`s age is "<<t.stu.age<<endl;cout<<"student`s score is "<<t.stu.score<<endl;cout<<"student`s name is "<<t.stu.name<<endl;
} 

                            

6,结构体做函数参数

作用:将结构体作为参数向函数中传递

传递方式有两种:

  • 值传递(形参修饰不会改变实参)
  • 地址传递(如果函数形参发生改变,实参也会跟着改变)

示例:

#include<bits/stdc++.h>
using namespace std;
struct student{string name;int age;int score;
};//定义学生结构体
void printstudent1(struct student s){s.age=100;cout<<"子函数1中,姓名:"<<s.name<<"年龄为 "<<s.age<<"成绩为 "<<s.score<<endl;
}
void printstudent2(struct student *p){p->age=100;cout<<"子函数2中,姓名:"<<p->name<<"年龄为:"<<p->age<<"成绩为:"<<p->score<<endl; 
}
int main(){student s;s.name="Bob";//实参 s.age=20;s.score=85;printstudent1(s);// 值传递,形参修饰实参,不会改变实参的值 printstudent2(&s);//地址传递 cout<<"main函数中"<<"姓名:"<<s.name<<"年龄为 "<<s.age<<"成绩为 "<<s.score<<endl;
}

 主函数里的赋值为实参,函数中的赋值为形参,大家可以相应修改两种参数传递方式的参数值看看主函数里的实参会怎么变化,得出的结论亦是上面两种结论。值传递修改形参不会改变实参的值,地址传递则会修改实参的值,具体原理参照C++——函数-CSDN博客。

最根本的原理在于:值传递参数时是独立开辟了一些内存空间,而地址传递则是用指针直接指向实参地址

7,结构体中const使用场景

作用:用const来防止误操作

struct student{string name;int age;int score;
};//定义学生结构体
void printstudent(const student *stu){stu->age=30;  加入const之后,一旦有修改的操作就会报错,可以防止我们的误操作cout<<"name is "<<stu->age;
}

上述函数中指针结构体加入const后,结构体中的数据变不允许修改,一旦修改便会报错。

8,结构体案例

案例1

描述:学校正在做毕设项目,每名老师带领五个学生,总共有三名老师,需求如下:

设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员

学生的成员有姓名,考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值

最终打印出老师数据以及老师所带的学生数据。

#include<bits/stdc++.h>
using namespace std;
struct student{string name;int score;	
};//定义学生结构体
struct teacher{string name;student arrstudent[5];
};
//给老师和学生赋值的函数
void teacher(struct teacher array[],int len){string nameseed="ABCDE";for(int i=0;i<len;i++){array[i].name="teacher_";array[i].name+=nameseed[i];for(int j=0;j<5;j++){array[i].arrstudent[j].name="student_";array[i].arrstudent[j].name+=nameseed[j];int random=rand()%60+40;array[i].arrstudent[j].score=random;}}} 
void print(struct teacher array[],int len){for(int i=0;i<len;i++){cout<<" teacher`s name is "<<array[i].name<<endl;for(int j=0;j<5;j++){cout<<"student`s name is "<<array[i].arrstudent[j].name<<"score is "<<array[i].arrstudent[j].score<<endl;} }
}int main(){struct teacher array[3]; int len=sizeof(array)/sizeof(array[0]);teacher(array,len);print(array,len);
}

案例2 

设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。

通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。

    {"刘备",23,"男"},
    {"关羽",22,"男"},
    {"张飞",20,"男"},
    {"赵云",21,"男"},
    {"貂蝉",19,"女"}

#include<bits/stdc++.h>
using namespace std;
struct hero{string name;int age;string sex;
};//定义学生结构体
void bubble(struct hero harray[],int len){for(int i=0;i<len-1;i++){for(int j=0;j<len-i-1;j++){if(harray[j].age>harray[j+1].age){struct hero temp=harray[j];//再次定义一个结构体接收。 harray[j]=harray[j+1];harray[j+1]=temp;}}}for(int i=0;i<5;i++){cout<<"排序后姓名为:"<<harray[i].name;cout<<"\t排序后年龄为:"<<harray[i].age;cout<<"\t排序后性别为:"<<harray[i].sex;cout<<endl;}}
int main(){struct hero harray[5]={{"刘备",23,"男"},{"关羽",22,"男"},{"张飞",20,"男"},{"赵云",21,"男"},{"貂蝉",19,"女"} }; int len=sizeof(harray)/sizeof(harray[0]);bubble(harray,len);}

此案例的关键在于,冒泡排序中,要定义一个新的结构体代替作为temp临时代替量接收被替换的全部内容。

http://www.lryc.cn/news/288222.html

相关文章:

  • C++技术要点总结, 面试必备, 收藏起来慢慢看
  • VR数字展厅,平面静态跨越到3D立体化时代
  • Linux中LVM实验
  • 外包干了一个月,技术退步明显。。。。。
  • gitlab.rb主要配置
  • 网络协议基础
  • Mac使用adb调试安卓手机
  • Web 开发 1: Flask 框架介绍和使用
  • Centos7.6之禅道开源版17.6.1安装记录
  • 有趣的代码(简单)
  • Java和Redis实现一个简单的热搜功能
  • 超越传统,想修哪里就修哪里,SUPIR如何通过文本提示实现智能图像修复
  • 《如何画好架构图》学习笔记
  • redis整合
  • 开循环低温样品架节约液氦操作技巧
  • 年薪30W+,待遇翻倍,我的经历值得每个测试人借鉴
  • DEB方式安装elastic search7以及使用
  • [Tomcat] [最全] 目录和文件详解
  • 微信小程序元素/文字在横向和纵向实现居中对齐、两端对齐、左右对齐、上下对齐
  • 兼容树莓派扩展模块,专注工业产品开发的瑞米派强势来袭
  • 云原生 - 微信小程序 COS 对象存储图片缓存强制更新解决方案
  • 设计公司设计ppt的优势—南京梵构广告
  • gitlab设置/修改克隆clone地址端口
  • Jellyfin影音服务本地部署并结合内网穿透实现公网访问本地资源
  • 笨蛋学设计模式行为型模式-责任链模式【18】
  • 【.NET Core】深入理解任务并行库 (TPL)
  • win10安装redis并配置加自启动(采用官方推荐unix子系统)
  • 【大数据面试题】HBase面试题附答案
  • SpringBoot中从HikariCP迁移到Oracle UCP指南
  • 第3章 接口和API设计