C 语言中的结构体和共用体(联合体)

在 C 语言中, 结构体(struct) 是一个或多个变量的集合,这些变量可能为不同的类型,为了处理的方便而将这些变量组织在一个名字之下。由于结构体将一组相关变量看作一个单元而不是各自独立的实体,因此结构体有助于组织复杂的数据,特别是在大型的程序中。

共用体(union),也称为 联合体 ,是用于(在不同时刻)保存不同类型和长度的变量,它提供了一种方式,以在单块存储区中管理不同类型的数据。

今天,我们来介绍一下 C 语言中结构体和共用体的相关概念和使用。

结构体/struct 结构体的定义

声明一个结构体类型的一般形式为:

struct 结构体名 { 成员列表 };

其中,成员列表中对各成员都应进行类型声明,即:

类型名 成员名;

例如,我们需要在程序中记录一个学生(student)的数据,包括学号(num)、姓名(name)、性别(sex)、年龄(age)、成绩(score)、地址(addr)等,如下图所示:

C 语言中的结构体和共用体(联合体)

如果要表示图中的数据结构,但 C 语言并没有提供这种现成的数据类型,因此我们需要用定义一种结构体类型来表示。

struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; };

上述定义了一个新的结构体类型 struct student (注意, struct 是声明结构体类型时所必须使用的关键及,不能省略),它向编译系统声明,这是一个“结构体类型”,它包括 num 、 name 、 sex 、 age 、 score 、 addr 等不同类型的数据项。

应当说,这里的 struct student 是一个类型名,它与系统提供的标准类型(如 int 、 char 、 float 、 double 等)具有同样的作用,都可以用来定义变量的类型。

结构体变量

前面只是声明了一个结构体类型,它相当于一个模型,但其中并无具体的数据,编译系统对其也不分配实际的内存单元。为了能在程序中使用结构体类型的数据,我们应当定义结构体类型的变量,并在其中存放具体的数据。主要以下 3 中方式定义结构体类型变量:

先声明结构体类型,再定义变量名

结构体类型名 结构体变量名;

例如上面我们已经定义了一个结构体类型 struct student ,就可以用它来声明变量:

struct student student1, student2;

定义了 student1 和 student2 为 struct student 类型的变量,它们具有 struct student 类型的结构,后续我们可以对它们进行初始化。

在声明类型的同时定义变量

例如:

struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; } student1, student2;

它的作用与第一种方法相同,即定义了两个 struct student 类型的变量 student1 、 student2 。这种形式的定义的一般形式为:

struct 结构体名 { 成员列表 } 变量名列表;

直接定义结构体类型变量

其省略了结构体名,一般形式为:

struct { 成员列表 } 变量名列表;

关于结构体类型,需要补充说明一点:

类型与变量是不同的概念,不要混淆。我们只能对变量赋值、存取或运算,而不能对一个类型进行赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。

简单地说,我们可以 把“结构体类型”和“结构体变量”理解为是面向对象语言中“类”和“对象”的概念

此外,结构体里的成员也可以是一个结构体变量。比如我们先声明了一个结构体 struct date :

struct date { int month; int day; int year; };

然后把它应用于声明 struct student 中:

struct student { int num; char name[20]; char sex; int age; float score; struct date birthday; char addr[30]; } student1, student2;

最后,解释一个在阅读大型开源代码(比如 Objective-C Runtime 源码)时容易产生疑问的点:如下两个结构体 SampleA 和 SampleB 声明的变量在内存上其实是完全一样的,原因是因为结构体本身并不带有任何额外的附加信息:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/787cb2c1eb540d305fa0626d1c6fe582.html