c语言的结构体、共用体、枚举

版权声明:转载需注明出处,若有不足,欢迎指正。 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类型的值罢了,之所以用符号代替,只是为了让人理解起来方便一些

猜你喜欢

转载自blog.csdn.net/qq_28992301/article/details/53310899