
结构体结构体指针的用法对于结构体类型的变量取地址的模式等同于int等类型取完地址后运用指针形式来使用1、可以用.的形式2、用箭头的形式指针指向我要访问的结构体函数内部的具体成员制作一个学生信息管理系统qsort函数函数介绍引用时要带头函数#include stdlib.h功能 对数组排序void qsort( void *base, size_t nmemb,size_t size, int (*compar)(const void *, const void *) );void *base, //表示数组所在空间首地址---数组名size_t nmemb, //表示要排序的元素个数size_t size, //表示单个元素的大小int (*compar)(const void *, const void *) //函数指针 --- 用来指定比较大小的规则qsort函数补充说明关于compar函数回调函数-- 用来指定比较大小的规则int compar(const void *a, const void *b){//a b 代表的数待比较的两个元素的地址}返回值 --- a b //做差a ba b例如int compar(const void *a, const void *b){const int *p (const int *)a;const int *q (const int *)b;return *p - *q;}int a[10] {2,1,5,7,8,6,3,4,9,10};qsort(a,10,sizeof(int),compar);qsort函数和compar函数的使用举例说明关于结构体类型大小的计算 ⭐⭐⭐规则结构体的对齐规则: 内存对齐1.结构体成员变量的对齐自然边界对齐2.结构体整体对齐以最大的成员来对齐3.只能按照定义的成员顺序逐个置位图像说明文字说明1、第一点的详细说明 -结构体成员变量的对齐自然边界对齐内存对齐只在结构体这部分讨论类型是n个字节的元素优先放在能被n整除的地址编号的地址上称为自然边界例如若有如下类型元素的结构体分别 char. int. short1 4 2//根据第一点char的自然边界是1int的自然边界是4short自然边界是2他们都分别放在能被自然边界整除的地址编号的地址上但是优先放能被4整除的地址编号的地址上优先最大的可能中间会空地址但空间换时间2、第二点的详细说明 -结构体整体对齐以最大的成员来对齐算完总字节数 看能否整除最大成员若不能整除则补齐至能整除[其实总长度即各类型公倍数若每个类型只有一个元素则是最小公倍数]若是元素是数组则以数组元素基类型长度为准例如若有如下类型元素的结构体分别 char a[5] 、int b、short c5*1 4 2//根据第二点这里最大成员是 int而非5因为a是char类型而char的长度是1相当于这个结构体里面罗列了5个15个char类型其实每个都算13、例子说明所以这个结构体的大小是24字节结构体类型定义的形式1.形式1 类型定义 和 变量定义分开最常用struct demo{}; //类型定义struct demo d; //变量定义2.形式2 类型定义和变量定义放到一起struct demo{}d{初始化}; //类型定义//把名字放在大括号后3.形式3 类型定义和变量定义放到一起,省略结构体名struct//没有结构体变量名{}d{初始化}; //类型定义这种结构体类型只能用一次 一次性的结构体语法细节结构体定义能放到局部结构体 和 数组区别首先都是构造类型结构体 --- 批量处理数据 --- 处理不同类型的数据数组 --- 批量处理数据 --- 处理的是同一类型的数据访问数据的方式数组 ---下标随机访问结构体 --- . 运算- 运算共用体介绍定义有时需要使几种不同类型的变量存放到同一段内存单元中这几个变量共用了一块内存空间称为共用体好处省内存 省空间用法构造类型类型 定义变量定义指针定义数组做函数形参 做函数返回值类型语法//类型定义union 共用体名{成员列表};union demo{int a;short b;char c;};重点说明1.共用体默认初始化只能初始化一个成员初始化是首个成员2.共用体的空间以最大的成员为空间大小3.成员变量起始地址是一样的但是用多少个字节取决于成员变量的类型4.连续赋值时共用体中最终结果取决于取决于最终内存中存放了什么后给到的会对前面给到数据形参覆盖5.关于截断和覆盖若给了 0X123456784字节但有成员是 short则只读2字节截断了输出 0X5678。共用体使用时存在覆盖现象后赋值的会盖前面赋的值不一定覆盖全看类型大小6.共用体成员的引用和结构体引用方式一样.-举例说明a、b、c都从第一个位置进入根据对应的字节数来输出对应长度的空间上的内容所以a、b、c的输出结果是这样并且三者的地址是一样的该共用体的长度是40X12345678┌──────┐│0X78 │小端├──────┤│0X56 │├──────┤│0X34 │├──────┤│0X12 │大端└──────┘练习考点:用共用体检测大小端写成函数共用体应用场景1. 节省空间例如struct stu{char name[20];int no;float score;};struct teacher{char name[20];int no;float salary;};//有共同的部分则可以合并为一个新的结构体并利用共同体把不同的部分打包起来因为不是一直用这个空间需要stu的时才需要score需要teacher时才需要salsry空间没充分利用上所以整合利用用到哪个调哪个整合后struct member{char name[20];int no;union data{float salary;float score;}d;};运用新结构体时struct member stu; //正常定义调用共同体部分的写法结构体变量名 . 共用体变量名 . 成员变量名student stu.d.scoreteacher stud.d.salary2. 数据转化ip地址192.168.1.93 //点分十进制//ip地址本质是一个32位整数//四个字节练习1. 利用结构体封装学生类型 姓名、性别、年龄、成绩1.封装函数从终端接收n个学生信息存放到堆区2.封装函数将接收到所有的学生信息实现打印2.有一个班的4个学生有5门课程。1、求第一门课的平均分2、找出有两门以上课程不及格的学生输出他们的学号和全部课程成绩及平均分3、找出平均分在90分以上或全部课程成绩在85分以上的学生。分别编写三个函数来实现以上三个要求关于第三个功能不可以把第二个if语句写进内层循环第一个if语句的下面并在后面加上一个break因为如果放在里面按照我的想法来的话遍历每个学生的时候遍历他第一门课的时候计算平均分的时候只有一门成绩遍历第二门课的时候计算平均分的时候只有两门成绩以此类推直到平均分大于90的时候才退出所以会存在重复遍历的情况而且如果第一门课就大于90的话那只遍历到第一门课的时候平均分就已经大于90就退出了判断也不准确