8.1 结构:结构类型的定义和访问、包含结构的结构
8.1.1 结构体类型的声明
struct 结构体名
{成员表列}
例如:
struct student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}
注意:
结构体类型的名字是由一个关键字 struct 和结构体名组合而成的(例如 struct Student)。结构体名是由用户指定的,又称 「结构体标记」(structure tag),以区别于其他结构体类型。上面的结构体声明中 Student 就是结构体名(结构体标记)。
花括号内是该结构体所包括的子项,称为结构体的成员(member)。上例中的 num,name,sex 等都是成员。对各成员都应进行类型声明,即:类型名 成员名;
「成员表列(member list)」也称为 "域表"(field list),每一个成员是结构体中的一个域。成员名命名规则与变量名相同。
8.1.2 结构体类型变量的定义
-
先声明结构体类型再定义变量名。
- 例如:
struct student student1, student2;
- 例如:
-
在声明类型的同时定义变量。
struct 结构体名 { 成员表列 } 变量名表列;
例如:
struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; } student1, student2;
-
直接定义结构体类型变量。
struct { 成员表列 } 变量名表列;
注意:
- 类型与变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。
- 对结构体中的成员(即"域"),可以单独使用,它的作用与地位相当于普通变量。
- 成员也可以是一个结构体变量。
- 成员名可以与程序中的变量名相同,二者不代表同一对象。
8.1.3 结构体变量的引用
引用结构体变量中成员的方式为:结构体变量名.成员名
。
例如,student1.num
表示 student1 变量中的 num 成员,即 student1 的 num(学号)项。
可以对变量的成员赋值,例如:student1.num = 10010;
。.
是成员(分量)运算符,它在所有的运算符中优先级最高,因此可以把 student1.num
作为一个整体来看待。上面赋值语句的作用是将整数 10010 赋给 student1 变量中的成员 num。
注意:
- 不能将一个结构体变量作为一个整体进行输入和输出。
例如: 已定义 student1 和 student2 为结构体变量并且它们已有值。
printf("%d,%s,%c,%d,%f\n", student1);
- 如果成员本身又属一个结构体类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取以及运算。
例如:对上面定义的结构体变量student1,可以这样访问各成员:
student1.num
、student1.birthday.month
- 对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)。
例如:
student2.score = student1.score;
、sum = student1.score + student2.score;
、student1.age++;
、++student2.age;
- 可以引用结构体变量成员的地址,也可以引用结构体变量的地址。
例如:
scanf("%d",&student1.num);
(输入 student1.num 的值)
printf(%o", &student1);
(输出 student1 的首地址)
- 但不能用以下语句整体读入结构体变量。
例如:
scanf("%d, %s, %c, %d, %f,%s", &student1);
8.2 联合:联合类型的定义和访问
8.2.1 共用体的定义
-
共用体:使几个不同的变量共占同一段内存的结构称为「共用体」类型的结构。
-
共用体的定义形式:
union 共用体名 { 成员表列 } 变量表列;
例如:
union data { int i; char ch; float f; } a,b,c; // 或 union data { int i; char ch; float f; }; union data a,b,c;
-
共用体和结构体的比较:
- 结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。
- 共用体变量所占的内存长度等于最长的成员的长度。
-
共用体变量的引用方式:只有先定义了共用体变量才能引用它,而且不能引用共用体变量,而只能引用共用体变量中的成员。
例如:前面定义了 a、b、c 为共用体变量。
a.i
(引用共用体变量中的整型变量 i)、a.ch
(引用共用体变量中的字符变量 ch)、a.f
(引用共用体变量中的实型变量 f) -
共用体类型数据的特点:
- 同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一种,而不是同时存放几种。
- 共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用。
- 共用体变量的地址和它的各成员的地址都是同一地址。
- 不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,又不能在定义共用体变量时对它初始化。
- 不能把共用体变量作为函数参数,也不能使函数带回共用体变量,但可以使用指向共用体变量的指针。
- 以前的 C 规定不能把共用体变量作为函数参数,但可以使用指向共用体变量的指针作函数参数。C99 允许用共用体变量作为函数参数。
- 共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。
8.3 类型定义语句(typedef)
可以用 typedef 声明新的类型名来代替已有的类型名。
-
声明 INTEGER 为整型:
typedef int INTEGER;
-
声明结构类型
typedef struct { int month; int day; int year; } DATE;
-
声明 NUM 为整型数组类型 :
typedef int NUM[100];
-
声明 STRING 为字符指针类型:
typedef char* STRING;
-
声明 POINTER 为指向函数的指针类型,该函数返回整型值:
typedef int (*POINTER)()
- 用 typedef 定义类型的方法:
- 先按定义变量的方法写出定义体(如:
int i
)。 - 将变量名换成新类型名(例如:将 i 换成 COUNT)。
- 在最前面加 typedef(例如:
typedef int COUNT
)。 - 然后可以用新类型名去定义变量。
- 先按定义变量的方法写出定义体(如:
注意:
用 typedef 可以声明各种类型名,但不能用来定义变量。
用 typedef 只是对已经存在的类型增加一个类型名,而没有创造新的类型。
当不同源文件中用到同一类型数据时,常用 typedef 声明一些数据类型,把它们单独放在一个文件
中,然后在需要用到它们的文件中用 #include 命令把它们包含进来。
使用 typedef 有利于程序的通用与移植。
typedef 与 #define 有相似之处,例如:
typedef int COUNT;
#define COUNT int
的作用都是用 COUNT 代表 int。但事实上,它们二者是不同的。
#define
是在预编译时处理的,它只能作简单的字符串替换,而 typedef 是在编译时处理的。实际上它并不是作简单的字符串替换,而是采用如同定义变量的方法那样来声明一个类型。
评论(没有评论)