前言
经常看到各种结构体的定义,项目中又该如何定义和使用结构体呢?
结构体
常见的结构体定义和使用
基本上见到的结构体定义就就这样四种
struct LQStructA {
bool a;
};
struct LQStructB {
bool a;
}structB;
typedef struct LQStructC {
bool a;
}LQStructC;
typedef struct {
bool a;
}LQStructD;
1.第一种见到的比较少,基本上自己不会用,但的确是定义结构体的一种方式,一般用在需要明确知道自己用的是结构体类型的数据,在C++的.h文件中见到的比较多,比如在scoket.h用的都是这种定义。
这种在自己使用的时候比较麻烦,无法像基础类型一样直接定义,需要带上关键字
struct才行,因为struct LQStructA才是一个类型。
struct LQStructA structA1;
structA1.a = YES;
struct LQStructA structA2;
structA2.a = NO;
2.第二种是定义了一个LQStructB类型,而且直接创建了一个结构体,可以直接使用这个结构体了,这中用法一般是用在就只需要创建一个结构体的时候。一般就是只操作structB就行。如果需要在后面还要创建LQStructB也可以创建,创建和第一种一样。
//一般操作这一个结构体就可
structB.a = YES;
structB.a = NO;
//也可以在创建
struct LQStructB structB2;
structB2.a = NO;
3.第三种和第四种的定义的所要效果是一样的,都是使用typedef创建别名,然后使用别名创建结构体。这两种在写的代码中都是比较常见的,区别是第三种可以使用struct+结构体名创建结构体,但是第四种只能根据别名创建结构体。两种的意思也不一样,第三种是将struct LQStructC定义为别名LQStructC,第四种是将一个匿名的结构体声明为LQStructD。
//LQStructC 可以使用别名也可以使用 'struct 结构体名'
LQStructC c1;
struct LQStructC c2;
c1.a = YES;
c2.a = NO;
//LQStructD 只能使用别名创建
LQStructD d1;
d1.a = NO;
总结:项目中基本上用第三种或者第四种就可以了。
结构体的继承
OC来源于C++,所以也有C++结构体特性,继承。在.m文件中是无法使用继承的,需要使用.mm文件才能使用结构体继承。
struct LQStructA {
int a;
};
struct LQStructB:LQStructA{
int b;
};
struct LQStructC:LQStructB{
int c;
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
struct LQStructC structC;
structC.a = 100;
structC.b = 200;
structC.c = 300;
NSLog(@"structC空间大小:%lu",sizeof(structC));
NSLog(@"structC地址:%p",&structC);
NSLog(@"end");
}
return 0;
}
结构体继承和C++几乎就是一模模一样样的,也有private和public等。继承后的结构体占用的内存包含了自己和父类的内存大小,排放是先父结构体,然后才是自己。这里用lldb也产看了一下存储结构。

位域
众所周知,一个字节有8位,有些信息在存储时,并不需要占用一个完整的字节,而只需占几位或一位。例如在存放一个只有0和1两种状态成员,用一位二进位即可,目的是节省存储空间。一般用在bool类型。
联合体
联合和结构体一样都可以定义多种数据类型,也可以嵌套使用,但是联合体内部成员是互斥的,用的是同一片内存空间,所需空间为最大变量所需空间,同一时间有效的只有一个变量。就像下面设置了sb后sa就无用了,联合体适用于二选一或多选情况下使用。