结构体:
结构体的引出是相对于数组而言的,数组要求数组中的各个元素属于同一个类型,那么有这些还不够,有时候还需要将不同类型的数据组合成一个有机的整体,以便于引用。于是C语言允许用户指定这样一种数据结构,它称之为结构体。
关于结构体的问题,做如下说明:
声明一个结构体类型:
struct student{
int num;
char name[20];
char sex;
}studeng1,student2;
上面的student就是结构体名,括号内的就是该结构体的各个成员,这样就构成了一个结构体。这只是一个结构体的类型。他是一个类型而不是一个变量,对于student而言,其中并无具体数据,系统对之也不分配实际的内存单元。
那怎么使用结构体类型的数据?
那就应该定义结构体类型的变量,并在其中存放具体的数据。其中student1和student2 就是结构体类型的变量。
而其中的num,name等都是结构体成员。特别地:结构体成员还可以是结构体。
1:结构体的引用
原型:结构体变量名.成员名 (student1.num)
问题1:如果一个结构成员还是一个结构体该如何引用?
分析:
struct date //声明一个结构体类型
{int month;
int day;
int year;
};
struct student
{int name;
char name[20];
char sex;
struct date birthday; //birthday是struct date类型
}student1,student2;
如果我想知道student1的出生的日数,可以这么访问:student1.birthday.day
结构体变量名与数组一样代表着结构体的首地址,可以引用结构体变量成员的地址,也可以引用结构体变量的地址。
如下:
scanf(“%d”,&student1.num);//输入student1.num的值
printf(“%o”,&student1); //输出student1的首地址
2:结构体数组
一个结构体变量中可以存放一组数据,如果有10个学生的数据需要参加运算,显然应该用数组,这就是结构体数组。
struct student{
int num;
:
:
:
}stu[3];
3:指向结构体变量的指针
一个结构体变量的指针就是该变量所占据的内存地址的起始地址。
可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值就是结构体变量的起始地址。
指针变量也可以用来指向结构体数组中的元素。
(关于结构体与指针之间的处理关系,在之后的章节中会专门讨论)
共用体
使几个不同的变量占用同一段内存的结构,称为“共用体”类型的结构。它们从同一地址开始存放,也就是使用覆盖技术,几个变量之间相互覆盖。
union data
{int i;
char ch;
float f;
}a,b,c;
1:共用体变量的引用
只有先定义了共用体变量才能引用它,而且不能引用共用体变量,而只能引用共用体变量的成员
只有如下:a.i,a.ch等
2:共用体的特点
(1)同一个内存的可以用来存放几种不同类型的成员,但在每一个瞬间只能存放其中一种,而不是同时存放几种。也就是说每一个瞬间只有一个成员起作用,其他的成员不起作用。
(2)共用体变量中起作用的是最后一次存放的成员,在存入一个新成员后原有的成员就失去作用
(3)共用体变量的地址和它各个成员的地址都是同一地址。
(4)不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,又不能在定义共用体变量时对其初始化
(5)不能把共用体作为函数参数,也不能使函数带回共用体变量,但可以使用指针共用体变量的指针
(6)共用体类型可以出现在结构体类型定义中,也可以定义共用体数组,反之亦可。
经典例题:
设有以下说明和定义:
typedef union
{
long i;
int k[5];
char c;
} DATE;
struct data
{
int cat;
DATE cow;
double dog;
} too;
DATE max;
则:
printf("%d",sizeof(struct data)+sizeof(max));
的执行结果是:
分析:max是一个共用体类型的变量,一个共用体类型的变量的长度为其成员的最长长度:int k[5],即:5*4=20;
data是一个结构体类型的变量,一个结构体类型的变量长度为其各个成员长度之和:int cat,即:4
double dog的长度为:8
cow又是一个共用体类型的长度,所以为20
总和长度就为:52