重温C语言十四-----结构体与共用体
文章目录
- 结构体和共用体
- 1.基本介绍
- -1,需求:
- 2.走向结构体
- -1.结构体关系图
- -2,面向对象的方式(struct)解决养猫的问题
- -3.结构体和结构体变量的区别与联系
- -4,结构体在内存中的布局
- -6.成员
- (1)基本介绍
- (2)注意事项与细节说明:
- -7.创建结构体和结构体变量
- -8.成员的获取与赋值
- 3.结构体应用实例
- -1.步骤
- -2.小狗案例
- -3.盒子案例
- -4.景区门票案例
- 4.共用体
- -1.基本介绍
- -2.走向共用体
- 1)介绍
- -3最佳实践:
结构体和共用体
1.基本介绍
-1,需求:
张老太养了两只猫猫:一只名字叫做小白,今年3岁,白色。还有一只叫小花,今年100岁,花色,请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示张老太没有这只猫猫
解决方案:
传统技术解决:
1)单独定义变量解决
void main(){char cat1Name[10]="小白";
int cat1Age=3;
char cat1Color="白色";
}
2)我们学习了数组,他是一组具有相同类型的数据的集合。在编程中,我们往往还需要一组类型不同的数据,例如猫的名字使用字符串、年龄是int,因为数据类型不同,不能使用一个数组来存放。
void main(){char *catsName[]={"小白","小花",}
}
int catsAge[]={3,100};
传统方案的问题:
不利于数据的管理和维护,因为本身猫的三个属性(名字,年龄,颜色)是一个整体,传统解决方法是将其分解。
新技术====>>结构体
2.走向结构体
-1.结构体关系图
进一步阐述:
-2,面向对象的方式(struct)解决养猫的问题
#include <stdio.h>
//养猫问题使用结构体解决
/** 分析:* 1。猫有三个成员变量组成* 2,使用结构体*/
//创建结构体 Cat
void main(){//创建结构体 Catstruct Cat{//结构体的名字 Cat,我们自己构造的一个数据类型char *name;//名字,使用指针,指向一个字符串int age;//年龄char *color;//颜色};//要加 ;号//使用Cat结构体,创建变量struct Cat cat1;//cat1就是Struct Cat的一个变量struct Cat cat2;//cat2就是Struct Cat的一个变量//给cat1的各个成员进行赋值cat1.name="小白";cat1.age=3;cat1.color="白色";//给cat2的各个成员赋值cat2.name="小花";cat2.age=100;cat2.color="花色";//输出两只猫的信息printf("\n第一只猫name=%s age=%d color=%s",cat1.name,cat1.age,cat1.color);printf("\n第二只猫name=%s age=%d color=%s",cat2.name,cat2.age,cat2.color);
/*运行结果:第一只猫name=小白 age=3 color=白色第二只猫name=小花 age=100 color=花色Process finished with exit code 37
*/
}
-3.结构体和结构体变量的区别与联系
通过上面的案例我们可以看出:
1)结构体是自定义的数据类型,表示的是一种数据类型
2)结构体变量代表一个具体变量好比
int num1; int 是数据类型,而num1是一个具体的变量
struct Cat cat1; //Cat 是结构体数据类型,而cat1是一个Cat变量
3)Cat就像一个模板,定义出来的结构体变量都含有相同的成员。也可以将结构体比作"图纸",将结构体变量比作“零件”。根据同一张图纸生产出来的零件的特性都是一样的。
-4,结构体在内存中的布局
struct Cat cat1;cat1.name="小白";cat1.age=3;cat1.color="白色";
在内存中的布局
-5.结构体的声明
struct 结构体名称{//结构体名首字母大写,比如 Cat,Person成员列表;
}
例子:
struct Student{char *name;//姓名int num;//学号int age;//年龄char group;//所在学习小组float score;//成绩//成员也可以是结构体
}
-6.成员
(1)基本介绍
1)从叫法上看:有些书称为成员,有些书说,结构体包含的变量
2)成员是结构体的一个组成部分,一般是一些基本数据类型;也可以是数组、指针、结构体等。比如我们前面定义Cat结构中的int age就是一个成员。
(2)注意事项与细节说明:
成员声明语法同变量,实例:数据类型 成员名
字段的类型可以为:基本类型、数组或指针、结构体等
在创建一个结构体变量后,需要给成员赋值,如果没有赋值就使用可能导致程序异常终止
#include <stdio.h> void main(){struct Cat{char *name;//名字int age;//年龄char *color;//颜色};struct Cat cat3;//定义了一个结构体变量cat1;cat3.name;cat3.age;cat3.color;printf("\n-猫name=%s age=%d color=%s",cat3.name,cat3.age,cat3.color); }
不同结构体变量的成员是否独立,互不影响。,一个结构体变量的成员更改,不影响另一个。
#include <stdio.h>
void main(){struct Cat{char *name;//名字int age;//年龄char *color;//颜色};struct Cat cat3;//定义了一个结构体变量cat1;cat3.name="小白";cat3.age=3;cat3.color="白色";printf("\n-猫name=%s age=%d color=%s",cat3.name,cat3.age,cat3.color);
}
-7.创建结构体和结构体变量
1)方式1-先定义结构体,然后再创建结构体变量
struct Stu{char *name;//姓名
int num;//学号
int age;//年龄
char group;//所在学习小组
float score;//成绩
};//要加;
struct Stu stu1,stu2;
//定义了两个变量stru1和sru2,他们都是Stu类型,都由5个成员组成
//注意关键字struct不能少
2)方式2-在定义结构体的同时定义结构体变量
struct Stu{char *name;//姓名
int num;//学号
int age;//年龄
char group;//所在学习小组
float score;//成绩
}stu1,stu2;
//在定义结构Stu的同时,创建了两个结构体变量stu1和stu2;
3)方式3-如果只需要stu1,stu2两个变量,后面不需要在使用结构体名定义其他变量,在定义时也可以不给出结构体名
struct {//没有写Stuchar *name;//姓名int num;//学号int age;//年龄char group;//所在学习小组float score;//成绩
}stu1,stu2;
stu1.name="tom";
stu1.num=100;....
//1.该结构体数据类型,没有名,匿名结构体
//2.stu1和stu2就是该结构体的两个变量
-8.成员的获取与赋值
结构体与数组类似,也是一组数据的集合,整体使用没有太大意义。数组使用下标[]获取单个元素,结构体使用点号.获取单个成员。获取结构体成员的一般格式为结构体变量名.成员名
1)案例1:
struct {//没有写Stuchar *name;//姓名int num;//学号int age;//年龄char group;//所在学习小组float score;//成绩
}stu1;
stu1.name="jack";
printf("%s",stu1.name)
2)案例2
#include <stdio.h>
void main(){struct Student{char *name;int num;//学号int age;//年龄char group;//所在学习小组float score;//成绩}stu1={"贾宝玉",11,18,'B',90.50},stu2={"林黛玉",12,16,'A',100};
printf("\nstu1.name=%s",stu1.name);
struct Student stu3={"林黛玉2",12,16,'A',100};printf("\nstu3.name=%s",stu3.name);struct Student stu4;//stu4={"林黛玉2",12,16,'A',100};//erro,这样不可以,除非单个赋值stu4.name="smith";printf("\nstu4.name=%s",stu4.name);
}
3.结构体应用实例
-1.步骤
1)声明(定义)结构体,确定结构体名
2)编写结构体的成员
3)白那些处理结构的函数
-2.小狗案例
1)编写一个额Dog结构体,包含name(char[10])、age(int)、weight(double)属性
2)编写一个say函数、返回字符串,方法返回信息中包含所有成员值
3)在main方法中,创建Dog结构体变量,调用say函数,将调用结果打印输出。
#include <stdio.h>//定义一个结构体
struct Dog{char *names;int age;double weight;};
//say函数,返回字符串,信息包含所有成员值
char *say(struct Dog dog){//将这个信息放入一个字符串当中static char info[50];sprintf(info,"name=%s age=%d weight=%.2f",dog.names,dog.age,dog.weight);dog.names="小花";//这里改动对输出没有任何影响,因为是值传递return info;
}
void main(){//测试
//定义结构体变量
struct Dog dog;char *info=NULL;dog.names="小黄";dog.age=1;dog.weight=3.4;info=say(dog);//结构体默认是值传递printf("\n小狗信息为:%s",info);}
-3.盒子案例
1)创建一个Box结构体,在其中定义三个成员表示一个立方体的长、宽
和高,长宽高可以通过控制台输入
2)定义一个函数获取立方体的体积(volume)
3)创建一个结构体,打印给定尺寸的立方体体积。
#include <stdio.h>
struct Box{double len;double width;double height;double volumn;//体积
};
double out(){struct Box box;printf("请输入长宽高:");fflush(stdout);scanf("%lf%lf%lf",&box.len,&box.width,&box.height);getchar();box.volumn=box.len * box.width * box.height;return box.volumn;
}
void main(){printf("该长方体的体积是:%.2f",out());
}
//运行结果是:
请输入长宽高:3 3 3
该长方体的体积是:27.00
Process finished with exit code 23
-4.景区门票案例
1)一个景区根据游人的年龄收取不同价格的门票
2)请编写游人结构体(Vistor),根据年龄段决定能够购买的门票价格并输出
3)规则:年龄>18,门票为20元,其他情况,免费
4)可以循环从控制台输入名字和年龄,打印门票收费情况,如果名字输入n则退出程序
#include <stdio.h>
#include <string.h>
/** 1)一个景区根据游人的年龄收取不同价格的门票2)请编写游人结构体(Vistor),根据年龄段决定能够购买的门票价格并输出3)规则:年龄>18,门票为20元,其他情况,免费4)可以循环从控制台输入名字和年龄,打印门票收费情况,如果名字输入n则退出程序*/
struct Vistor{char name[10];int age;double pay;//应付票价
};
//编写函数处理业务逻辑
//说明:因为结构体默认是值传递,会拷贝一份完整的数据,效率较低
//因此为了提高效率我们直接接收一个指针
void ticket(struct Vistor *vistor){//判断if((*vistor).age>18){(*vistor).pay=20;}else{(*vistor).pay=0;}
}
void main(){//测试//创建结构体变量(创建一个游客)struct Vistor vistor;//死循环一直循环下去while(1){printf("\n请输入游客名字:");fflush(stdout);scanf("%s",vistor.name);if(strcmp("n",vistor.name)==0){break;}printf("\n请输入游客年龄:");fflush(stdout);scanf("%d",&vistor.age);//调用函数ticket,获取应付的票价ticket(&vistor);//取地址放进去printf("\n该游客应付票价=%.2f",vistor.pay);}printf("退出程序!!");
}
//运行结果:
请输入游客名字:张得请输入游客年龄:12该游客应付票价=0.00
请输入游客名字:jabs请输入游客年龄:34该游客应付票价=20.00
请输入游客名字:n
退出程序!!
Process finished with exit code 12
4.共用体
-1.基本介绍
需求
现有一个关于学生信息和教师信息的表格。学生信息包括姓名、编号、性别、职业、分数、教师的信息包括姓名、编号、性别、职业、教学科目。请看下面表格
Name | Num | Sex | Profession | Score/Course |
---|---|---|---|---|
孙二娘 | 501 | 女(f) | 学生(s) | 89.5 |
吴用 | 1011 | 男(m) | 老师(t) | math |
顾大嫂 | 109 | 女(f) | 老师(t) | English |
林冲 | 982 | 男(m) | 学生(s) | 95.0 |
解决方案:
1)传统方案:
定义结构体,根据人员的职业,使用对应的成员变量。
struct Person{char name[20];int num;char sex;char proffession;float score;//学生使用scorechar course[20];//老师使用course
};
传统方式的问题分析:会造成空间的浪费,比如学生只使用score,但是也占用了course成员的20个字节
解决方案:
1)做struct Stu 和struct Teacher【但如果职业很多,就会对应多个结构类型,不利于管理】
2)使用共用体
-2.走向共用体
1)介绍
共用体(Union)属于构造类型,它可以包含多个类型不同的成员。和结构体非常类似,但是也有不同的地方
共用体有时也被称为联合或者联合体,定义格式为
union 共用体{成员列表 };
结构体和共用体的区别在于:结构体的各个成员会占用不同的内容,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。
2)快速入门
定义共用体类型和共用体变量的三种方式(和结构体一样)
第一种:
union data{int n;
char ch;
double f;
};
union data a,b,c;
第二种:
union data{int n;
char ch;
double f;
} a,b,c;
第三种:
union{//匿名共用体
int n;
char ch;
double f;
}a,b,c;
案例;
#include <stdio.h>
union data{//一个公共体数据类型,包含3个成员共享数空间,该空间的大小以占用最大的成员为主int n;//4byteschar ch;//1bytesshort m;//2bytes
};
void main(){union data a;//定义一个共用体变量printf("%d,%d\n",sizeof (a),sizeof(union data));//4,4(以类型最大的为主)a.n=0x40;//4*16=64printf("%d,%c,%d\n",a.n,a.ch,a.m);//后面两个变量也有值64,@(64的ASCII),64a.ch='9';//字符9对应的十进制是57printf("%d,%c,%d\n",a.n,a.ch,a.m);//57,9,57a.m=0x2059;//8281printf("%d,%c,%d\n",a.n,a.ch,a.m);//8281,Y,8281(char一个字节发现是89对应的Ascii是Y0)a.n=0x3E25AD54;//1042656596printf("%d,%c,%d\n",a.n,a.ch,a.m);//1042656596,T,-21164
}
data内存布局:
-3最佳实践:
使用共用编程对以上表格进行编程
#include <stdio.h>
#define TOTAL 1 //人员总数
//定义了一个结构体
union MYUNION{float score;char course[20];
};
struct Person{char name[20];int num;//编号char sex;//性别 f==>女 m=>男char profession;//职员 s==>学生 t==>老师union {float score;char course[20];}sc;//sc是一个共用体变量~
//union MYUNION sc;
};
void main(){int i;struct Person persons[TOTAL];//定义一个共用体变量数组//录入人员信息for(i=0;i<TOTAL;i++){printf("Input info;");fflush(stdout);scanf("%s %d %c %c",persons[i].name,&(persons[i].num),&(persons[i].sex),&(persons[i].profession));if(persons[i].profession=='s'){//如果是学生printf("请输入该学生的成绩:");fflush(stdout);scanf("%f",&persons[i].sc.score);}else{//是老师printf("请输入该老师所教的课程:");fflush(stdout);scanf("%s",&persons[i].sc.course);}fflush(stdin);//刷新输入}//输出人员信息printf("\nName\tNum\tSex\tProfession\tScroce/Course\n");for(i=0;i<TOTAL;i++){if(persons[i].profession=='s') {//如果是学生printf("%s\t\t%d\t%c\t%c\t\t\t%.2f\n",persons[i].name,persons[i].num,persons[i].sex,persons[i].profession,persons[i].sc.score);}else{printf("%s\t\t%d\t%c\t%c\t\t\t%s\n",persons[i].name,persons[i].num,persons[i].sex,persons[i].profession,persons[i].sc.course);}}
}
//运行结果
Input info;小伟 14 f s
请输入该学生的成绩:78Name Num Sex Profession Scroce/Course
小伟 14 f s 78.00Process finished with exit code 21
重温C语言十四-----结构体与共用体相关推荐
- C语言入门系列之10.结构体和共用体
文章目录 一.结构体变量的基本使用 1.概述 2.定义结构体类型变量的方法 3.结构体变量的引用 4.结构体变量的初始化 二.结构体的高级应用 1.结构体数组 Ⅰ定义结构体数组 Ⅱ结构体数组的初始化 ...
- C语言-结构体与共用体
int 4字节:char 1字节:short 2字节:float 4字节: 1字节bytes=8位bits(2^8): struct date {int month;int day;int year; ...
- 江哥带你玩转C语言 | 14 - 结构体-枚举-共用体
什么是结构体 结构体和数组一样属于构造类型 数组是用于保存一组相同类型数据的, 而结构体是用于保存一组不同类型数组的 例如,在学生登记表中,姓名应为字符型;学号可为整型或字符型;年龄应为整型;性别应为 ...
- C语言之结构体和共用体
C语言之结构体和共用体 算上这篇笔记加上之前的四篇笔记,C语言基础我们也就告一段落了,对于刚刚接触c语言的童鞋们来说,这些以及足够了,稍后我会发布数据结构,对于想要深入学习的童鞋可以继续关注.本人也算 ...
- 【C语言】结构体、共用体、位域
结构体 1. 结构体的声明方法 struct struct_name {data_type member1;data_type member2;.. }; 这是其中一种声明方式~ 2.定义一个结构体变 ...
- [视觉SLAM十四讲]学习笔记1-刚体运动之旋转矩阵与变换矩阵
[视觉SLAM十四讲]学习笔记1-刚体运动之旋转矩阵与变换矩阵 1点.向量和坐标系 2 坐标系间的欧式变换 2.1 欧式变换之旋转 2.2 欧式变换之平移 3 变换矩阵与齐次坐标 4 Eigen库的简 ...
- C语言结构体与共用体03
小甲鱼结构体与共用体03 实战例题:有一个结构体变量stu,内含学生学号.姓名和3门课程的成绩.通过调用函数print将它们输出. ①先用结构体变量作函数参数: //先用结构体变量作函数参数 #inc ...
- c语言指针变量输出不了共用体,瘋子C语言札记(结构体/共用体/枚举篇)
瘋子C语言笔记(结构体/共用体/枚举篇) (一)结构体类型 1.简介: 例: struct date { int month; int day; int year; }; struct student ...
- 结构体与共用体05 - 零基础入门学习C语言57
第十章:结构体与共用体05 让编程改变世界 Change the world by program 对链表结点的删除操作实现 实现源代码: [codesyntax lang="c" ...
最新文章
- 英伟达颠覆CPU!Arm架构专为AI而生,性能超x86十倍
- [转]配置子报表和钻取报表
- C++:读写二进制文件到double数组,根据二进制数据量进行读取
- ABAP 查询性能提高之我见
- android 运行在ui县城,Android基础:在UI线程中运行代码
- 在Apache服务器上安装SSL证书
- 不可不知的 5 种 JavaScript 代码编辑器
- Android APK包文件解析
- mockwebserver java_在Java中使用WireMock和SOAP Web服务
- 清华ACL'22 | 一文读懂刘知远所在实验室18篇论文详情
- 9.Linux/Unix 系统编程手册(上) -- 进程凭证
- 如何使用ArcGIS Pro制作三维地图
- 重磅!2022年JCR正式发布(附最新影响因子详单)
- 五款机房教学管理系统,你的教室安装了吗
- 淘宝商品评论API接口
- 电动汽车对系统运行的影响(Matlab实现)
- LabVIEW自动整理程序框图
- 极验验证——滑块拼图验证码
- 2021年烷基化工艺找解析及烷基化工艺考试试卷
- layui分页和模板引擎