当前课程知识点:C语言程序设计 > 第22讲 编程训练 > 编程训练 > 结构体及其应用(上)
我们 前面用到的数据类型
包括整形 浮点型等都属于基本数据类型
结构体是一种常见的复合数据类型
在有些场合使用它比较方便
从基本数据类型到复合数据类型
不同语言会定义不同的基本类型
C语言规定的基本数据类型有整型 浮点型 字符型等
除了基本数据以外
用户可以构造自己的数据类型 复合数据类型
复合数据类型是由基本数据类型迭代派生而来
用来表示复杂的数据对象
典型的代表就是 结构体
学习结构体你需要掌握一下四个要点
1 为什么要使用结构体
2 结构体变量的定义
3 结构体的引用
4 结构体指针
我们先看一下为什么要使用结构体
我们看一下下面这个例子
如何用计算机程序实现下述表格的管理
这个表格是学生的一些信息
包括学号 姓名 性别 出生年 数学 英语
计算机原理 程序设计这四门课的成绩
我们先看一下用前面学过的方法
用数组来解决这个问题
用数组来解决可以这样来做
首先定义这么多数组
其中的studentId是学号
studentName表示姓名
studentSex表示性别
然后yearOfBirth表示出生年
后面这几个分别表示那四门课的成绩
这个是在定义数组的同时给它进行了初始化
那么采用数组来解决这个问题当然是可以的
但是它存在一些问题
比如说分配内存不集中
寻址效率不高
这一点就先不展开讲
我们看看下面的两个问题
对数组赋初值时
易发生错位
这个是什么情况呢
比如说这位同学它的学号是100310121叫王刚 男
出生年
就本来是他的一条完整信息
但是你在用数组解决的时候
我们看到它是分散在不同数组当中的
那么正常情况下
它的赋值就都应该是这些数组的最开始的那个元素
第二个同学它的信息是这样的
它应该是在每个数组的第二个元素里面的赋值
但是当学生比较多时
很容易发生这个错位的情况
就是你输入的时候学号可能是第三个
你输入姓名时可能弄错
可能弄到第四个了
或者是偏的更远
这样就容易发生错误
另外
这种模式下
它是把同一个学生的不可分割的这种信息整体给它打散了
这样管理起来也不方便
比如说你要是把这些学生当中的某一个学生
或者某些学生要把它的信息删除掉
采用这种方式就非常麻烦
你需要一个数组一个数组的来把相应的信息给他删除
从刚才的那个实例当中我们看到
用数组的方法解决那一类问题不太可行
那么有一个好的办法就是用结构体来解决这一类问题
那么我们首先来看看结构体变量的定义方法
结构体在进行定义的时候先定义结构体类型
再定义变量名
这是结构体定义的写法
这个struct是规定的就要这么写
这个student是这个结构体的类型名
这个是可以根据不同情况来取名的
因为我们这个里面表示的是学生信息
所以就用student这个名字
然后这里面就是结构体的成员
结构体的成员包括studentId表示学号
studentName表示姓名
studentSex表示性别
yearOfBirth表示出生年
然后那四门课的成绩这个地方用了一个数组来这样来表示
前面定义了一个叫student的这样一个结构体
这个结构体还不能直接用
需要再定义结构体的变量
结构体变量在定义的时候
就是前面这struct student就是这个结构体它的名字
然后 这个是真正的变量名
那这个看起来有点长
但是实际上你理解的时候
和我们前面的那个普通变量
或者叫简单变量来一起来理解就好理解一些
比如说我们在前面使用整型的时候
我们都是比如定义一个int 、I、 j
就是int是它的类型
i、j是它的变量名
那这个地方也很类似
只不过它这个类型长一点
就写成struct这样的形式
也可以用typedef来定义数据类型
我们看用typedef来定义的时候是这样的
就是它把原来写的struct student这个结构体给它换了个名称
就是这样写
表示的意思就是我现在用这个STUDENT
这个大写的这个词来代替struct student这两个词
就表示这个的含义和这个意义是一样的
关键词typedef 为一种已存在的类型定义一个别名
注意这个别名
并未定义新类型
刚才也说了
这样写了以后这个大写的STUDENT
与struct student类型是同义词
我们看一下几种不同的形式
那你这样写是可以的
就是你定义了两个结构体的变量stu1、stu2
那么这是用直接结构体这样的方式来描述
那么这样行不行呢
这样是不行的
因为如果你这个前面不带struct的话
它不知道这个student是什么
那单写struct也不行
因为有可能你的程序当中会定义多个结构体
那你单写一个struct它不知道具体对应的是哪一个结构体
那么这样写也是可以的
就是我们刚才也讲了
大写的STUDENT他和那个struct student是同义词
所以这个地方可以这样来定义
那么我们有些时候用typedef这种方式
来定义一个结构体的时候其实一个主要的作用
是为了在后面写的时候能让他写的简单一点
别像这个
你这样定义了以后呢在后面定义变量的时候
我这只写一个这样只写一个词
而你前面这样写
你会写两个词
有些时候当比较多的时候
会觉得这样写比较繁琐
我们可能喜欢这样来写
其实这样写和这样它们是等价的
下面我们看一下结构体变量的引用
访问结构体变量的成员必须使用成员选择运算符
也称圆点运算符
我们看一下这个具体的例子
这个就是刚才前面一页讲过的typedef定义的这样一个结构体
然后这儿定义了一个结构体的变量
我们看这是这一页的重点
就是你要访问结构体的时候
我们需要对结构体当中的每一个单独的成员单独来访问
这个地方你要访问结构体里面的学号的话
那么就是这个结构体的变量名加一个点
然后这是成员名
这是成员给他赋值
那么我们稍微注意一下
就说我们前面讲过的简单变量类型的时候
比如说不管整型还是浮点型
那么我们前面就直接就是变量名
然后这个地方是具体给那个变量名赋值
这样和前面简单类型很相似
只不过就是它先要把结构体的这个变量名加上
再加一点把成员名加上
也就是说这个和简单标量相比就这么点差别
那么这是给他赋值
如果要去取它的值的话那就是把这个写到这个右边
你要把这个值取出来赋值给另外一个变量的话
那把这个写到右边
这是拿一个值赋给它
下面我们看一看结构体指针的定义和初始化
这儿
我们定义了这样一个结构体变量
这个STUDENT这个结构体类型就是假定前面已经定义好了
那么当你定义这样一个结构体变量了以后
系统会在计算机当中给你进行这样的分配
这种分配我们在前面也看到了它一共有五个成员
其中的成员5它包含了一个数组
包含了4门课的成绩
所以这个地方看到的是这个样子
这样定义了一个结构体的指针变量
然后 下面是把普通的结构体变量的取地址
取出来赋值给这个指针变量
那么这两步相当于是这一步
这一步它是在定义这个结构体指针变量的同时给它赋了值
这个赋的值就是前面定义的一个普通的结构体
变量取地址以后赋给它
这个写法其实和简单变量也是很相似的
那么这么做了以后
就相当于这个结构体指针变量指向了这儿
结构体的指针变量怎么使用呢
有两种使用方法
一种就是加*
加*号以后这个地方加点这样来访问它的成员
这是和普通的结构体变量有点类似的
通过加点这种方式
这种方式是前面这个地方不加*号
就是这儿是结构体指针变量
然后这儿加->
看起来像箭头
这样的方式
然后这是结构体成员
通过这种方式来访问
这两种方式都可以
看你愿意喜欢用哪一种
我们看一下一个结构体应用的例子
这个例子当中
首先定义了一个叫Point的这样一个结构体
你可以理解成它是数学上的一个点
它包含两个成员
一个是x坐标
一个是y坐标
然后这儿、这儿定义了两个函数
其中的这个函数
函数名叫getpoint()
它没有参数
但是它有返回类型
就是这样子
它的返回类型也是一个struct Point
就是这样一个坐标点的这样一个返回类型
那我们看具体的程序里面先定义了一个这样的结构体变量p
然后通过这个scanf从键盘上分别读入x坐标和y坐标
然后返回p
注意因为我们刚才定义的时候这个p就是结构体的变量
那么返回以后呢
这个函数的返回结果也是结构体类型
这个是一个计算距离的函数
那么它的参数是一个结构体
它的返回值是这个
这个相当于是计算这个点它到坐标原点的距离
就是根号x平方加y平方就这个意思
我们看在main函数当中
定义了这样一个结构体变量p
然后float类型d
这儿调用getpoint()这个函数
这样得到了一个坐标点
然后再调用distance(p)这个函数计算出来这个距离
然后输出这个距离
这个程序我觉得是一个比较好的一个结构体应用的实例
就是说它内容够简单
而且这个地方既演示了返回类型
是结构体的这样的一种情况
也演示了这个形参是结构体的这种情况
当然了这个程序拿来演示还是比较好的
这个功能看起来是过于简单了
实际上你不用这样的函数
直接把所有的功能写到main当中完全可以
那么我们这个地方实际上有点有意要演示这个结构体的用法
所以 把这两部分给它拆成这个两个函数来使用
-作业
-作业
-作业
-作业
-作业
-作业
-作业
-作业
-循环类型
-作业
-程序结构
-函数基础
-作业
-数组基础
-作业
-作业
-作业
-作业
-程序调试
- 文件(上)
- 编程训练



