联合体
联合体(union)在C语言中是一个特殊的数据类型,能够存储不同类型的数据在同一个内存位置。可以定义一个联合体使用许多成员,但只有一个部件可以包含在任何时候给定的值。联合体会提供使用相同的存储器位置供多用途的有效方式。
typedef union data
{
short i;
char ch;
float f;
}DATA;
int main()
{
DATA temp2;
temp2.i = 100;
printf("%hd\n",temp2.i);
temp2.ch = 'a';
printf("%c\n",temp2.ch);
temp2.f = 2.5;
printf("%.1f\n",temp2.f);
printf("%d\n",sizeof(DATA));
return 0;
}
大小端序测试
#include<stdio.h>
#pragma pack()
typedef union data
{
int i;
char ch;
}DATA;
int main()
{
DATA temp;
temp.i = 0x12345678;
if(temp.ch == 0x12)
{
printf("大端序\n");
}
else
{
printf("小端序\n");
}
return 0;
}
结构体内存分配
原则一:结构体中元素按照定义顺序存放到内存中,但并不是紧密排列。从结构体存储的首地址开始 ,每一个元素存入内存中时,它都会认为内存是以自己的宽度来划分空间的,因此元素存放的位置一定会在自己大小的整数倍上开始。
原则二: 在原则一的基础上,检查计算出的存储单元是否为所有元素中最宽的元素长度的整数倍。若是,则结束;否则,将其补齐为它的整数倍。
struct stu
{
int id;//4
char name[20];//20
float score;//4
}stu1;
struct stu
{
int id;
char gender;
double score;
};
int main()
{
printf("%d\n",sizeof(struct stu));
// printf("%d\n",sizeof(stu1));
return 0;
}
枚举
枚举定义了一些符号,这些符号的本质就是int类型的常量,每个符号和一个常量绑定。这个符号就表示一个自定义的一个识别码,编译器对枚举的认知就是符号常量所绑定的那个int类型的数字。
一般情况下我们都不明确指定这个符号所对应的数字,而让编译器自动分配。
说一下宏定义与枚举的区别:
1、枚举是将多个有关联的符号封装在一个枚举中,而宏定义是完全散的。也就是说枚举其实是多选一,而且只能在这里面选,有时候有效防止其他不符数据的输入。
2、什么情况下用枚举?当我们要定义的常量是一个有限集合时(譬如一星期有7天,譬如一个月有31天,譬如一年有12个月····),最适合用枚举。(其实宏定义也行,但是枚举更好)
3、不适合用枚举的情况下(比如定义的常量符号之间无关联,或者无限的)用宏定义。
typedef enum week
{
mon=1,tus,wed,thu=6,fri,sat,sun
}WEEK;
int main()
{
enum week weekday;
WEEK workday;
workday = mon;
weekday = mon;
printf("%d\n",weekday);
printf("%d\n",workday);
weekday = tus;
workday = tus;
printf("%d\n",weekday);
printf("%d\n",workday);
weekday = thu;
workday = thu;
printf("%d\n",weekday);
printf("%d\n",workday);
return 0;
}
位段:
注意事项:
1、位段的内存分配2)位段占的二进制位数不能超过该基本类型所能表示的最大位数,即位段不能跨字节存储
1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型。
2. 位段的空间上是按照需要以 4 个字节( int )或者 1 个字节( char )的方式来开辟的。
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
//struct A
//{
// int a:2;//3
// int b:5;//11111 ->1F
// int c:10;// 11 1111 1111 ->3FF
// int d:30;
// };
typedef struct reg
{
int a:2;
int b:4;
int c:6;
int d:4;
}REG;
int main()
{
REG registe;
registe.a=3;//3
registe.b=10;//1010 ->1101 ->1110=-6
registe.c=20;//0001 0100 ->
registe.d=9;//1001 -> 1110 ->1111=-7
printf("%d %d %d %d\n",registe.a,registe.b,registe.c,registe.d);
printf("%d",sizeof(REG));
return 0;
}