C与指针-第十章-结构体\联合union

在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问。

含义:

结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,叫做结构。

定义与声明:

结构体的定义如下所示,struct为结构体关键字,tag为结构体的标志,member-list为结构体成员列表,其必须列出其所有成员;variable-list为此结构体声明的变量。

struct tag {
member-list
} variable-list ;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c
//同时又声明了结构体变量s1
//这个结构体并没有标明其标签
struct {
int a;
char b;
double c;
}s1;

struct {
int a;
char b;
double c;
}s2;
注:s1和s2被编译器当做两种截然不同的类型,即使他们成员列表相同。
1
2
3
4
5
6
7
8
9
10
11
//同上声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c
//结构体的标签被命名为SIMPLE,没有声明变量
struct SIMPLE{
int a;
char b;
double c;
};
用标签来创建变量:
struct SIMPLE x;
struct SIMPLE y[20];
这里x和y是两个完全相同的类型,因为他们用标签来进行定义

typedef:

声明结构体时可以使用的另一种良好技巧是用typedef创建一种新的类型。

typedef struct{
int a;
char b;
double c;
}s3;

这个技巧和标签的效果几乎完全相同,区别在于s3现在是个类型名而不是个结构标签。以后的声明如下:

s3 x;
s3 y[20];

结构成员:

结构体的成员可以是标量、数组、指针甚至是其他结构体。

typedef struct{
int a;
char b;
double c:
s3 d;
s3 e[10];
}s4;

1)直接访问

结构体成员通过’.’操作符来访问的。
例:
s4 comp;

访问成员a, comp.a;
访问成员d中的a, comp.d.a;
访问成员e中第5个元素的成员a,comp.e[4].a;

2)间接访问

如果拥有一个指向结构体的指针,那么我们访问结构体成员需要用’->’操作符来访问。
s4 *comp;

访问成员a, comp->a;
访问成员d中的a, comp->d.a;
访问成员e中第5个元素的成员a,comp->e[4].a;

联合:

含义:

“联合”是一种特殊的类,也是一种构造类型的数据结构。在一个“联合”内可以定义多种不同的数据类型, 一个被说明为该“联合”类型的变量中,允许装入该“联合”所定义的任何一种数据,这些数据共享同一段内存,以达到节省空间的目的。 这是一个非常特殊的地方,也是联合的特征。另外,同struct一样,联合默认访问权限也是公有的,并且,也具有成员函数。

联合使用关键字union来定义。

声明:

联合声明跟结构体类似。
union {
数据成员;
}变量;

union{
int a;
float b;
}message;

在一个32位的机器上,变量message只占用内存中最大的变量类型的大小,这里int跟float占用内存相同,因此变量message这里只占用内存中一个32位的字。
如果a被访问,这个字就作为int型访问;
如果b被访问,这个字就作为float型访问。

1
2
3
4
message.b = 3.14;
message.a = 10;
printf(“%d\n”,message.a);
printf(“%f\n”,message.b);

由于最后一个访问的是a,因此a打印的值为10,b的值为0.000000;反之相同

union和结构体:

通常我们把union和struct结合起来使用,这样更加方便我们的程序开发。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
typedef struct{
int age;
int height;
}class;

typedef struct{
int year;
char class_name[10];
enum {class1,class2} type;
union{
class first_student;
class second_student;
}data;
}message;

int main(void)
{
message msg;
int y;
int z;
/*msg相关变量赋值*/
msg.data.first_student.age = 10;
msg.data.first_student.height = 170;
msg.type = class1;

if(msg.type == class1)
{
/*union一次只能访问一个成员*/
y = msg.data.first_student.age;
z = msg.data.first_student.height;
}
else
{
y = msg.data.second_student.age;
z = msg.data.second_student.height;
}
printf("%d\n",y); //打印10
printf("%d\n",z); //打印170
return 0;
}

总结:

1.结构体中,不同类型的值可以存储在一起,成员可以是标量、数组、指针或结构体
2.不同的二结构体声明即使它们的成员列表相同也被认为是不同的类型,typedef可以用于解决此问题
3.联合的所有成员都存储于同一个内存位置,通过访问不同类型的联合成员,内存中相同的位组合可以被解释为不同的东西。

Tianger Ge wechat
如果您喜欢这篇文章,欢迎扫一扫我的微信公众号!