1.定义
联合(union):联合(共同体)是一种特殊的数据类型,它允许您在相同的内存位置存储不同数据类型的数据(但不同时),这样可以定义一个带有多成员的共用体,通过不同成员访问不同的存储空间。
结构体(struct):用户自定义的可用的数据类型,允许存储不同类型的数据,结构体里的成员按定义先后顺序存放。
2.联合(union)
基本格式:
union
{
unsigned char var1;
unsigned short var2;
unsigned int var3;
};
存储:联合所占的内存大小为空间内最大内存成员的内存大小;联合内的成员占用同一个内存空间
上述的union中,var1 为char类型,其所占1B内存;var2为short类型,占2B;var3为int类型占4B;由此可见,在这个联合中,最大内存成员是var3,所以这个联合所占内存空间与var3所占内存一样,是为4B
例子:
#include <stdio.h>
int main(int argc, char **argv)
{
union
{
unsigned char var1;
unsigned short var2;
unsigned int var3;
}test;
printf("union size:%d\n", sizeof(test));
test.var3 = 0x12345678;
printf("var1:0x%02x\n", test.var1);
printf("var2:0x%04x\n", test.var2);
printf("var3:0x%03x\n", test.var3);
return 0;
}
Ps: 这里涉及到一个概念,小端字节序和大端字节序
小端字节序(LSB):高字节数据存放在高地址,低字节数据存放在低地址。
大端字节序(HSB):低字节数据存放在高地址,高字节数据存放在低地址。
应用:联合的同一内存空间存放不同成员这个特性,可以辅助验证大端字节序与小端字节序
例子:
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(int argc, char **argv)
{
union
{
unsigned char var1;
unsigned short var2;
unsigned int var3;
}test;
printf("union size:%d\n", sizeof(test));
test.var3 = 0x12345678;
//test.var2 = 0xAABB;
printf("var1:0x%02x\n", test.var1);
printf("var2:0x%04x\n", test.var2);
printf("var3:0x%03x\n", test.var3);
if(test.var1 == 0x78)
{
printf("LSB\n");
}
else if(test.var1 == 0x12)
{
printf("HSB\n");
}
else
{
printf("error:%s\n", strerror(errno));
return -1;
}
return 0;
}
3.结构体(struct)
结构体由基本数据类型构造处一种新的符合数据类型,空间内按照定义顺序存储,结构体相当于一个箱子
结构体不可以嵌套定义
基本结构:
Struct st_s
{
char a;
int b;
float c;
};
两种存储数据方法:(在此之前,不分配存储空间给成员)
Struct st_s stu = {“zhang”, male, 90};
Struct st_s stu = {.a=“zhang”, .b=male, .c=90};
内存空间: 开辟空间很大,足以单独存储所有成员所占空间
可与typedef结合使用,定义一种新的数据类型(不展开,之前有过typedef的题目总结)
Typedef struct st_s
{
...........
}st_t;
其中,struct st_s 等价于(==) st_t
CPU到内存中读取数据,32位机,就是有32根连线,SDRAM一次发送32bit(4B)的数据
一次发送4B,第一种存储正好一次取完所有数据,第二种就需要取两次,浪费了资源----------------------------------所以存储会保证数据的整数倍存储,保证数据的完整性
例子:
#include <stdio.h>
typedef struct a_s
{
int a;
short b;
char c;
}a_t;
typedef struct b_s
{
short b;
int a;
char c;
}b_t;
int main(int argc, char **argv)
{
printf("size a_t :%d\n", sizeof(a_t));
printf("size b_t :%d\n", sizeof(b_t));
return 0;
}
结构体对齐:
自身对齐值:每个成员自身大小
指定对齐值:由宏#pragma pack (N) 指定,N必须是2的幂次方,不指定的话,32位机默认4,64位默认8
有效对齐值:取每个成员【自身对齐值,指定对齐值】中的较小的一个
结构体和联合两者的区别总结:
结构体:各成员各自拥有自己的内存,各自使用互不干涉,同时存在的,遵循内存对齐原则。一个struct变量的总长度等于所有成员的长度之和。
联合(覆盖): 各成员共用一块内存空间,并且同时只有一个成员可以得到这块内存的使用权(对该内存的读写),各变量共用一个内存首地址。因而,联合体比结构体更节约内存。一个union变量的总长度至少能容纳最大的成员变量,而且要满足是所有成员变量类型大小的整数倍。