C++程序设计 湖南大学 杜四春、银红霞
第 7章 结构体与共用体
7.1 结构体的概念
7.2 结构体类型变量
的定义方法
7.3 结构体变量的使
用形式和初始化
7.4 结构体数组
7.5 结构体与指针
7.6 结构体与函数
7.7 共用体
C++程序设计 湖南大学 杜四春、银红霞
在实际的处理对象中,有许多信息是由多
个不同类型的数据组合在一起进行描述,而且
这些不同类型的数据是互相联系组成了一个有
机的整体。此时,就要用到一种新的构造类型
数据 —— 结构体( structure),简称结构。结
构体的使用为处理复杂的数据结构(如动态数
据结构等)提供了有效的手段,而且,它们为
函数间传递不同类型的数据提供了方便。
同时也介绍在相同存储区域内存储不同数
据类型的构造类型 ――共用体(也称联合体)
的相关概念。
C++程序设计 湖南大学 杜四春、银红霞
7.1 结构体的概念
结构体是用户自定义的新数据类型,在结
构体中可以包含若干个不同数据类型和不同意
义的数据项(当然也可以相同),从而使这些
数据项组合起来反映某一个信息。结构体相当
于 COBOL 和 PASCAL等高级语言中的“记录” 。
例如,可以定义一个职工 worker结构体,
在这个结构体中包括职工编号、姓名、性别、
年龄、工资、家庭住址、联系电话。这样就可
以用一个结构体数据类型的变量来存放某个职
工的所有相关信息。并且,用户自定义的数据
类型 worker也可以与 int,double等基本数据类
型一样,用来作为定义其他变量的数据类型。
C++程序设计 湖南大学 杜四春、银红霞
定义一个结构体类型的一般形式为:
struct 结构体名
{
数据类型 成员名 1;
数据类型 成员名 2;

数据类型 成员名 n;
};
在大括号中的内容也称为“成员表列”或“域
表”。其中,每个成员名的命名规则与变量名相同;
数据类型可以是基本变量类型和数组类型,也可以是
指针变量类型,或者是一个结构体类型;用分号“;”
作为结束符。整个结构的定义也用分号作为结束符,
C++程序设计 湖南大学 杜四春、银红霞
例如:定义一个职工 worker结构体如下:
struct worker
{ long number;
char name[20];
char sex; //sex是成员名
int age;
float salary;
char address[80];
char phone[20]; }; //注意分号不要省略
int sex=10; //sex是变量名
C++程序设计 湖南大学 杜四春、银红霞
结构体类型中的成员名可以与程序中的变量名相
同,二者并不代表同一对象,编译程序可以自动对它
们进行区分。
最后, 总结一下结构体类型的特点:
( 1) 结构体类型是用户自行构造的 。
( 2) 它由若干不同的基本数据类型的数据构成 。
( 3)它属于 C++语言的一种数据类型,与整型、
实型相当。因此,定义它时不分配空间,只有用它定
义变量时才分配空间。
C++程序设计 湖南大学 杜四春、银红霞7.2 结构体类型变量
的定义方法
结构体只是用户自定义的一种数据类型, 因此要
通过定义结构体类型的变量来使用这种类型 。 通常有
三种形式来定义一个结构体类型变量, 分别说明如下:
7.2.1 先定义结构体类型再定义变量名
这是 C++语言中定义结构体类型变量最常见的方
式, 一般语法格式如下:
struct 结构体名
{
成员表列;
};
struct 结构体名 变量名;
C++程序设计 湖南大学 杜四春、银红霞
例如, 定义几个职工变量:
struct worker
{
long number;
char name[20];
char sex;
int age;
float salary;
char address[80];
char phone[20];
};
struct worker worker1,worker2;
C++程序设计 湖南大学 杜四春、银红霞
注意:, struct worker”代表类型名, 不能分开写
为:
struct worker1,worker2;
//错误, 没有指明是哪种结构体类型

worker worker1,worker2;
//错误, 没有 struct关键字
//系统不认为 worker是结构体类型
为了使用上的方便, 程序员通常用一个符号常量
代表一个结构体类型 。 即在程序开头加上下列语句:
#define WORKER struct worker;
这样在程序中,WORKER与 struct worker完全等效。
C++程序设计 湖南大学 杜四春、银红霞
例如:
WORKER
{ long number;
char name[20];
char sex;
int age;
float salary;
char address[80];
char phone[20]; };
WORKER worker1,worker2;
此时, 可以直接用 WORKER 定义 worker1,
worker2两个变量, 而不必再写关键字 struct。
C++程序设计 湖南大学 杜四春、银红霞
如果程序规模比较大, 往往将对结构体类型的定
义集中写入到一个头文件 ( 以,h为后缀 ) 中 。 哪个源
文件需用到此结构体类型则可用 #include命令将该文件
包含到本文件中 。 这样做便于程序的修改和使用 。
7.2.2 在定义类型的同时定义变量
这种形式的定义的一般形式为:
struct 结构体名
{
成员表列;
}变量名;
C++程序设计 湖南大学 杜四春、银红霞
例如:
struct worker
{ long number;
char name[20];
char sex;
int age;
float salary;
char address[80];
char phone[20];
} worker1,worker2;
此例与前例作用相同,都定义了两个变量 worker1、
worker2,它们是结构体类型 struct worker。
C++程序设计 湖南大学 杜四春、银红霞
7.2.3 直接定义结构类型变量
其一般形式为:
struct //没有结构体名
{
成员表列
}变量名;
C++程序设计 湖南大学 杜四春、银红霞
例如:
struct
{
long number;
char name[20];
char sex;
int age;
float salary;
char address[80];
char phone[20];
} worker1,worker2;
C++程序设计 湖南大学 杜四春、银红霞
一个结构体变量占用内存的实际大小, 也可以利
用 sizeof运算求出 。 它的运算表达式为:
sizeof( 运算量 )
//求出给定的运算量占用内存空间的字节数
其中运算量可以是变量、数组或结构体变量,也
可以是数据类型的名称。
例如:
sizeof(struct worker)
sizeof(worker1)
C++程序设计 湖南大学 杜四春、银红霞
7.3 结构体变量的
使用形式和初始化
7.3.1 结构体变量的使用形式
在定义了结构体变量以后, 就可以使用这个变量 。
结构体变量是不同数据类型的若干数据的集合体 。 在
程序中使用结构体变量时, 一般情况下不能把它作为
一个整体参加数据处理, 而参加各种运算和操作的是
结构体变量的各个成员项数据 。
结构体变量的成员用以下一般形式表示:
结构体变量名,成员名
例如, 上节给出的结构体变量 worker1具有下列七
个成员:
worker1.number; worker1.name; worker1.sex;
worker1.age; worker1.salary; worker1.address;
worker1.phone
C++程序设计 湖南大学 杜四春、银红霞
在定义了结构体变量后, 就可以用不同的赋值方
法对结构体变量的每个成员赋值 。 例如:
strcpy(worker1.name,”Zhang San”);
worker1.age=26;
strcpy(worker1.phone,”1234567”);
worker1.sex=’m’;
:
:
除此之外,还可以引用结构体变量成员的地址以
及成员中的元素。例如:引用结构体变量成员的首地
址 &worker1.name;引用结构体变量成员的第二个字
符 worker1.name[1];引用结构体变量的首地址
&worker1。
C++程序设计 湖南大学 杜四春、银红霞
在使用结构体类型变量时有以下几点需要加以注
意:
( 1) 不能将一个结构体类型变量作为一个整体加
以引用, 而只能对结构体类型变量中的各个成员分别
引用 。
例如, 对上面定义的结构体类型变量 wan,下列引
用都是错误的:
cout<<wan;
cin>>wan;
但是可以如下引用:
cout<<wan.name;
cin>>wan.name;
C++程序设计 湖南大学 杜四春、银红霞
( 2) 如果成员本身又属一个结构体类型, 则要用
若干个成员运算符, 一级一级地找到最低的一级成员 。
只能对最低级的成员进行赋值或存取以及运算 。 例如,
对上面定义的结构体类型变量 worker1,可以这样访问
各成员:
worker1.age
worker1.name
worker1.birthday,year
worker1.birthday,month
worker1.birthday,day
注意:不能用 worker1.birthday来访问 worker1变
量中的成员 birthday,因为 birthday本身是一个结构体
变量。
C++程序设计 湖南大学 杜四春、银红霞
( 3) 对成员变量可以像普通变量一样进行各种运
算 ( 根据其类型决定可以进行的运算 ) 。 例如:
worker2.age=worker1.age;
sum=worker1.age+worker2.age;
worker1.age++;
( 4)在数组中,数组是不能彼此赋值的,而结构
体类型变量可以相互赋值。
在 C++程序中,同一结构体类型的结构体变量之
间允许相互赋值,而不同结构体类型的结构体变量之
间不允许相互赋值,即使两者包含有同样的成员。
C++程序设计 湖南大学 杜四春、银红霞
7.3.2 结构体变量的初始化
与其他类型变量一样, 也可以给结构体的每个成
员赋初值, 这称为结构体的初始化 。 有两种初始化形
式, 一种是在定义结构体变量时进行初始化, 一般语
法格式如下:
struct 结构体名 变量名 ={初始数据表 };
另一种是在定义结构体类型时进行结构体变量的
初始化 。 一般语法格式如下:
struct 结构体名
{
成员表列;
}变量名 ={初始数据表 };
C++程序设计 湖南大学 杜四春、银红霞
例如, 前述 student结构体类型的结构体变量 wan在
说明时可以初始化如下:
struct student wan={”Wan Jun”,’m’,20,” SuZhou
Road No.100”};
它所实现的功能, 与下列分别对结构体变量的每
个成员赋值所实现的功能相同:
strcpy(wan.name,” Wan Jun”);
wan.sex=’m’;
wan.age=20;
wan.addr=” SuZhou Road No.100”;
C++程序设计 湖南大学 杜四春、银红霞
与数组的初始化特性相同,结构体的初始化仅限
于外部的和 static型结构体。也就是说,在函数内部对
结构体进行初始化时,必须指定该结构体为 static型。
对缺省存储类型的 auto型结构体不能在函数内部对它
们进行初始化。
C++程序设计 湖南大学 杜四春、银红霞
7.4 结构体数组
具有相同结构体类型的结构体变量也可以
组成数组,称它们为结构体数组。结构体数组
的每一个数组元素都是结构体类型的数据,它
们都分别包括各个成员(分量)项。
7.4.1 结构体数组的定义
定义结构体数组的方法和定义结构体变量的方法
相仿,只需说明其为数组即可。可以采用三种方法:
C++程序设计 湖南大学 杜四春、银红霞
1,先定义结构体类型, 再用它定义结构体数组 。
结构体数组的定义形式如下:
struct 结构体名
{
成员表列;
};
struct 结构体名
例如:
struct student
{
char name[20];
char sex;
int age;
char addr[20];
};
struct student stu[3];
C++程序设计 湖南大学 杜四春、银红霞
2,在定义结构体类型同时定义结构体数组 。
结构体数组的定义形式如下:
struct 结构体名
{
成员表列;
}数组名 [元素个数 ];
例如:
struct student
{
char name[20];
char sex;
int age;
char addr[20];
}stu[3];
C++程序设计 湖南大学 杜四春、银红霞
3,直接定义结构体数组
结构体数组的定义形式如下:
struct //没有结构体名
{
成员表列;
}数组名 [元素个数 ];
例如:
struct
{
char name[20];
char sex;
int age;
char addr[20];
}stu[3];
C++程序设计 湖南大学 杜四春、银红霞
结构体数组名表示该结构体数组的存储首地址 。
结构体数组适合于处理由若干具有相同关系的数
据组成的数据集合体。用结构体数组处理数据时可以
使用循环,从而使程序十分简炼。
C++程序设计 湖南大学 杜四春、银红霞
7.4.2 结构体数组的初始化
结构体数组在定义的同时也可以进行初始化, 并
且与结构体变量的初始化规定相同, 只能对全局的或
静态存储类别的结构体数组初始化 。
结构体数组初始化的一般形式是:
struct 结构体名
{
成员表列;
};
struct 结构体名 数组名 [元素个数 ]={初始数据表 };
C++程序设计 湖南大学 杜四春、银红霞
或者:
struct 结构体名
{
成员表列;
}数组名 [元素个数 ]={初始数据表 };
在对结构体数组进行初始化时,方括号 [ ]中元素
个数可以不指定。编译时,系统会根据给出初始的结
构体常量的个数来确定数组元素的个数。
由于结构体变量是由若干不同类型的数据组成,
而结构体数组又是由若干结构体变量组成 。 所以要特
别注意包围在大括号中的初始数据的顺序, 以及它们
与各个成员项间的对应关系 。
C++程序设计 湖南大学 杜四春、银红霞
7.4.3 结构体数组的使用
一个结构体数组的元素相当于一个结构体变量,
因此前面介绍的有关结构体变量的规则也适应于结构
体数组元素 。 以上面定义的结构体数组 stu[3]为例说明
对结构体数组的引用:
( 1) 引用某一元素中的成员 。
若要引用数组第二个元素的 name成员, 则可写为:
stu[1].name
若数组已如前所示进行了初始化, 则 stu[1].name的
值为, Liu Yong”。
C++程序设计 湖南大学 杜四春、银红霞
( 2) 可以将一个结构体数组元素值赋给同一结构
体类型的数组中的另一个元素, 或赋给同一类型的变
量 。 如:
struct student stu[3],student1;
现在定义了一个结构体类型的数组, 它有 3个元素,
又定义了一个结构体类型变量 student1,则下面的赋
值是合法的 。
student1=stu[0];
stu[0]=stu[1];
stu[1]=student1;
C++程序设计 湖南大学 杜四春、银红霞
( 3) 不能把结构体数组元素作为一个整体直接进
行输入输出 。 如:
cout<<stu[0];

cin>>stu[0];
都是错误的 。
只能以单个成员为对象进行输入输出, 如:
cin>>stu[0].name;
cin>>stu[1].num;
cout<<stu[0].name;
cout<<stu[1].num;
C++程序设计 湖南大学 杜四春、银红霞
7.5 结构体与指针
通常把指向结构体变量的指针称为结构体指针,
把指向结构体数组或数组元素的指针称为结构体数组
指针。
7.5.1 结构体指针
可以设一个指针变量用来指向一个结构体变量,
此时该指针变量的值是结构体变量的起始地址, 该指
针称为结构体指针 。 结构体指针与前面介绍的各种指
针变量在特性和方法上是相同的 。 与前述相同, 在程
序中结构体指针也是通过访问目标运算, *” 访问它的
目标结构体 。 结构体指针在程序中的一般定义形式为:
struct 结构体名 *结构指针名;
其中的结构体名必须是已经定义过的结构体类型。
C++程序设计 湖南大学 杜四春、银红霞
例如, 对于上一节中定义的结构体类型 struct
student,可以说明使用这种结构体类型的结构指针如
下:
struct student *pstu;
其中 pstu是指向 struct student结构体类型的指针。
结构体指针的说明规定了它的数据特性,并为结构体
指针本身分配了一定的内存空间。但是指针的内容尚
未确定,即它的具体指向是不定的。前面讲过,在程
序中注意不要使用不定向的指针。因此,指针在使用
之前,必须通过初始化或赋值运算把实际存在的某个
结构体变量的存储地址赋于它。这时要求结构体指针
与结构体变量必须属于相同的结构体类型。
C++程序设计 湖南大学 杜四春、银红霞
当表示指针变量 p所指向的结构体变量中的成员时,
,( *结构体指针名 ),成员名, 这种表示形式总是需
要使用圆括号, 显得很不简炼 。 因此, 对于结构体指
针指向的结构体成员项, 给出了另外一种简洁的表示
方法, 如下表示:
结构体指针名 ->成员名
它与前一种表示方法在意义上是完全等价的 。 例
如, 结构体指针 p指向的结构体变量中的成员 name可
以表示如下:
( *p),name 或 p->name
在后种表示方法中,,->”(减号和大于号)也是
一种运算符。从表 2-4中看出,它在第一运算优先级中。
它表示的运算意义是,访问指针指向的结构体变量中
的成员。
C++程序设计 湖南大学 杜四春、银红霞
7.5.2 结构体数组指针
在 C++语言中,把指向结构体数组或数组元素的
指针称为结构体数组指针。
例 7-7
C++程序设计 湖南大学 杜四春、银红霞
7.5.3 结构体指针数组
在一个数组中,若每个元素都是一个结构体指针,
则称为结构体指针数组。
例 7-8
C++程序设计 湖南大学 杜四春、银红霞
7.6 结构体与函数
在调用函数时, 可以把结构体变量的值作为参数
传递给函数 。 由于结构体是多个数据的集合体, 当把
它们传递给函数时, C++的编译系统不允许把结构体
变量整体作为一个参数传递到函数中去 。 因此, 只能
把每个结构体变量的成员作为一个个的参数传递到函
数中去 。 例如, 用 stu[1].name或 stu[2].age作函数实
参, 将实参值传给形参 。 这种用法和用普通变量作实
参是一样的, 属, 值传递, 方式 。 这种方式一般不常
用 。
一种常用的方式是,与数组在函数间传递一样,
结构体传递给函数时,一般采用地址传递方式,即把
结构体变量(或数组)的存储地址作为参数向函数传
递,函数中用指向相同结构体类型的指针接收该地址
值。然后,在函数中通过这个结构体指针来处理结构
体变量(或数组)中的各项数据。
C++程序设计 湖南大学 杜四春、银红霞
7.6.1 传递结构值
结构体可以按值传递,这种情况下整个结构值都
将被复制到形参中去。
例 7-9
C++程序设计 湖南大学 杜四春、银红霞
7.6.2 传递结构体的引用
结构体也可以引用传递, 这种情况下仅仅把结构
体变量地址传递给形参 。 引用传递效率较高, 因为它
不用传递整个结构体变量的值, 节省了传递的时间和
空间 。
例 7-10
C++程序设计 湖南大学 杜四春、银红霞
7.6.3 传递结构体的指针
结构体变量(或数组)的值也可以通过结构体指
针传递,但程序的可读性比引用传递要差一些。
例 7-11
C++程序设计 湖南大学 杜四春、银红霞
7.7 共用体
7.7.1 共用体的概念
在 C++语言中,不同数据类型的数据可以使用共
同的存储区域,这种数据构造类型称为共用体,简称
共用,又称联合体。共用体在定义、说明和使用形式
上与结构体相似。两者本质上的不同仅在于使用内存
的方式上。
定义一个共用体类型的一般形式为:
union 共用体名
{
成员表列;
};
C++程序设计 湖南大学 杜四春、银红霞
例如:
union gy
{
int i;
char c;
float f;
};
就定义了一个共用体类型 union gy,它由三个成员
组成,这三个成员在内存中使用共同的存储空间。由
于共用体中各成员的数据长度往往不同,所以共用体
变量在存储时总是按其成员中数据长度最大的成员占
用内存空间。如上述共用体类型 union gy的变量占用 4
个字节的内存。
C++程序设计 湖南大学 杜四春、银红霞
在这一点上共用体与结构体不同,结构体类型变
量在存储时总是按各成员的数据长度之和占用内存空
间。
例如, 定义了一个结构体类型:
struct gy
{
int i;
char c;
float f;
};
则结构体类型 struct gy的变量占用的内存为
2+1+4=7个字节 。
C++程序设计 湖南大学 杜四春、银红霞
定义共用体类型变量的方法与定义结构体类型变
量的方法相似,也有三种方法,
1,union 共用体名
{
成员表列;
}变量表列;
例如:
union gy
{
int i;
char c;
float f;
}a,b,c;
C++程序设计 湖南大学 杜四春、银红霞
2,将共用体类型定义与共
用体变量定义分开:
union gy
{
int i;
char c;
float f;
};
union gy a,b,c;
3,直接定义共用体变
量:
union
{
int i;
char c;
float f;
}a,b,c;
上面几种方法都是定义了一个共用体类型 union
data,又定义了几个共用体类型变量 a,b,c。
C++程序设计 湖南大学 杜四春、银红霞
与结构体类型, 也可以定义共用体指针和共用体
数组 。
union 共用体名 *共用指针名;
union 共用体名 数组名 [元素个数 ];
例如:
union gy *pu;
union gy u1[3];
分别定义了共用体指针 pu和共用体数组 u1[3]。
C++程序设计 湖南大学 杜四春、银红霞
7.7.2 共用体变量的使用形式
由于共用体变量的各个成员使用共同的内存区域,
所以共用体变量的内存空间在某个时刻只能保持某个
成员的数据 。 由此可知, 在程序中参加运算的必然是
共用体变量的某个成员,而不能直接使用共用体变量 。
共用体变量成员的表现形式与结构体相同, 它们也使
用访问成员运算符,,”和, ->”表示 。
例如, 前面定义了 a,b,c为共用体类型变量, 下
面的使用形式是正确的:
a.i 引用共用体变量中的整型变量 i
a.c 引用共用体变量中的字符变量 c
a.f 引用共用体变量中的实型变量 f
C++程序设计 湖南大学 杜四春、银红霞
不能只引用共用体类型变量, 例如,cout<<a是错
误的, a的存储区有好几种类型, 分别占不同长度的存
储区, 仅写共用体类型变量名 a难以使系统确定究竟输
出的是那一个成员的值 。 应该写成 cout<<a.i或者
cout<<a.c等 。
在使用共用体类型变量的数据时要注意:在共用
体类型变量中起作用的成员是最后一次存放的成员,
在存入一个新的成员后原有的成员就失去作用 。 如有
以下赋值语句:
a.i=1;
a.c=’a’;
a.f=1.5;
在完成以上三个赋值运算以后,a.f是有效的,a.i和 a.c已
经无意义了。
C++程序设计 湖南大学 杜四春、银红霞
共用体类型变量可以向另一个相同共用体类型的
变量赋值 。 此外, 共用体类型变量可以作为参数传递
给函数, 也可以使用地址传送方式把共用体类型变量
的地址作为参数在函数间传递 。
在程序中经常使用结构体与共用体相互嵌套的形
式 。 即共用体类型的成员可以是结构体类型, 或者结
构体类型的成员是共用体类型 。
C++程序设计 湖南大学 杜四春、银红霞
例如, 下列结构体类型 datas的第三个成员是共用体类型:
struct datas
{
char *ps;
int type;
union
{
float fdata;
int idata;
char cdata;
}udata;
};
C++程序设计 湖南大学 杜四春、银红霞