重温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 
//养猫问题使用结构体解决
/** 分析:* 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)注意事项与细节说明:

  1. 成员声明语法同变量,实例:数据类型 成员名

  2. 字段的类型可以为:基本类型、数组或指针、结构体等

  3. 在创建一个结构体变量后,需要给成员赋值,如果没有赋值就使用可能导致程序异常终止

    #include 
    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);
    }
    
  4. 不同结构体变量的成员是否独立,互不影响。,一个结构体变量的成员更改,不影响另一个。

#include 
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 
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 //定义一个结构体
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 
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 
#include 
/** 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.基本介绍

需求

现有一个关于学生信息和教师信息的表格。学生信息包括姓名、编号、性别、职业、分数、教师的信息包括姓名、编号、性别、职业、教学科目。请看下面表格

NameNumSexProfessionScore/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 
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 
#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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部