一、学习内容
-
结构体位域
#include <myhead.h> typedef struct { int a:2; short b:1; char c:1; }m1; typedef struct { char a:3; short b:7; int c:10; }m2; int main(int argc, const char *argv[]) { printf("%ld\n",sizeof(m1)); printf("%ld\n",sizeof(m2)); return 0; }
-
共用体(union)
-
概念
-
与结构体一样,自定义类型,允许在同一内存上存储不同类型的变量,但是多个变量一次只能使用或者赋值一个变量,多个变量共享内存空间。
-
-
作用
-
节约内存空间,多个变量共享一个内存空间。
-
-
定义格式
-
union EUM { 类型1 成员1; 类型2 成员2; 类型3 成员3; };
-
-
共用体注意事项
-
内存占用,所有基础成员中最大的成员所占大小就是联合体内存大小。
-
赋值或者使用时,一次只能赋值或者使用一个成员变量。
-
-
共用体初始化
-
#include <myhead.h> union EMU { int age; char a; short b; double c; }; int main(int argc, const char *argv[]) { union EMU www; www.age = 200; www.a ='W'; www.b = 10; www.c = 120; printf("www.age = %d\n",www.age);//第一个赋值可以输出 printf("www.a = %c\n",www.a);//第一个被第二个覆盖掉 printf("www.b = %d\n",www.b);//第二个被第三个覆盖掉 printf("www.c = %lf\n",www.c);//第三个被第四个覆盖掉 return 0; }
-
-
-
枚举
-
枚举实际就是枚举常量
-
定义格式
-
枚举常量: 定义格式: enum 枚举名 { 成员1,成员2,成员3,成员4 };
-
枚举成员直接使用,不需要结构体或者联合体那样引用。
-
默认第一个成员是0,如果给第一个成员赋值,后面成员依次累加1
-
-
-
枚举的初始化
-
-
数据结构绪论
-
概念
-
数据的组织方式,施加在数据上的一组操作,(增删改查等)
-
-
数据
-
能被计算机识别存储处理的符号集合
-
数据分为数值类型和非数值类型
-
数值:int a,123,float b;等我们熟知的变量和常量都是数值数据。
-
非数值:mp3,光盘,磁带,电影视频。
-
-
-
数据对象
-
多个数据对象构成了数据
-
例如:24081班,24071班,24091班 都属于数据对象,构成上海中心属于数据。
-
-
-
数据元素
-
多个数据元素构成了数据对象
-
例如:24081班有27个(学生)数据元素。
-
-
-
数据项
-
数据元素的最小组成单位
-
例如:数据元素张震有两条腿,有耳朵,有嘴,这些都是组成数据元素的最小单位。
-
数据>数据对象>数据元素>数据项
-
数据元素是组成数据的基本单位,数据项是数据的最小单位。
-
-
-
数据结构体分为逻辑结构和物理结构体
-
数据结构
-
逻辑结构
-
集合结构:数据元素之间没有关系
-
线性结构:数据元素一对一的关系
-
树形结构:数据元素一对多的关系
-
图形结构:数据元素多对多的关系
-
-
物理结构(真实的结构)
-
顺序存储
-
逻辑相邻的元素物理上也相邻
-
-
链式存储
-
逻辑相邻的元素物理上不一定相邻
-
-
散列存储
-
哈希存储,数据元素的存储和哈希函数和关键字有关(了解)
-
-
索引存储
-
在存储数据元素时建立一个索引表,以便快速查找
-
-
-
-
-
顺序存储和链式存储的区别
-
-
顺序存储必须占用连续的内存空间。
-
链式存储内存空间连续与否均可。
-
链式存储时节点体积较小,可以充分利用内存碎片。
-
相同节点个数的顺序存储和链式存储,链式存储占用内存较多。
-
链式存储和顺序存储都有优缺点,不能单纯的认为链式或者顺序存储较好。
-
-
-
-
线性表(部分)
-
例如:顺序表,顺序栈,顺序队列,顺序串,单链表,双链表,循环链表都属于线性表。
-
-
第一个元素没有前驱最后一个元素没有后继。
-
中间 的元素都有唯一的前驱和唯一的后继,元素之间一对一关系。
-
-
-
顺序表
-
概念
-
数据元素之间采用顺序存储的方式。
-
数据元素之间占用连续的内存空间。
-
采用数组存储顺序表。
-
-
-
实现方式
-
-
借助数组来存储顺序表。
-
数组长度固定
-
顺序表长度可变。
-
顺序表长度<=数组长度。
-
-
-
顺序表的组成
-
顺序表借助数组来存储,封装结构体时需要封装数组。
-
顺序表长度不固定,所以还需要封装计数器,统计顺序表元素个数。
-
结构体内部成员data和len,不能直接使用,必须使用指针L来引用成员。
-
-
-
脑图
二、作业
1.定义结构体数组存储5个学生的信息:姓名,年龄,性别
定义函数实现输入,要求形参使用结构体指针接收
函数实现5个学生年龄排序(注意对年龄排序时,交换的是所有信息)
定义函数实现输出,要求形参使用结构体指针接收
代码解答:
#include <myhead.h>
// 定义学生结构体,包含姓名、年龄和性别
typedef struct {
char name[20]; // 存储学生的姓名,最大长度 20
int age; // 存储学生的年龄
char sex[10]; // 存储学生的性别,最大长度 10,考虑 "female" 等情况
} stu, *sstu;
// 输入学生信息函数,参数为指向学生结构体数组的指针
int input_stu(sstu S) {
for (int i = 0; i < 5; i++) {
// 输入学生的姓名
printf("请输入学生的名字:");
fgets(S[i].name, sizeof(S[i].name), stdin);
S[i].name[strcspn(S[i].name, "\n")] = 0; // 移除 fgets 读取的换行符
// 输入学生的年龄
printf("请输入学生的年龄:");
scanf("%d", &S[i].age);
// 输入学生的性别
printf("请输入学生性别:");
scanf("%s", S[i].sex);
// 吃掉输入缓冲区中的多余换行符,避免下次 fgets 读取到它
getchar();
printf("\n");
}
return 0;
}
// 输出学生信息函数,参数为指向学生结构体数组的指针
int output_stu(sstu S) {
for (int i = 0; i < 5; i++) {
// 打印学生的姓名、年龄和性别信息
printf("%s\t%d\t%s\n", S[i].name, S[i].age, S[i].sex);
}
return 0;
}
// 根据年龄对学生进行排序的函数,参数为指向学生结构体数组的指针
int sort_stu(sstu S) {
stu temp; // 用于临时存储学生信息的变量
// 冒泡排序,按年龄从小到大排序
for (int i = 0; i < 5 - 1; i++) {
for (int j = 0; j < 5 - i - 1; j++) {
if (S[j].age > S[j + 1].age) {
// 交换两个学生的所有信息
temp = S[j];
S[j] = S[j + 1];
S[j + 1] = temp;
}
}
}
return 0;
}
// 主函数
int main(int argc, const char *argv[]) {
// 动态分配内存,存储 5 个学生的结构体数组
sstu S = (sstu)malloc(sizeof(stu) * 5); // 强制转换 malloc 返回的 void* 类型为 sstu 类型
// 调用输入函数,输入 5 个学生的信息
input_stu(S);
// 调用排序函数,按年龄排序
sort_stu(S);
// 调用输出函数,输出排序后的学生信息
output_stu(S);
// 释放之前分配的动态内存,避免内存泄漏
free(S);
S = NULL; // 防止悬空指针
return 0;
}
结果展现:
2.定义小车结构体,存储名称、价钱、颜色。定义两个变量a,b,初始化,实现ab互换。
代码解答:
#include <myhead.h>
// 定义小车结构体,包含名称、价钱和颜色
typedef struct {
char name[20]; // 小车的名称
float price; // 小车的价格
char color[10]; // 小车的颜色
} car;
int main() {
// 定义两个小车变量 a 和 b
car a = {"Toyota", 20000.0, "Red"}; // 初始化 a
car b = {"BMW", 18000.0, "Blue"}; // 初始化 b
// 打印互换前的小车信息
printf("交换前:\n");
printf("a: %s, %.2f, %s\n", a.name, a.price, a.color);
printf("b: %s, %.2f, %s\n", b.name, b.price, b.color);
// 互换 a 和 b 的信息
car temp = a;
a = b;
b = temp;
// 打印互换后的小车信息
printf("\n交换后:\n");
printf("a: %s, %.2f, %s\n", a.name, a.price, a.color);
printf("b: %s, %.2f, %s\n", b.name, b.price, b.color);
return 0;
}
成果展现:
三、总结
学习内容概述
1. 位域(Bit Fields)
位域是一种能够在结构体内存中精确控制数据成员所占位数的技术。主要用于节省内存,尤其在硬件寄存器中使用。
2. 共用体(Union)
共用体是一种允许多个成员共享同一块内存的自定义类型,可以有效节省内存,但同一时间只能使用一个成员。
3. 枚举(Enum)
枚举用于定义一组命名常量,通常用于表示有限的、互斥的选项。枚举成员默认从 0 开始,也可以手动赋值。
4. 数据结构基本概念
数据:由数值类型和非数值类型组成,能被计算机存储和处理的符号集合。
数据:元素是构成数据的基本单位。
数据项:是数据元素的最小组成单位。
数据结构分类:
逻辑结构:集合结构、线性结构、树形结构、图形结构。
物理结构:顺序存储、链式存储、哈希存储、索引存储。
5. 线性表
线性表是一种具有一对一数据元素关系的数据结构,包含顺序表和链表等具体实现。
学习难点
1. 位域的内存对齐与实际内存使用:
如何在不同类型的数据之间正确分配位数,避免内存浪费。
2. 共用体的使用规则:
理解如何在不损坏数据的情况下有效利用内存,尤其是当不同类型数据共存时。
3. 数据结构的逻辑与物理存储差异:
如何根据需求选择合适的存储方式(顺序存储与链式存储)以优化性能。
4. 线性表的实现:
如何合理使用数组实现顺序表,并动态管理顺序表长度。
主要事项
1. 位域:
理解位域的数据成员如何分配位数,以及不同类型的数据成员的最大限制。
2. 共用体:
在使用共用体时,确保一次只能使用一个成员,防止数据覆盖。
3. 顺序存储与链式存储的权衡:
顺序存储适用于访问速度快的场景,而链式存储适合内存不连续的场景。理解何时应选用哪种存储方式。
4. 线性表的动态性:
顺序表使用数组存储,但数组长度是固定的。要确保顺序表不会超过数组长度,并且能够灵活扩展。
未来学习重点
1. 深入理解位域的应用场景:
特别是在嵌入式系统和硬件编程中,通过位域节省内存的实际应用。
2. 共用体在复杂场景中的使用:
探索如何在资源受限的场景下合理使用共用体,同时避免数据丢失或覆盖。
3. 链表的深入学习:
链式存储的优势在于节省内存碎片以及动态扩展能力,后续可重点学习单链表、双链表及其操作。
4. 复杂数据结构的实现:
在掌握顺序表和链式存储的基础上,未来可以探索栈、队列、哈希表和树等更复杂的数据结构。
标签:存储,int,元素,www,Day15,printf,数据结构,数据 From: https://blog.csdn.net/weixin_65095004/article/details/142340639