目录
位段的介绍
枚举的介绍与应用
联合体的大小计算
位段:与结构体相似,其关键字同样是struct!但是位段的成员它的类型必须是整数家族的类型!位段的声明如下:
struct S
{
char a : 1;
unsigned char a1 : 1;
int b : 2;
unsigned int b1 : 2;
long c : 3;
unsigned long c1 : 3;
long long d : 4;
unsigned long long int d1 : 4;
};
int main()
{
struct S s1 = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
return 0;
}
位段可以说是用来声明一个变量所要占用的bit位的数目;
同时:
观察监视结果可以发现位段是区分有符号与无符号的类型的!
思考:位段是如何去存储的呢?
struct S
{
char a : 3;
short b : 4;
long c : 5;
long long d : 8;
}*S1;
int main()
{
char arr[10] = { 0 };
S1= (struct S*)arr;
S1->a = 12;
S1->b = 20;
S1->c = 30;
S1->d = 0xff;
printf("%d", sizeof(struct S));
return 0;
}
讨论:位段的存储是否和结构体相似呢?
其实,位段和结构体的存储方式相似却又不完全相似;
struct S
{
char a : 3;
int b : 16;
long c : 17;
long long d : 8;
}*S1;
int main()
{
char arr[100] = { 0 };
S1= (struct S*)arr;
S1->a = 12;
S1->b = 20;
S1->c = 30;
S1->d = 0xff;
return 0;
}
位段也要遵循对齐,但是当相邻成员的类型相同时,如果它们的位宽之和小于类型的 sizeof 大小,那么后面的成员紧邻前一个成员存储,直到不能容纳为止;如果它们的位宽之和大于类型的 sizeof 大小,那么后面的成员将从新的存储单元开始,其偏移量为类型大小的整数倍。(注意,是相邻的类型相同!)
枚举:
enum Sex
{
//枚举的可能取值,默认是从0开始,递增1的
//枚举常量
MALE,
FEMALE,
SECRET,
NO = 100,
YES
};
int main()
{
enum Sex s = FEMALE;
printf("%d\n", MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
printf("%d\n", NO);
printf("%d", YES);
return 0;
}
可以看出枚举是按照前一个加1,而默认第一个枚举常量为0!
联合体:联合体的关键字是union!
观察可以得知:这个联合体的大小是4,而变量c和i都是存储在相同的位置!因此,修改c的同时,也修改了i;
因此可以基本得出联合体的存储为 :
联合体的计算大小规定为:1.联合体的大小至少为最大成员的大小,以上可以体现!
2.当最大成员的大小不是最大对齐数的整数倍时,就要对齐到最大对齐数整数倍!
union UN
{
short i[7];
int c;
};
int main()
{
printf("%d", sizeof(union UN));//结果为16
return 0;
}
可以知道,这个联合体实际使用的字节数为14个,但是,最大对齐数时4,因此要进2达到16为最大对齐数整数倍!