第九章、结构体与共用体
文章目录
- 9.1 结构体变量定义、引用、初始化
- 9.1.1 结构体概述
- 9.1.2 定义结构体类型变量的方法
- 9.1.3 结构体类型变量的引用
- 9.1.4 结构体变量的初始化
- 9.2 结构体数组、结构体指针
- 9.2.1结构体数组
- 如何定义结构体数组
- 9.2.2 结构体指针
- 9.2.3 用指向结构体的指针做函数参数
- 9.3 共用体、枚举类型、typedef
- 9.3.1共用体(联合)
- 结构体与共用体的区别
- 9.3.2枚举类型
- 9.3.3用typedef来定义类型
9.1 结构体变量定义、引用、初始化
9.1.1 结构体概述
类型回顾: int float double char int a[10] float b[100]
结构体概述:
结构体也是一种数据类型,被叫做结构体类型
结构体: 将多种不同类型的数据组到一起。目的是为了表达更丰富的信息。类似于SQL语言中的“记录”。
形式:
#include "stdio.h"
int main(){struct student{int num; //学号char name[100]; //姓名int sex; //性别, 0->女, 1->男int age; //年龄char address[100]; //地址};
}
总结:
结构体类型 定义的一般形式
struct 结构体名
{//成员列表(可以有多个) 各个成员之间都带一个分号;
}; // 不能忘记这个分号;
9.1.2 定义结构体类型变量的方法
二: 定义结构体类型变量的方法
需要将结构体名看成一个类型名就行了,
总共有三种写法
1. 普通写法
struct 结构体名 变量名列表;例如:
struct student s1,s2; //定义两个结构体类型变量
2. 定义结构类型的时候顺便定义了变量。变量位于} 之后 ; 之前多个变量之间使用 , 分割
struct 结构体名
{//成员列表
**}变量名列表;**#include "stdio.h"
int main(){struct student{int num; //学号char name[100]; //姓名int sex; //性别, 0->女, 1->男int age; //年龄char address[100]; //地址**}s1,s2;**
}
1. 直接定义结构类型变量,连结构体名都省略了
struct
{//成员列表
**} 变量名列表;**
说明:
- 使用结构体,我们一般要先定义一个结构体类型,然后定义某些变量为该类型的变量。
- 结构体内可以套结构体
struct date
{int month;int day;int year;
};struct student{int num; //学号char name[100]; //姓名int sex; //性别, 0->女, 1->男int age; //年龄char address[100]; //地址**struct date birthday; //生日,结构体类型变量**};int main()
{struct student s1,s2;
}
- 结构体内的成员变量,可以与程序中的变量名相同,彼此间不影响
9.1.3 结构体类型变量的引用
三: 结构体类型变量的引用
- 不能将结构体变量作为一个整体进行引用,比如s1,s2都是结构体变量,但不能拿过来直接用,只能对结构体变量中的各个成员分别引用,
引用方法:
**// 结构体变量名.成员名**
**s1.num = 1; //将1赋值给s1变量中的成员num; 这个 . 叫结构成员运算符
//该 . 运算符的优先级跟()是同级别 还有 ->**
**所以可将s1.num当成一个整体来看待**
如果成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级的找到最低一级成员,只能对最低级别成员进行赋值或者存取。
#include "stdio.h"
struct date {int month;int day;int year;
};
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;// }s1,s2;
};
int main() {int num; //这个名字和结构体变量的名字相同,但互不影响.struct student s1,s2;s1.num = 001; //将001赋值为s1结构体变量中的成员num.//**s1.birthday.day = 1; //如果成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级的找到最低一级成员,只能对最低级别成员进行赋值或者存取。**return 0;
}
成员变量
//成员变量,可以像普通变量一样进行各种运算
s1.age = 19;
s2.age = s1.age;
int AgeSum = s1.age + s2.age;
s1.age++; //年龄自加1,因为.的优先级最高,所以s1.age是个整体
9.1.4 结构体变量的初始化
// 成员变量也是有地址的.
//结构体名不可以有地址
// s1++ s1.birthday++ 这都是错的
int *p = &s1.num;printf("%d",*p); //也可以使用指针变量来取得其地址//结构体变量的初始化,定义时初始化
struct student s3 = {1003,"网速",1,19,"浦东",10,14,2018};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Aw4VI4cA-1667044997212)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3520ce3c-9115-41d9-abb7-fcc7d3c06369/Untitled.png)]
9.2 结构体数组、结构体指针
9.2.1结构体数组
如何定义结构体数组
a. 单独写成一行定义
struct studeng stu[3]; //可以用的下标 0-2
b. 定义结构的时候顺便定义结构体数组
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;}stu[3];
c. 定义结构体数组的时候还可以同时进行初始化
一般形式:
struct student stu[] = { {…},{…},{…}};
struct student stu[3] = { //stu包含的元素程序自己会判断出来,所以可以写成stu[]{2019250116,"zhangsan",1,18,"2401",12,30,2000},{2019250119,"振华",0,22,"小区2401",11,11,1999},{2019250118,"郭襄",0,20,"平凉",9,23,2001}
};
printf("stu[%d]",stu[1].age);
9.2.2 结构体指针
- 就是结构体变量的指针,这个指针肯定是指向该结构体变量所占据的内存段的起始地址
- 结构体变量指针,也可以指向结构体数组中的元素。因为结构体数组中的每个元素就相当于一个结构体变量
#include "stdio.h"
#include "string.h"
struct date {int month;int day;int year;
};
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;};//stu[3];
int main() {**//结构体指针//就是结构体变量的指针,这个指针肯定是指向该结构体变量所占据的内存段的起始地址//结构体变量指针,也可以指向结构体数组中的元素。因为结构体数组中的每个元素就相当于一个结构体变量struct student stu{}; //定义一个结构体变量,struct student *ps; //定义结构体变量的指针ps = &stu;strcpy(stu.name,"小虎");stu.age = 18;//ps已经指向了stu,stu里面的内容若改变了,就等于ps所指向的内容改变了。//如何通过结构体变量的指针来访问结构体变量的成员呢?两种方法://1.(*ps).age=29; //* 与 . 的运算等级不一样, .是最高的,所以这里要用 (*ps).ageps -> num = 2019250119;//2.ps -> sex = 1; //其中 -> 叫指向结构体成员运算符 .printf("name=%s\n",ps->name);printf("age=%d\n",ps->age);printf("num=%d\n",stu.num);printf("sex=%d\n",stu.sex);return 0;
}**
#include "stdio.h"
#include "string.h"
struct date {int month;int day;int year;
};
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;};//stu[3];
int main() {struct student stu[3] = { //stu包含的元素程序自己会判断出来,所以可以写成stu[]{2019250116,"zhangsan",1,18,"2401",12,30,2000},{2019250119,"振华",0,22,"小区2401",11,11,1999},{2019250118,"郭襄",0,20,"平凉",9,23,2001}};printf("stu[%d]",stu[1].age);**//演示指向结构体数组的指针****struct student *ps;ps = stu; //数组名代表数组首地址。int i; //随时使用随时定义for(i=0;i<3;i++){printf("num=%d\n",ps->num);printf("name=%s\n",ps->name);printf("age=%d\n",ps->age);ps++; //ps指向了下一个数组元素的开始地址printf("-----------------\n");}int ILen = sizeof(struct student);printf("%d\n",ILen);**
#include "stdio.h"
#include "string.h"
struct date {int month;int day;int year;
};
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;};//stu[3];
int main() {struct student stu[3] = { //stu包含的元素程序自己会判断出来,所以可以写成stu[]{2019250116,"zhangsan",1,18,"2401",12,30,2000},{2019250119,"振华",0,22,"小区2401",11,11,1999},{2019250118,"郭襄",0,20,"平凉",9,23,2001}};printf("stu[%d]",stu[1].age);**//演示指向结构体数组的指针struct student *ps;ps = stu; //数组名代表数组首地址。(++ps)->num; //值为2019250119,指针指向了2019250119(ps++)->num; //值为2019250116,指针指向了2019250119
}**
(2)不能让ps指向某一个数组元素中的成员。
错误写法
ps =&stu[0].num; //可以强制转,但没有意思
ps = &stu[0]; //这是对的
9.2.3 用指向结构体的指针做函数参数
#include "stdio.h"
#include "string.h"
struct date {int month;int day;int year;
};
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;};//stu[3];
int main() {struct student stu[3] = { //stu包含的元素程序自己会判断出来,所以可以写成stu[]{2019250116,"zhangsan",1,18,"2401",12,30,2000},{2019250119,"振华",0,22,"小区2401",11,11,1999},{2019250118,"郭襄",0,20,"平凉",9,23,2001}};printf("stu[%d]",stu[1].age);**//演示指向结构体数组的指针struct student *ps;ps = stu; //数组名代表数组首地址。(++ps)->num; //值为2019250119,指针指向了2019250119(ps++)->num; //值为2019250116,指针指向了2019250119
}**
(2)不能让ps指向某一个数组元素中的成员。
错误写法
ps =&stu[0].num; //可以强制转,但灭有意思
ps = &stu[0]; //这是对的
9.3 共用体、枚举类型、typedef
9.3.1共用体(联合)
将几种不同类型的变量存放到同一段内存单元(同一个内存地址开始的单元中)。
几个变量共同占同一段内存的结构,叫共用体
union 共用体名
{//成员列表
} 变量列表;
union myuni
{int carnum; //车编号,char cartype; //车的类型char cname[60]; //轿车名
}a,b,c;
结构体与共用体的区别
结构体:
占用的内存是其成员所占内存之和。 如果定义的结构体不能被4整除或被某个数整除的话,系统会多分配几个字节以保证字节对齐
保证字节对齐的目的是为了效率问题。
#include "stdio.h"
#include "string.h"
struct student //结构体
{int num;char name[101];int sex;
};
int main(){union MyUni a,b,c;int StructLen(sizeof(struct student)); //StructLen=112;
// 4+101+4=109; 112-109=3
//保持的是4k对齐,108/4=27 109-112是4个字节。
printf("StructLen=%d\n",StructLen); // 112
共用体: 所占用内存长度等于最长的成员长度。
#include "stdio.h"
#include "string.h"
union MyUni //共用体
{int CarNum; //车编号,char CarType; //车的类型char name[60]; //轿车名
};int main(){union MyUni a,b,c;
int UnionLen(sizeof(union MyUni));printf("UnionLen=%d\n",UnionLen); // UnionLen=60
//最长的成员类型长度
说明:
a、共用体变量的引用
a.name;
a.CarNum;
b、共用体变量的特点
同一段内存存放几种不同类型的成员,但每一个瞬间只能存放其中一种。也就是说,每个瞬间只能由一个成员起作用,其他成员不起作用,并不是同时存在、都起作用
程序代码中最后给哪个成员赋值,那么哪个成员就起作用
#include "stdio.h"
#include "string.h"
union MyUni //共用体
{int CarNum; //车编号,char CarType; //车的类型char name[60]; //轿车名
};struct student //结构体
{int num;char name[101];int sex;
};
int main(){union MyUni a,b,c;int StructLen(sizeof(struct student)); //StructLen=112;// 4+101+4=109; 112-109=3 保持的是4k对齐,108/4=27 109-112是4个字节。int UnionLen(sizeof(union MyUni));printf("StructLen=%d\n",StructLen);printf("UnionLen=%d\n",UnionLen);**a.name;a.CarNum = 12; //这个不起作用strcpy(a.name,"ab"); //这是最后一个成员,所以这个才起作用printf("%d\n",a.CarNum); //不确定的值printf("%s\n",a.name); //ab**
c、共用体变量的地址 和 其他成员地址都相同
&a &a.Carnum &a.name &a.CarType
这三个地址都相同
d、共用体变量不能在定义的时候初始化,而结构体可以初始化
e、不能把共用体变量作为函数参数,也不能让函数带回共用体变量
9.3.2枚举类型
例如:
//四种颜色: 红,绿,蓝,黄
// Red表红色
//Green
//Blue
//Yellow
枚举值当成整型值用就行了
枚举类型关键字
enum
enum color
{Red, //枚举常量,值不能被改变(可以当成一个整形数字)//占用4个字节Green,Blue,Yellow
};
枚举就是将值一一列举出来,那么定义的枚举变量值就只限于列出来的这些值的范围内;
可以直接定义枚举变量,不要枚举名,这就要直接定义枚举变量才行
enum
{Red,Green,Blue,Yellow
}MyColor1,MyColor2;
这些Red,Green,Blue,Yellow叫做枚举常量,这些常量的值不能被改变
//枚举常量,值不能被改变(可以当成一个整形数字),占用4个字节
d、可以直接给 枚举类型变量 赋值
#include "stdio.h"
#include "string.h"
enum color
{Red, //0,默认从0开始,Green, //1Blue, //2Yellow //3
};int main(){**enum color MyColor1,MyColor2;**printf("%d\n",Red);printf("%d\n",Yellow);**MyColor1 = Red; // 0Mycolor2 = Yellow; // 3**}
e、定义枚举类型时,直接给枚举常量一个值。
#include "stdio.h"
#include "string.h"
enum color
{
Red= 12, // 从12开始 往下走每次加1
Green, //13
Blue, //14
Yellow //15
};int main(){enum color MyColor1,MyColor2;printf("%d\n",Red); //12printf("%d\n",Yellow); //15MyColor1 =Red; //Red当做常量printf("%d\n",MyColor1); //12}
f、枚举值,理解成整型值
枚举值可以做比较
MyColor1 = (enum color)-8;
//强制转换将-8给了Red这个常量
if(MyColor1 == Red // 枚举值可以做比较
{printf("OK");
}
MyColor1 = (enum color)20000
printf("%d\n",MyColor1);
//枚举值其实就是整型值,可以互通
g、枚举值可以赋给一个整形
int abc;
abc = Green;printf("%d\n",Green); printf("%d\n",abc); //两个的值都是一样的
9.3.3用typedef来定义类型
使用typedef来定义新的类型名,可以用来代替已有的类型名,
#include "stdio.h"
#include "string.h"
enum color
{Red = 12,Green,Blue,Yellow
};int main(){typedef int INTEGER; //可以使用INTEGER来代表int型,那再次定义整形变量时我们//就可以如下定义INTEGER a,b,c; //int a1,a2,a3; // 这两个都是一样的**//如何定义结构体类型typedef struct date{int month;int day;int year;}DATE;DATE birthday;DATE *p1; //p为指向此结构体类型数据的指针//变形:typedef int NUM[100]; //定义num数组是整形NUM n; // 等价于int n[100];typedef char *RNG; //定义RNG为字符指针类型RNG p,q; // char *p,*q;****//指向函数的指针typedef int (*POINTER)(); //定义pointer为指向函数的指针类型,该函数返回的是整型值POINTER x,y;**
}
//总结: 第一步:先写出常规的整形数组定义方式
int n[100];
//第二步:将变量名替换成自己想用的类型名
int NUM[100];
//第三步:在前面加上typedef
typedef int NUM[100];
说明:
- typedef中用的类型别名使用大写
- typedef用来定义类型名的,不是定义变量
- typedef只是对已存在的类型增加一个类型名,没有创建新的类型
- typedef是在编译的时候处理的,是在编译环节进行的
可执行文件需要经过编译(预处理(#define,#include,#ifdef)**,编译(typedef),**汇编),链接,
1. typedef主要作用:
程序的通用性和可移植性
int a,b,c;
typedef int INTEGER;
INTEGER a,b,c;
第九章、结构体与共用体相关推荐
- 第九章结构体变量实验报告
实验项目: 1.结构体变量的应用 2.结构体数组的应用 3.共用体的应用 4.结构体指针的应用 姓名:谢丽萍 实验地点:教学楼514教室 实验时间2019.6.26 一.本章要点 1.对结构体和共 ...
- C语言-结构体与共用体
int 4字节:char 1字节:short 2字节:float 4字节: 1字节bytes=8位bits(2^8): struct date {int month;int day;int year; ...
- 数组、结构体和共用体的长度计算?
数组.结构体和共用体的长度计算? 运算符sizeof可以计算出给定类型的大小,对于32位系统来说,sizeof(char) = 1; sizeof(int) = 4.基本数据类型的大小很好计算,我们来 ...
- 结构体与共用体(联合体)
参考:结构体与共用体 作者:一只青木呀 发布时间: 2020-08-09 08:29:22 网址:https://blog.csdn.net/weixin_45309916/article/detai ...
- 结构体与共用体05 - 零基础入门学习C语言57
第十章:结构体与共用体05 让编程改变世界 Change the world by program 对链表结点的删除操作实现 实现源代码: [codesyntax lang="c" ...
- 结构体与共用体07 - 零基础入门学习C语言59
第十章:结构体与共用体07 让编程改变世界 Change the world by program 用typedef定义类型 用typedef声明新的类型名来代替已有的类型名 声明INTEGER为 ...
- C语言之结构体和共用体
C语言之结构体和共用体 算上这篇笔记加上之前的四篇笔记,C语言基础我们也就告一段落了,对于刚刚接触c语言的童鞋们来说,这些以及足够了,稍后我会发布数据结构,对于想要深入学习的童鞋可以继续关注.本人也算 ...
- 结构体、共用体、位操作和枚举类型
1 引言 ● 结构体(Structure)[在C标准中有时也称为聚合体(Aggregate)]是统一在同一个名字之下的一组相关变量的集合,它可以包含不同类型的变量 ● 结构体通常用来定义储存在文件中的 ...
- 【C语言】结构体、共用体、位域
结构体 1. 结构体的声明方法 struct struct_name {data_type member1;data_type member2;.. }; 这是其中一种声明方式~ 2.定义一个结构体变 ...
最新文章
- python多态的例子_Python编程之多态用法实例详解
- PyTorch分布式训练
- matlab用lism求零输入响应,信号与系统matlab课后作业_北京交通大学讲解.docx
- IOS8 Playground介绍
- Eclipse Plug-in Hello world
- 知识点old1908
- C#的COM接口定义细则
- uva 1463 - Largest Empty Circle on a Segment(二分+三分+几何)
- 牛腩新闻发布系统-发布
- 在 Windows 10 中映射网络驱动器
- VS2012帮助下载地址
- OK插件安装常见问题集锦(PowerPoint版)|OneKeyTools Lite安装说明
- 编码:隐匿在计算机软硬件背后的语言
- [code] 在ROS上搭建ROVIO节点
- 张馨予一幅画拍出几十万,然而范冰冰却一直在向粉丝要画!
- PCL——简单点云可视化
- 数字电路逻辑设计笔记(3):集成逻辑门电路
- Python matplotlib 中填充颜色
- 计算机学科专业基础综合科目(408)
- VS中怎么实现代码换行