结构体
结构体是把不同类型的数据组合成一个整体,其元素是共存的,元素是否使用都会分配内存。
优点 : 元素之间存储互不影响,容量大,“有容乃大”。
缺点 : 结构体的内存 >= 所有元素所占内存之和,比较浪费内存。
举个例子:
struct LGStruct1 {
double a;
char b;
int c;
short d;
}struct1;
struct LGStruct2 {
double a;
int b;
char c;
short d;
}struct2;
结构体大家都熟悉,但是结构体大小怎么计算未必都清楚,现提供提供计算秘诀
1:数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第
⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要
从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,
结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存
储。 min(当前开始的位置m n) m = 9 n = 4 9 10 11 12
2:结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从
其内部最⼤元素⼤⼩的整数倍地址开始存储.(struct a⾥存有struct b,b
⾥有char,int ,double等元素,那b应该从8的整数倍开始存储.)
3:收尾⼯作:结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤
成员的整数倍.不⾜的要补⻬。
跟着这个公式我们来计算下大小
struct LGStruct1 { 字节数 存储位置
double a; // 8 [0, 7]
char b; // 1 [8]
int c; // 4 9,10,11,[12,13,14,15]
short d; // 2 [16, 17]
}struct1;
分析:
a 占8个字节,从0 开始,a占的位置就是0-7;
b 占1个字节,根据公式1,8是1的整数倍,所以8这个位置可以存放,
c 占4个字节,根据公式1,9不是4的整数倍,所以往后排,10,11 都不是,12是4的整数倍,所以从12开始,12,13,14,15
d 占2个字节,工具公式1,16是2的整数倍,所以从16开始,16,17
根据公式3,struct1中最大的是a,17不是8的整数倍,要往后补齐,到24的时候是8的整数倍,所以struct1 的大小是24;
接下来我们打印验证
打印的结果和我们计算的完全一样。用同样的方法计算下一个
struct LGStruct2 {
double a; // 8 [0 7]
int b; // 4 [8 9 10 11]
char c; // 1 [12]
short d; // 2 (13 [14 15]
}struct2;
大小为16
可以看出struct1和struct2中元素一样,只是位置不同则结构体的大小不一样。
接下来我们来看看联合体
double a; // 8 [0,7]
int b; // 4 [8,9,10,11]
char c; // 1 [12]
short d; // 2 13, [14,15]
int e; // 4 [16,17,18,19]
struct LGStruct1 str; // 24 20,21,22,23,[24,47]
}struct3;
a,b,c,d,e 的计算相比大家都会算了,str结构体大小为24,根据公式3中结构体套结构体,必须是其内部最⼤成员的整数倍,str中最大的是8,整数倍就是24开始。最后struct3的大小是48.
联合体
联合体又名共用体是把不同类型的数据组合成一个整体,其元素是互斥的,所有元素共占一段内存,只能又一个元素有值;如果对新元素赋值,则会将原来的元素值覆盖掉。
优点 : 所有元素共占同一片内存,所以节约内存,存储效率高,灵活.
缺点 : 所有元素都是互斥的,包容性差
创建一个联合体
union HHDemo {
int a;
double b;
char c;
}demo;
联合体赋值
NSLog(@"大小 -- %lu",sizeof(demo));
demo.a = 10;
NSLog(@"a = %d - %f - %c",demo.a,demo.b,demo.c);
demo.b = 20.0;
NSLog(@"b = %d - %f - %c",demo.a,demo.b,demo.c);
demo.c = 'A';
NSLog(@"c = %d - %f - %c",demo.a,demo.b,demo.c);
打印结果
2021-10-28 23:23:42.578151+0800 003-联合体位域[22215:413826] 大小 -- 8
2021-10-28 23:23:42.578898+0800 003-联合体位域[22215:413826] a = 10 - 0.000000 - - 0.000000
2021-10-28 23:23:42.578986+0800 003-联合体位域[22215:413826] b = 0 - 30.000000 -
2021-10-28 23:23:42.579041+0800 003-联合体位域[22215:413826] c = 65 - 30.000000 - A - 0.000000
2021-10-28 23:23:42.579088+0800 003-联合体位域[22215:413826] d = 1112014848 - 30.000004 - - 50.000000
通过打印的结果好像元素之间并不是互斥的,给d赋值后,a,b 也有值,但是是错误的值,这是因为系统给的脏数据;