1:结构体
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//系统默认对齐数为8,成员对齐数和默认对齐数,取较小值
//总的字节数必须为最大对齐数的整数倍
struct A
{
int a; // 对齐数为4(位置顺序必须为4的倍数才能放)
char b;//对齐数为1(位置顺序必须为1的倍数才能放)
int c;//c的位置本来应该是5,但5不是4的倍数,所以不行,必须放在第8位
};
int main()
{
struct A s = {4,'d',5};
printf("%d",sizeof(s));//所以打印出来的数值为12
return 0;
}
2:位段
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct A
{
int a:2;//这里的2,是规定a只能占2个BIT位
int b:3;//这里的3,是规定b只能占3个BIT位
int c:4;//这里的4,是规定c只能占4个BIT位
};
int main()
{
struct A s = {4,5,10};
printf("%d",sizeof(s));//32位系统,最小输出32位数据,4个字节
printf("%d",s);//所以最后结果为00000000000000000000101010100=340
return 0;
}
3:枚举
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum Stu
{
name = 1,
age,
num
};
int main()
{
enum Stu s = name;
printf("%d",sizeof(s));
printf("%d",s);
return 0;
}
枚举相当于定义了三个常量,但并没有定义其数据类型,s大小就是4个字节
如果前面name赋值1,那么age的值默认为2,num的值为3..如果name也没有赋值,那name的值默认为0,age为1,num为2
枚举定义的常量在用处和表达上和define定义的常量是差不多的,但是枚举定义有它的优势
在调试上,define定义的常量在预处理时就把代码里的常量全部替换为具体的值,不利于调试
define定义的常量并没有数据类型,在代码里容易出现重复定义,产生混淆
如果要定义的常量比较多,用define就显得不那么整洁了
4:联合体
字面意思,大家共享一块内存,成为一体
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
union Stu
{
int a ;
char b;
};
int main()
{
union Stu s;
printf("%p\n",&s);
printf("%p\n",&s.a);
printf("%p\n",&s.b);
return 0;
}
打印结果:
实事证明,联合体变量和它的成员的地址都是指向同一块内存,内存的大小最小应该为最大成员的大小
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
union Stu
{
int a ;
char b;
};
int main()
{
union Stu s;
s.a = 0x12325678;
printf("%x\n",s.b);
printf("%d\n",sizeof(s));//4个字节
return 0;
}
上面给a赋值ox12345678,在内存中的分布就是 78 56 34 12,因为它们地址都是指向同一处,所以s.b的值就是ox78,s.b并没有另外开辟内存,所以整个联合体的大小就是int a的大小,4个字节.