当前课程知识点:高级语言程序设计 > 结构体和共用体 > 9.2 结构体变量及指针变量的定义及使用 > 结构体类型变量和指针变量的定义和使用
大家好
本讲介绍结构体类型变量
和指针变量的定义和使用
上一讲我们学习了自己定义结构体类型
结构体类型的功能和基本类型的功能是一致的
只是告诉编译器该如何表示数据
但是它没有让计算机为其分配空间
我们有了这个结构体类型
就可以用它来定义结构体变量了
结构体类型的变量
也需要先定义 后使用
这是我们上一讲定义的STUDENT结构体类型
定义结构体类型变量有三种方法
先来看第一种方法
先定义结构体类型
给类型定义一个别名
再定义变量
可以用struct student直接定义变量 s1
这种定义方法是合法的
在这里的定义结构体变量的时候
struct和 student
都是缺一不可的
缺少其中的任何一个
都是不能够定义结构体变量的
这两条语句是非法的
也可以用别名定义变量s1
这条语句是合法的
第二种方法是在定义类型的同时定义变量
这里stu1是结构体变量
再看
如果struct前面有typedef关键字
花括号后面的STUDENT就是结构体类型别名
这种方法定义结构体变量要注意的是
花括号后面有可能是结构体变量
也有可能是结构体类型别名
这要看前面有没有typedef关键字
第三种方法就是
不指定结构体类型的名字
直接定义结构体变量
例如我们可以这样来定义一个
具有这种类型的结构体变量stu1
不给这个结构体类型起一个名字
这样带来的问题就是
如果一次可以定义程序中所有的结构体变量的话
那么也没什么问题
但是如果
你要在程序中不同的位置
来定义相同类型的结构体变量的话
那就麻烦了
现在我们来看看
这个结构体变量的初始化问题
关于结构体变量的初始化
与初始化数组类似
这是初始化一般形式
初值表也是用花括号括起来
用逗号分隔的
注意花括号里初始化列表的初值
必须要和初始化的结构体成员类型相匹配
例如用struct student类型
定义一个结构体变量stu1
在定义的同时
还要用初值表给stu1赋值
这个时候要注意
初始化列表中第1个值是int型常量
第2个值是字符串型常量
第3个值是字符型常量
初始化列表中成员的顺序
必须和结构体类型定义的顺序保持一致
初始值必须是常量
不能是变量
初值表里面的花括号可以省略
可以将准备赋给score数组
四个初值的花括号省略
并且这个初始化也可以部分初始化
没有给出初始值的成员
系统会自动将它的初值设置为零
如果将这4个分数删掉
系统将score数组的值全置为0
这个与数组的初始化类似
如果这个结构体有内嵌的结构体成员
仍然要遵守这个规则
初始化列表中成员的顺序
必须要和结构体类型定义的顺序保持一致
逐一的对相应的成员进行初始化
来看
这是个嵌套的STUDENT类型
有一个birthday成员
birthday成员是DATE类型
现在我们定义一个变量stu1并且初始化
注意给birthday成员初始化的是3个整型常量
如果我们把DATE类型的month成员类型
修改成字符数组类型
那么在定义变量并且初始化的时候
跟month成员对应的位置
应该是一个字符串常量
结构体变量定义并且初始化时
要注意初始化列表中初始值的顺序
必须和结构体类型定义的顺序保持一致
并且初始值必须是常量
现在来看
如果我们先定义一个结构体类型
再定义一个结构体变量
怎么对这个结构体变量赋值呢
也就是如何将一个学生的信息
保存到变量stu1里
一般情况下结构体变量不能整体引用
只能引用变量成员
访问结构体变量的成员
必须使用成员选择运算符
也称圆点运算符
例如我们可以将常量403101赋给stu1.num
而访问stu1的name成员的时候
由于name成员是一个字符数组
而C语言呢
是不支持直接用字符串
对字符数组名进行复制的
所以呢
这样赋值是错误的
我们想把这个学生名字复制给这个字符数组
那么就必须使用字符串处理函数strcpy
来将这个字符串复制到这个字符数组当中去
对性别进行复制的时候
由于性别是用一个字符来表示的
所以可以直接对它进行赋值
后面的成员依次类推
再来看定义了一个嵌套的结构体的变量stu1
对它进行赋值的时候
必须以级联的方式进行访问
也就是连续使用两次成员选择运算符
首先指出
我们访问的是stu1的birthday成员
而birthday成员又是一个结构体变量
再去访问birthday这个结构体变量的year成员
后面的month和day成员是同样的
都要使用级联的方式来访问
只能对最低级的成员
进行赋值或者存取以及其它的运算
现在来看如何通过键盘给结构体变量赋值呢
定义了一个STUDENT类型的变量stu2
可以用scanf语句
来输入一个结构体变量stu2的成员的值
stu2的num成员是int型
用%d格式输入时
变量前面有取地址运算符
stu1的name成员是字符数组类型
用%s的格式输入时
name本身就是字符数组的数组名
它代表了这个数组的首地址
name前面是不需要添加一个取地址运算符的
stu1的sex成员是字符类型
为什么要在%c格式字符前面加一个空格呢
这是因为前面在输入学生的姓名之后呢
输入了一个回车符
如果不在百分号前面加上一个空格的话
那么前面输入的回车符
就会被后面的这条scanf语句
将这个回车符读入
那性别就无法再输入到sex成员了
所以我们在%c前面的要加一个空格
就可以利用这个空格
忽略掉前面输入的这个回车符
从而保证能够输入一个正确的学生的性别
接下来
输入学生的出生年月日
这里是以级联的方式来输入stu2
这个结构体变量的birthday成员的
year month和day三个成员的
在输入这个学生的四门课成绩的时候
我们可以四条scanf语句
也可以用这样的一个for循环语句
来输入学生的四门课的成绩
大家请考虑考虑
如何输出变量stu2的值
请大家自行写出对应的输出语句
我们要强调的是
C语言不能将一个结构体变量
作为一个整体进行输入输出
只能对各个成员变量分别输入输出
但是C语言允许将一个结构体变量
直接赋给另一个具有相同结构的结构体变量
数组是不允许以这种整体的方式进行赋值的
结构体允许以这种方式进行整体赋值
例如 定义了结构体变量stu1和stu2
可以直接用赋值运算符将stu1的值整体赋给stu2
结构体变量整体赋值的时候
只能在相同类型的结构体变量之间进行
因为数组是不允许
以这种整体的方式进行赋值的
直接将a赋给b是错误的
来看一个关于结构体变量操作的演示程
将一个学生的信息初始化
另一个学生的信息从键盘输入
然后交换两个学生的信息
再输出交换后学生的信息
这是结构体类型的定义
这是主函数
定义了3个结构体变量s1 s2 s3
并且初始化了s1
这一段代码是从键盘输入结构体变量s2的值
利用s3
交换两个结构体变量s1和s2的值
这一段代码是输出交换后的结构体变量
s1和s2所有成员的值
目前为止
我们交换过两个整型变量的值
交换过两个字符串的值
现在我们还可以交换两个结构体变量的值
请大家对比C语言
对这几种类型数据的处理方法
现在我们来看看
结构体指针的定义和初始化
前面我们已经学习过很多种类型的指针
比如说变量的指针
数组的指针等等
那么现在我们就来学习结构体的指针
首先来看
如何定义一个指向结构体变量的指针呢
所谓结构体指针就是指向结构体变量的指针
当然首先要定义一个结构体类型STUDENT
然后呢
用这个STUDENT类型来定义一个变量stu1
接下来呢
就是定义一个STUDENT类型的指针变量pt
但是这条语句只是定义了一个结构体指针而已
并没有让这个结构体指针指向一个结构体变量
pt = &stu1
这样呢
就使得结构体指针变量pt
指向了结构体变量stu1
这两条语句呢
也可以写成这样的一条语句
可以在定义pt的同时
将stu1的地址赋给pt
将pt进行初始化
那么定义完一个结构体指针变量之后
如何通过pt访问
它所指向的结构体变量stu1呢
前面的我们已经学习了
要想访问一个结构体变量的某个成员
就需要使用成员选择运算符
例如我们要访问结构体变量
stu1的num的成员
我们就可以这样来访问
而现在呢
我们定义了一个结构体指针变量pt
并且让pt指向了stu1
*pt等价于stu1
那么也可以这样访问stu1的num成员了
实际上
在C语言中
还提供了另外一种运算符
用于访问指针变量指向的结构体成员
就是指向运算符
指向运算符
是用一个短横线和一个大于号构成的
这里需要注意的一点就是
这个短横线和大于号中间
是不能有空格的
那么可以通过指向运算符
来访问pt所指向的结构体变量stu1的n成员
那么当结构体嵌套的时候
如何来访问结构体指针变量
指向的结构体成员
例如STUDENT现在是嵌套的结构体类型
用这个嵌套的STUDENT类型定义了一个变量stu1
定义了指针变量pt
将pt指向stu1
那么我们如何来访问
stu1中的birthday成员中的year成员呢
我们可以通过这种级联的方式来访问
注意比较这三条语句
来看这第3条语句
pt和birthday成员之间是指向运算符
birthday成员和year成员呢
是圆点运算符
好了
本讲介绍了结构体变量
和结构体指针变量的定义和使用
谢谢大家
-1.1 计算机程序和计算机语言
-1.2 C程序的构成
--C程序的构成
-1.3 C语言编辑、编译、运行(VC++2010学习版)
-练习题
-2.1 变量的定义和使用
--变量的定义和使用
-2.2 数据类型
--数据类型简介
--整型数据
--实型数据
-2.3 格式输出和格式输入
-2.4 运算符和表达式
--运算符和表达式
-2.5 结构化程序设计入门
-练习题
-3.1 为什么要用选择结构解决问题
-3.2 如何正确表示选择结构中的条件
-3.3 用if语句及if语句嵌套实现选择结构
-3.4 用switch语句实现选择结构
-练习
-4.1 循环的引入
-4.1 循环的引入--作业
-4.2 用while语句实现循环
-4.3 用do-while语句实现循环
-4.4 用for语句实现循环
-- 用for语句实现循环
-4.4 用for语句实现循环--作业
-4.5 何时需要用循环的嵌套
-4.6 如何提前终止循环和提前结束本次循环
-习题--作业
-5.1 数组类型的引入
--数组类型的引入
-5.2 一维数组的定义和初始化
-5.3 一维数组的使用
--一维数组的使用
-5.4 二维数组的定义和初始化
-5.5 二维数组的使用
--二维数组的使用
-习题--作业
-6.1 什么是指针
--什么是指针
-6.2 指针类型及相关概念
-6.3 指针变量的定义、赋值与使用
-6.4 指针的运算
--指针的运算
-6.5 指针与一维数组
--指针与一维数组
-6.6 指针的指针
--指针的指针
-6.7 指针与二维数组
--指针与二维数组
-习题--作业
-7.1 为什么要自定义函数
-7.2 函数的定义
--函数的定义
-7.3 函数的调用
--函数的调用
-7.4 函数参数的传递
--函数参数的传递
-7.5 函数的嵌套调用和递归调用
-7.6 变量的作用域和存储类型
-习题--作业
-8.1 字符串的存储及输入输出
-8.2 系统字符串处理函数
-8.3 自定义字符串处理函数
-习题--作业
-9.1 结构体类型的定义
--结构体类型的定义
-9.2 结构体变量及指针变量的定义及使用
-9.3 结构体变量和指针变量作函数的参数
-9.4 结构体数组的定义和使用
-9.5 共用体类型和枚举类型
--共用体和枚举类型
-习题--作业
-动态内存分配--习题
-习题--作业