目录
2.计算下题pointer分配的空间大小?(包含位段成员的结构体大小)
1.如何计算结构体大小?
首先得掌握结构体的对齐规则:
1. 第一个成员在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小之间的较小值。
VS中默认的值为8
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
概念就这些,上题目
1.在32位系统环境,编译选项为4字节对齐。那么sizeof(A)和sizeof(B)分别为多少?(sizeof求所占空间的大小,单位字节)
#pragma pack(4)//设置默认对齐数为4
struct A
{
int a;
short b;
int c;
char d;
};
struct B
{
int a;
short b;
char c;
int d;
};
#pragma pack()//取消默认设置的对齐数
int main()
{
struct A a = { 0 };
struct B b = { 0 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(b));
}
struct A最大对齐数,及成员的对齐数
int a 大小为4个字节 == 默认对齐数为4 所以 对齐数为4
short b 大小2个字节 < 默认对齐数 对齐数为2
char c 大小1个字节 < 默认对齐数 对齐数为1
int d 大小4个字节 == 默认对齐数 对齐数为4
故最大对齐数:4
struct B 同理可得,不在赘述
图解
故sizeof(a)=16,sizeof(b)=12
2.计算下题pointer分配的空间大小?(包含位段成员的结构体大小)
#define MAX_SIZE 2+3
struct Test
{
unsigned char a : 4;
unsigned char b : 2;
unsigned char c;
unsigned char d : 1;
}*Record;
int main()
{
struct Test* pointer = (struct Test*)malloc(sizeof(struct Test) *MAX_SIZE);
//pointer分配的空间
printf("%d", sizeof(struct Test) *MAX_SIZE);
}
本题需要主要考察包含了位段成员的结构体大小计算及对宏的了解程度
位段成员包含char是按1个字节开辟内存的,第一个成员a开辟一个字节等于8个bit位,被a用去4个bit,还剩4个bit可以给b用去2个bit,故位段a,b共用一个字节
c不是位段重新开辟一个字节的内存,它直接占一个字节
位段d只占1个bit,但也要开辟1个字节的空间,故一起共开辟了3个字节的空间
sizeof(struct Test)*MAX_SIZE=3*2+3=9,pointer分配的空间为9个字节
3.下题输出结果是?
int main()
{
unsigned char puc[4];
struct tagPIM
{
unsigned char a;
unsigned char b : 1;
unsigned char c : 2;
unsigned char d : 3;
}*p;
p = (struct tagPIM*)puc;
memset(puc, 0, 4);//memset:内存函数
p->a = 2;
p->b = 3;
p->c = 4;
p->d = 5;
printf("%02x %02x %02x %02x \n", puc[0], puc[1], puc[2], puc[3]);
return 0;
}
图解
由上图可知最后输出 02 29 00 00
4.计算下面联合体所在内存的大小
union Un
{
short s[7];
int n;
};
int main()
{
printf("%d",sizeof(union Un));
}
联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。联合大小的计算
1.联合的大小至少是最大成员的大小。2.当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
short s[7] 所占大小为14个字节 一个short类型大小为2个字节<默认对齐数8 则对齐数为2
int n 占4个字节<默认对齐数8 对齐数为4
得最大对齐数为4
由联合体大小计算可知:该联合体大小为16
5.下面输出结果为?
int main()
{
union
{
short k;
char i[2];
}*s,a;//a为联合体变量
s = &a;
s->i[0] = 0x39;
s->i[1] = 0x38;
printf("%x\n",a.k);
}
图解
7.下面输出结果为?
typedef struct{//typedef对类型重定义
int a;
char b;
short c;
short d;
}AA_t;//AA_t为重定义的结构体类型
int main()
{
printf("%d\n",sizeof(AA_t));
return 0;
}
如果你看了前面的题目这道题完全可以心算
int a 占0-3偏移
char b 4偏移处
5偏移处浪费掉
short c 6-7偏移
short d 8-9偏移
总共占了10个字节 0-9偏移
由于最大对齐数为4,结构体大小为最大对齐数的整数倍
故结构体大小sizeof(AA_t)=12
6.下面输出结果为?(枚举)
enum A
{
X1,
Y1,
Z1=255,
A1,
B1,
};
int main()
{
enum A a = Y1;
enum A b = B1;
printf("%d %d\n", a, b);
}
要知道上题答案,须知枚举类型定义
{}中的内容是枚举类型的可能取值,也叫枚举常量。
这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。
简单来说如果都没赋初值值从0开始,依次递增1
如果部分赋了初值,后面一位的值为赋了值得那一位的值加1
以上题为例:
X1没赋初值 默认为0
Y1 X1+1=1
Z1赋了初值255
A1 Z1+1=256
B1 A1+1=257
所以输出:1 257