一、结构体
1.结构体的作用
在网络协议、通信控制、嵌入式系统的C/C++编程中,我们经常要传送的不是简单的字节流,而是多种数据组合起来的一个整体,其表现形式就是一个结构体。
2.结构体的定义
结构体:是指定义相应的数据结构及相应的变量。
结构体如下所示,
其中,struct是结构体关键字,一定不能省略。node是结构体名,可以省略,成为无名结构体。结构体成员可以使基本类型或者构造类型。
3.变量用 . 访问,指针用 -> 访问。eg. node.num = 1; node->name = "abc";
4.字对齐和半字对齐
我们通过一两个例子来进行分析
#include <stdio.h>
struct node
{
char a;
short b;
char c;
};
int main()
{
struct node Node;
printf("the size of node is %d\n", sizeof(Node));
return 0;
}
我们知道结构体分配的空间为所有成员分配的空间之和。如果按这种理解,那么分配的空间大小为 1 + 2 + 1 = 4。但是结果真的是这样吗?
[root@localhost 0814]# ./a.out
the size of node is 6
为什么结果和我们想象的不太一样呢?说明分配空间的时候并不是这样分配。
#include <stdio.h>
struct node
{
char a;
short b;
int c;
char d;
};
int main()
{
struct node Node;
printf("the size of node is %d\n", sizeof(Node));
return 0;
}
结果是什么呢?
[root@localhost 0814]# ./a.out
the size of node is 12
我猜测这里是 2 + 2 + 4 + 4 = 12。为什么会是这样的呢?这是内存对齐的结果。那什么是内存对齐呢?
从理论上讲,对于任何变量的访问都可以从任何地址开始访问,但事实上不是如此,实际上访问特定类型的变量只能在特定的地址访问,这就需要各个变量在空间上按一定的规则排列,而不是简单地顺序排列,这就是内存对齐。
在第一道例题中,
在计算机内存中,只有字对齐和半字对齐。1 字 = 2 个半字 = 4 个字节!(这里默认为32位机)。所以当出现short的时候,就会以半字进行对齐。当出现 int的时候就会以字进行对齐。
在第二道例题中,
这样的内存分配会使内存资源的使用上存在缺陷,那么我们将如何减少这种内存空洞呢?
5.内存空洞
将相同的数据类型放在一起可以减少内存空洞,使内存资源利用更有效。
二、共用体
1.特点
用覆盖技术,几个变量相互覆盖,从而使几个不同变量共占一段内存的结构。共用体的所有成员都在一段内存中存放,起始地址一样,并且同一时刻只能使用其中的一个成员变量。
2.定义
共用体如下所示,
其中union是共用体关键字,不能省略。node是共用体名。
3.共用内存空间
#include <stdio.h>
union node
{
int a;
char b;
};
int main()
{
union node Node;
Node.a = 1;
printf("b = %d\n", Node.b);
return 0;
}
对共用体中的a进行赋值,共用体中的b也可以使用。
[root@localhost 0814]# ./a.out
b = 1
4.大端字节序和小段字节序
5.利用共用体测试机器的大小端格式
#include <stdio.h>
union node
{
int a;
char b;
};
int main()
{
union node Node;
Node.a = 0x12345678;
printf("b = %x\n", Node.b);
return 0;
}
[root@localhost 0814]# ./a.out
b = 78
从这里可以看出,我测试的机器是小端字节序。