联合体也叫共用体,由不同的数据类型组成,其变量互斥,存储方式是所有成员共用一个段内存,共同体同一时刻只能保存一个成员的值,如果对新的成员赋值,就会将原来成员的值覆盖掉。
union中,分配内容空间大小,等于占用内存最大的数据类型字节大小// 联合体的定义
union Teacher {char *name; // 8int age; // 4double height; // 8
};
int main(int argc, const char * argv[]) {@autoreleasepool {// 联合体union Teacher teacher;teacher.name = "AngaoTu";teacher.age = 18;teacher.height = 175.0;NSLog(@"联合体大小 size = %lu", sizeof(teacher));}return 0;
}
打印结果:2022-07-30 15:38:42.149406+0800 联合体+位域[9304:21445471] 联合体大小 size = 8
可证明联合体的大小,是由占用内存最大的数据类型字节大小决定
int main(int argc, const char * argv[]) {@autoreleasepool {// 联合体union Teacher teacher;teacher.name = "AngaoTu";teacher.age = 18;teacher.height = 175.0;NSLog(@"name 地址 = %p, age 地址 = %p, height 地址 = %p", &teacher.name, &teacher.age, &teacher.height);}return 0;
}
打印结果:2022-07-30 15:43:05.950276+0800 联合体+位域[10267:21450499] name 地址 = 0x7ffeefbff398, age 地址 = 0x7ffeefbff398, height 地址 = 0x7ffeefbff398
可验证联合体中成员变量使用同一个地址
int main(int argc, const char * argv[]) {@autoreleasepool {// 联合体union Teacher teacher;teacher.name = "AngaoTu";teacher.age = 18;teacher.height = 175.0;}return 0;
}
打印结果:
- (Teacher) teacher = (name = “AngaoTu”, age = 16176, height = 2.1220037829711594E-314)
- (Teacher) teacher = (name = “”, age = 18, height = 2.1219957998584539E-314)
- (Teacher) teacher = (name = “”, age = 0, height = 175)
可验证成员变量的赋值操作,其他成员变量原有数据将成为脏数据,不可用
有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。 例如在存放一个开关量时,只有 0 和 1 两种状态,用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。
sturct 位域结构名 {位域列表 // 格式: [类型 位域名:位域长度]
};struct bits {int a: 8;int b: 2;int c: 6;
}
struct bits {char a:2;
};
// size = 1 struct bits {char a:2; char b:2;
};
// size = 1 struct bits {char a:2; char b:2;char c:4; char d:4;
};
// size = 2struct bits {int a:4;
};
// size = 4 struct bits {int a:4;int b:4;
};
// size = 4struct bits {char a:8; char b:8; char c:8; char d:8; int e:4;
};
// size = 8
sizeof 大小,那么后面的成员紧邻前一个成员存储,直到不能容纳为止;如果它们的位宽之和大于类型的 sizeof 大小,那么后面的成员将从新的存储单元开始,其偏移量为类型大小的整数倍。把联合体和位域结合起来的数据类型,称为联合体位域
union isa_t {uintptr_t bits;
#if defined(ISA_BITFIELD)struct {ISA_BITFIELD; // defined in isa.h};Class cls;
};
isa_t是一个共用体,所以bits和cls共用一块内存空间。bits是一个位域,里面根据不同位定义了数据,节省空间。