来源:微信公众号「编程学习基地」
结构体
结构体的作用
数组:具有相同类型的数据的集合
结构体:存储不同类型的数据项
单一的数据类型无法满足特定的需求,数据类型的集合体:结构体 出现了
结构体的定义和使用
结构体的定义方式
结构体是一种自定义数据类型 struct用来定义一个类型
- 结构体的定义方式:
struct 结构体名字
{
//成员变量
};
- 定义结构体后再定义变量
//例1:
struct stu
{
int id //学号
char name[20]; //名字
};
struct stu stu1,*pStu,arr[10]; //定义变量
- 在定义结构体的同时定义变量
//例2:
struct stu
{
int id; //学号
char name[20]; //名字
}stu1,*pStu,arr[10]; //定义变量
引用结构体变量中的成员
- 点运算符访问结构体的成员变量 .
//对例2的结构体变量进行访问
stu1.id=1001;
strcpy(stu1.name,"小明同学");
arr[1].id=1002;
strcpy(arr[1].name,"梦凡老师");
- 箭头运算符访问结构体成员变量 ->
//对例2的结构体变量进行访问
pStu=(struct stu*)malloc(sizeof(struct stu));//分配内存
pStu->id=1001;
strcpy(pStu->name,"小明同学");
(arr+1)->id=1002;
strcpy((arr+1)->name,"梦凡老师");
typedef的定义和使用
作用 : 给类型取短一点的别名 方便阅读
_t结尾的类型 一般都是别名,例如size_t 就是 unsigned int
typedef的定义
- 给基本数据类型取别名
typedef 数据类型 别名
typedef unsigned int size_t; //给unsigned int 取别名 size_t
- 给结构体变量取别名
typedef struct 结构体名字 结构体别名
typedef struct stu STU; // STU 等价于 struct stu
STU stu1={1001,"小明同学"}; // STU这个结构体类型就可以直接定义使用了
- 定义结构体的时候给结构体取别名
//例3: 推荐这种写法
typedef struct stu //定义结构体的时候取别名
{
int id //学号
char name[20]; //名字
}STU;
STU stu1,*pStu,arr[10]; //定义变量
内存对齐
结构体变量大小 >= 结构体所有成员变量大小
结构体总大小为最大对齐数的整数倍
#include<stdio.h>
typedef struct test
{
int x;
char ch;
int y;
char c;
}TEST;
int main()
{
printf("test的大小为:%d\n",sizeof(TEST));
return 0;
}
输出结果:
test的大小为:16
Press any key to continue
上面的例子很简单,看的懂的话我变换一下再来看看
#include<stdio.h>
typedef struct test
{
int x;
char ch[10]; //数组看成单个元素
int y;
char c;
}TEST;
int main()
{
printf("test的大小为:%d\n",sizeof(TEST));
return 0;
}
输出结果:
test的大小为:24
Press any key to continue
为什么会是24,我们开头就说了:结构体总大小为最大对齐数的整数倍
该结构体最大对齐数为 int 也就是4个字节大小 ,结构体的大小就是4的整数倍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U4yaxN0T-1577347105811)(D:\360MoveData\Users\邓志荣\Desktop\无标题.png)]
如果嵌套了结构体的情况,嵌套的结构体对齐到自己最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
为什么要有内存对齐
简单来说就是:浪费一点内存快速定位
专业点来说:
1.平台问题(移植问题):不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地质处取某些特定类型的数据,否则跑出硬件异常。
2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要做两次内存访问,而对齐的内存只需要访问一次。
位域
在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),这就是位域。
位域的定义:
struct Stu
{
int a; //成员 a 没有限制它占用 4 个字节的内存。
int b:4; //成员 b 被:后面的数字限制 占用 4 位的内存
};
注意:
- 一个 字节 是 8 位
- 位域的取值范围不能超过它所依附的数据类型的长度
例4:
struct Stu
{
int b:33; // int 4 个字节,32位;33超过了int的数据长度,报错
};
- 例4中sizeof(Stu)=4;原因还是内存对齐
枚举
关键字:enum
枚举类型的定义
enum game
{
SPACE, WALL, SNAKE, FOOD, HEAD//空地 墙 蛇 食物
};
定义完之后 SPACE=0 ,WALL=1 ,后面依次类推
enum game
{
SPACE, WALL=5, SNAKE, FOOD, HEAD//空地 墙 蛇 食物
};
SPACE=0, WALL=5, SNAKE=6,后面依次类推
enum和switch搭配,可以防止遗漏内容
在VS里面输入switch+tab键+枚举类型 可以迅速匹配枚举类型的所有成员
联合
关键字:union 共用一块内存
联合类型的定义
union 联合类型名
{
//成员
};
联合和结构体的区别:
- 结构体变量可以同时存放多个成员
- 联合只能保证一个成员有效 (共同用一块内存)
联合在一般的编程中应用较少,在单片机中应用较多,只做了解就可以了。