您的位置:首页 > 编程语言 > C语言/C++

结构体与共用体(转自C语言习题解析 李春葆 第3版)

2012-11-12 16:31 232 查看
定义结构体类型,定义结构体变量,结构体变量的初始化,结构体变量的成员的引用
1、结构体类型与结构体变量
数组是具有相同数据类型的数据序列,结构体是不同数据类型的数据序列,但这两种“数据”是不同的,前者是数据元素,后者是数据域。结构体是一种构造数据类型,即先要定义结构体类型,然后定义其结构体变量(顺序不可颠倒(说明结构体然后定义结构体))。
(1)结构体类型说明
结构体由不同类型的数据域组成。组成结构体的每个数据域称为该结构体的成员项,简称成员。
在程序中使用结构体变量时,首先要对结构体类型进行描述,这称为结构体类型说明。结构体类型说明的一般形式如下:
struct 结构体名
{
数据类型 成员名1;
数据类型 成员名2;
...
数据类型 成员名n;
};
其中struct是关键字,其后是说明的结构体类型的名字,它们两者组成了结构体数据类型的标示符。在结构体名下面的大括号中,是组成该结构类型的各成员项的说明。每个结构体可以含有多个相同类型的成员名,这些成员名之间以逗号分隔。结构体类型中的成员名可以和程序中的其它变量同名;不同结构体类型中的成员也可以同名。
(2)结构体变量的定义
说明该结构体后,就可以指明使用该结构体的具体对象,即定义结构体的变量(简称结构体变量)。可以使用以下几种方式定义结构体变量:
a、先定义结构体类型再定义结构体变量
一般形式如下:struct 结构体名 结构体变量名表;
例如以下语句说明了student结构体的两个变量student1和student2:struct student student1,student2;
b、在定义结构体类型的同时定义结构体变量
一般形式如下:struct 结构体名
{
结构体成员表;
} 结构体变量名表;
这里先说明了一个有名的结构体变量,然后定义其变量。例如以下语句说明了student结构体的同时定义了两个结构体变量student1和student2。
struct student
{
结构体成员表;
}student1,student2;
c、直接定义结构体类型变量
这种方式不需要给出结构体类型名,然后定义其变量,而是直接给出结构体类型并定义结构体变量,其一般形式如下:
struct
{
结构体成员表;
}结构体变量名表;
这里先说明了一个无名的结构体类型,然后定义其变量。例如:
struct
{
结构体成员表;
}student1,student2;
(3)结构体成员的引用
结构体成员的引用一般有两种方式:
结构体变量名.成员名   或    结构体指针变量名->成员名
(4)结构体变量的初始化
结构体类型时数组类型的扩充,可以在定义结构体变量的同时,对它的每个成员赋初值。结构体变量的初始化规则与数组形同。结构体变量初始化的一般形式如下:struct 结构体名 变量={初始数据列表}。例如定义一个结构体sample如下:
struct sample
{
int a;
int b;
float c;
}
则:
struct sample st={1};//后面没有的自动赋初值为0,如果是数值型或字符型数据的话。
struct sample st={1,2};
struct sample st={1,2,3.4};
 
例子:
7.1.3:typedef struct
{
int n;
char ch[8];
}PER;
这里利用typedef指明一个无名的结构体类型的名称为PER。
共用体的大小是最大成员的大小。
2、结构体数组和结构体指针
(1)结构体数组
定义:struct 结构体类型名  结构体数组名[元素个数];
结构体数组的初始化:C语言中规定,只能对全局的或静态结构体数组进行初始化。
(2)结构体指针
结构体指针指向结构体变量所分配的存储区域的首地址。
a、结构体变量指针定义和使用
C语言引入了一个指向运算符“->”,用于连接指针变量与其指向的结构体变量的成员。优先级最高。
b、结构体数组指针
结构体数组指针是指向结构体数组的指针变量。其只能指向该结构体数组中的一个元素,而不能直接指向一个成员。
*p++=*(p++)
3、函数之间结构体变量的数据传递
和其它变量一样,结构体变量也可以作为函数参数,用于在函数之间传递数据。结构体变量的数据传递方式有以下几种方式:
(1)结构体赋值方式(值传递)
实际上是进行实参到形参的结构体变量对应成员项之间的数据复制。
(2)结构体地址传递方式
(3)结构体数组在函数间传递
当需要把多个结构体作为一个参数向函数传递时,应该把他们组织成结构体数组,一般采用地址传递方式,即把结构体数组的存储首地址作为实参。
4、结构体的应用——链表
链表是指将若干个节点相互连接起来的点。如果每一个节点只有一个指针域,称为单链表;如果每个节点有两个指针域,称为双链表。单链表的连接原则是,前一个节点指向下一个节点,只有通过前一个节点才能找到下一个节点。
为了实现链表操作,需要动态地分配和释放内存空间。C语言提供了两个动态分配和释放内存空间的函数malloc和free函数。由于malloc函数返回的指针为void *(无值型),故在调用时,需要使用强制类型转换将其转换成所需的类型。链表带有一个头结点,其余的为数据节点,从数据节点开始编号。对链表的操作包括建立链表(例如尾插法建表)、查询链表、插入链表、删除链表和释放链表。
5、二叉树
二叉树是解决层次问题最有效的数据结构之一。
(1)二叉树的定义与二叉链存储结构
无左右子树的节点称为叶子节点。其它非叶子节点称为分支节点(含根节点)。只有一个孩子节点的分支节点称为单分支节点,有两个孩子节点的分支节点称为双分支节点。
用二叉链方式存储二叉树时,每个节点除了存储节点本身的数据外,还应设置两个指针域lchild和rchild,分别指向该节点的左孩子和右孩子。
(2)二叉树的遍历
所谓遍历就是查找每个节点,且不重复查找。不同于单链表,二叉树不能从头向尾直接查找,只能分层的查找所有节点。根据访问根节点的次序,二叉树的遍历方式分为先序(访问根节点的操作发生在遍历左右子树之前)、中序(访问根节点的操作发生在遍历左右子树之间)和后序遍历(访问根节点的操作发生在访问左右子树之后)。
(3)二叉排序树
二叉排序树或者是空树或者是满足下列条件的二叉树:
a、若它的左子树非空,则左子树上记录的所有值均小于根纪录的值;
b、若它的右子树非空,则右子树上记录的所有制均大于根记录的值;
c、左右子树又分别都是二叉排序树。
二叉排序树也可采用二叉链的存储结构。
在二叉排序树*bt中查找值为k的节点过程:略。(查找节点算法)
6、共用体
在C语言中,可以定义不同类型的数据使用共用的存储区域,这种形式的数据构造类型称为共用体。共用体与结构体的定义、说明和引用形式很相似,但他们在存储空间的占用和分配上有着本质的区别。
共用体变量的特点如下:
(1)共用体变量在定义的同时只能用第一个成员的类型的值进行初始化。
(2)共用体所有成员共用一段公共存储区,所以共用体变量所占内存字节数与其成员中所占字节数最多的成员相等。
(3)共用体变量与其所有成员的地址相同。
(4)共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原来的成员就失去作用。(全部覆盖)
(5)共用体变量不能作为函数参数,但指向共用体变量的指针可以作为函数参数。
一旦定义共用体变量后,只能引用变量成员,而不能引用变量。
各种进制的数字在内存中的存储方式?
7、枚举类型
它用于声明一组命名的常数,当一个变量有几种可能的取值时,可以将它定义为枚举类型。
枚举是一个命名为整形常量的集合。
其一般形式为:enum 枚举名 {枚举元素表} 枚举变量表;
枚举元素表中的枚举元素都表示一个整数值,且可以用在任意的整形表达式中。
有关枚举变量的说明如下:
(1)枚举元素是按常量处理的,如果没有进行初始化,第一个枚举元素的值为0,第二个为1,以此类推。
(2)对应枚举变量只能取枚举元素表中的某个元素,而不能取其它值,如不能把整数直接赋给枚举变量。
(3)若想将整数值赋给枚举变量,需作强制类型转换。
枚举元素只能是符号,其值只能是整数。
8、用户自定义类型
C语言允许用typedef说明一种新的类型名,其一般形式为typedef 类型名1 类型名2;其中类型名1是系统提供的标准类型名或已经定义过的其它类型名,类型名2就是用户定义的类型名。使用用户定义类型时注意一下几点:
(1)用typedef只能定义各种用户定义类型名,而不能用于定义变量;
(2)用户定义类型相当于原类型的别名;
(3)typedef并不只是做简单的字符串替换,与#define的作用不同;
(4)typedef定义类型名可嵌套进行;
(5)用typedef定义类型名有利于程序的移植,并增加程序的可读性。
typedef char NAME[10];定义NAME为字符型数组类型名;
typedef char* POINT;定义POINT为字符型指针类型名;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C语言 结构体