C语言|(师承郝斌老师)C语言——结构体

结构体1-为什么需要结构体?什么叫结构体? 前言:先学重要的,次重要的后面补;C语言的结构体,有助于学习Java的类
要上课认真听讲,要有效率,不然啥事干不成
学习时,要思考:什么是什么,为什么,有什么用
结构体的代码每行一定要看懂,结构体会影响到后面两门课的学习,
数据结构和面向对象,是面向对象和面向过程的链接
1、为什么需要结构体 为了表示一些复杂的事物,而普通的基本类型无法满足实际要求
2、什么叫结构体 把一些基本类型数据组合在一起形成的一个新的复合数据类型,这个叫结构体

# include ? struct Student//结构体,定义新的数据类型———学生类型 { int age; float score; char sex; }; ? int main(void) { struct Student st = {80, 98, 'A'}; //定义变量 return 0; }

3、如何定义结构体 3种方式,推荐使用第一种
//第一种方式这只是定义了一个新的数据类型,并没有定义变量 struct Student//结构体,定义新的数据类型———学生类型 { int age; float score; char sex; }; ? //第二种方式,变量同时定义好 struct Student2 { int age; float score; char sex; } st2; //注意最后有分号 ? //第三种方式,没有说明是什么类型名 struct { int age; float score; char sex; } st3; //注意最后有分号

结构体2-怎样使用结构体变量 1、赋值和初始化 定义的同时可以整体赋初值
如果定义完之后,则只能单个地 赋初值
# include ? struct Student//结构体,定义新的数据类型———学生类型 { int age; float score; char sex; }; //注意最后有个分号 ? int main(void) { struct Student st = {80, 66.6, 'F'}; struct Student st2; st2.age = 10; //st2已经被定义了,只能单个赋值了 st2.score = 88; st2.sex = 'B'; ? printf("%d %f %c\n", st.age, st.score, st.sex); printf("%d %f %c\n", st2.age, st2.score, st2.sex); ? return 0; }


2、如何取出结构体变量中的每一成员(重点) (1)结构体变量名.成员名:
(2)指针变量名 -> 成员名: 指针变量名 -> 成员名
在计算机内部会被转化为 (*指针变量名).成员名的方式来执行
以上是" ->"的含义,这是一种硬性规定
以上这两种方式是等价的
# include ? struct Student//结构体,定义新的数据类型———学生类型 { int age; float score; char sex; }; //注意最后有个分号 ? int main(void) { struct Student st = {80, 66.6f, 'F'}; struct Student *pst = &st; //&st不能改成stpst -> age = 88; //第二种方式 //st.age = 88; //第一种方式 st.score = 66.5f; /* 66.6在C语言中默认是double类型, 如果希望一个实数是float类型,则必须在末尾加f或F 因此66.6是double型,66.6f或66.6F是float类型 */ printf("%d %f\n", st.age, pst -> score); return 0; }

上面程序注释:
(1)pst ->age 在计算机内部会被转化成(*pst).age,没有为什么
这就是 -> 的含义,这也是一种硬性规定
(2)所以 pst ->age 等价于 (*pst).age 也等价于 st.age
(3)我们之所以知道pst -> age 等价于 st.age,是因为 pst ->age 是被转化成 (*pst).age来执行
(4)pst -> age 的含义:
pst 所指向的那个结构体变量中的 age 这个成员
C语言|(师承郝斌老师)C语言——结构体
文章图片




3、结构体变量和结构体变量指针作为函数参数传递的问题 推荐使用结构体指针变量作为函数参数来传递
/* 2021年11月7日12:29:54 通过函数完成对结构体变量的输入和输出 */ ? # include # include ? struct Student { int age; char sex; char name[100]; }; //分号不能省 ? void InputStudent(struct Student *); void OutputStudent(struct Student ss); ? int main(void) { struct Student st; InputStudent(&st); //对结构体变量进行输入必须发送st的地址 //printf("%d %s %c\n", st.age, st.name, st.sex); //这里输出字符串用%s,输出字符用c,否则打印不出东西 OutputStudent(st); //对结构体变量输出可以发送st的地址也可以直接发送st /* 发送地址不安全,被调用函数里有时误操作写些程序会将其修改, (C++)可以使用const, 只读不改 但为了提高发送速度,减少内存的耗用,推荐发送地址 */ ? return 0; } ? void InputStudent(struct Student * pstu)//pstu占4个字节 { (*pstu).age = 10; strcpy(pstu->name, "张三"); pstu->sex = 'F'; } ? void OutputStudent(struct Student ss) { printf("%d %s %c\n", ss.age, ss.name, ss.sex); }

发送地址还是发送内容:
指针的优点之一:快速传递数据耗用内存小执行速度快
4、结构体变量的运算 结构体变量不能相加减、不能相乘除
但结构体变量可以相互赋值
struct Student { int age; char sex; char name[100]; }; //分号不能省 struct Student st1, st2; st1 + st2st1 * st2st1/st2都是错误的 st1 = st2或者st2 = st1都是正确的

5、举例:动态构造存放学生信息的结构体数组 (1)冒泡排序:排序比查找重要,排好了就容易查了,比较复杂
如何看程序:1流程、2语句功能、3试数
看书,看着看着就看进去了,学习很有意思,应该这样去学
哪有谁是一帆风顺的,你只有拼尽全力,才可以让人看起来毫不费力
# include ? //冒泡排序 void sort(int * a, int len) { int i; int j; int t; for(i=0; i a[j+1])// > 表示升序,< 表示降序 { t = a[j]; a[j] = a[j+1]; a[j+1] = t; } ? }} ? int main(void) { int a[6] = {10, 2, 8, -8, 11, 0}; //需要排序的数组 int i; ? sort(a, 6); //调用函数,进行冒泡排序 ? for(i=0; i<6; ++i)//将排序好的数组打印出来 printf("%d", a[i]); return 0; } ?

冒泡排序示意图:如何看程序:1流程、2语句功能、3试数
C语言|(师承郝斌老师)C语言——结构体
文章图片




(2)动态构造存放学生信息的结构体数组
【C语言|(师承郝斌老师)C语言——结构体】动态构造一个数组,存放学生信息 然后按分数排序输出
# include # include ? //构造结构体学生的age、score、name struct Student { int age; float score; char name[100]; }; //注意分号 ? //主函数 int main(void) { //定义变量 int len; struct Student * pstu; int i, j; struct Student t; //动态地构造一维数组 ? printf("请输入学生个数:\n"); printf("len = "); scanf("%d", &len); pstu = (struct Student *)malloc(len * sizeof(struct Student)); ? //输入 for(i=0; i pstu[j+1].score) { t = pstu[j]; pstu[j] = pstu[j+1]; pstu[j+1] = t; ? } } ? printf("\n\n学生的信息是:\n"); //输出 for(i=0; i

    推荐阅读