版权声明:转载需注明出处,若有不足,欢迎指正。 https://blog.csdn.net/qq_28992301/article/details/53310899
1.结构体
- 现在有一个结构体var,以他为例进行分析
struct s
{
char a;
int b;
}var;
- var是struct s类型的变量,其值为0。结构体名和数组名不同,它代表的是整个结构体变量,而不是一个地址,所以它的值是没有意义的
- &var是struct s *类型的变量,其值为结构体第一个元素的地址(&(var.a))。它代表的是整个结构体的起始地址
- 结构体元素按照一定规律对齐,要保证提取数据的高效,同时保证节省体积。对于32位linux来说,规律为:各个类型存储时的起始地址,需是特定字节数整数倍;此外,还需保证结构体本身的开头和结尾地址都是4字节对齐的
- 以下是结构体元素对齐实例
struct s
{
char a; //存放起始地址是1字节的整数倍
short b; //存放起始地址是2字节的整数倍
int c; //存放起始地址是4字节的整数倍
}var1; //结构体本身的开头和结尾地址都是4字节的整数倍
struct s
{
char a; //存放起始地址是1字节的整数倍
int c; //存放起始地址是4字节的整数倍
short b; //存放起始地址是2字节的整数倍
}var2; //结构体本身的开头和结尾地址都是4字节的整数倍
struct s
{
char a; //存放起始地址是1字节的整数倍
struct var2;//存放起始地址是4字节的整数倍
short b; //存放起始地址是2字节的整数倍
}var3; //结构体本身的开头和结尾地址都是4字节的整数倍
由此可见,元素的安放顺序非常讲究
- offsetof宏:用来计算某元素相对于结构体首地址的偏移量。原型为
offsetof(type, member) //type是结构体类型,member是具体的元素名
- container_of宏:用来计算包含了某元素的结构体的地址。这个宏是基于offsetof宏实现的,其原型为
container_of(ptr, type, member) //ptr是某元素的地址,type是含了该元素的结构体类型,member是该元素的名字
2.共用体
- 共用体用起来和结构体很相似,现在有一个共用体var,以他为例进行分析
union s
{
char a;
int b;
}var;
var.a = 23; //赋值方法和结构体一模一样
- sizeof对共用体变量测得的大小,是共用体中占用内存最大的那个变量的大小
3.枚举
- 枚举也是c语言的一种数据类型,和结构体、共用体是一伙的,用法如下
enum return_value
{
ERROR;
RIGHT;
}; //定义一个共用体类型return_value
enum return_value ret; //定义一个return_value类型的变量ret
ret = ERROR; //把ERROR赋值给ret
- 枚举类型的变量其实就是规定了一个变量,它能有几种值,并且这些值都由符号代替。ERROR、RIGHT这些符号的本质,其实就是int类型的值罢了,之所以用符号代替,只是为了让人理解起来方便一些