结构体,枚举,联合

一、结构体:

1.结果体是一些值的集合,这些值称为成员变量。结果的每个成员可以是不同类型的变量,可以是数组,指针,甚至其他结构体

2.结构体的声明:

struct Stu

{

     char name[20];

     int age;

     char sex[5];

};

3.特殊的声明:不完全声明

struct

{

      int a;

      char b;

      float c;

}x;

//省略结构体名称,直接定义结构体变量

struct

{

        int a;

        char b;

        float c;

}*p,arr[20];

//省略了结构体名称,直接定义结构体指针,结构体数组

//p = &x ; 是否合法?

警告:编译器会把上面的俩个声明当成完全不同的俩个类型,所以这样的赋值不合法

4.结构体成员的访问

  • 结构体变量的成员是通过点操作符(.)来访问的
  • 结果体指针的成员是通过->来访问的

5.结构体的内存对齐

  • 内存对其的原则:

1.第一个成员在与结构体便宜了为0的地址处

2.其他成员变量要对其到对其数的整数倍的地址处

对齐数 = min(编译器默认的对其数,该成员的大小)

vs默认的值:8

Linux默认的值:4

3.结构体的总大小为最大对齐数的整数倍

最大对齐数:几个对齐数中最大的

4.如果有嵌套结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍

  • 为什么存在内存对齐?

1.平台原因

并不是所有的硬件都能任意的访问任意地址上的任意数据,编制并不是对所有的内存进行编制,所以有些内存不能访问

2.性能原因:

数据结构一个尽可能地在自然边界上对齐

如果访问未对齐的的内存,处理器需要做俩次内存访问,而对齐的内存访问仅仅需要一次

结构体的内存对齐是一种以空间换时间的做法。

#program pack(4)//设置默认对齐数是4

6.sizeof求空结构体大小

Linux:sizeof(struct)//0;

Windows://报错,1个结构体/联合中至少有一个变量

所以结构体定义时,不能为空

7.结构体传参:

数组名作为形参传参时会发生降级

但是如果结构体内含有数组,以结构体变量作为形参传参时,结构体内数组不会发生降级,会直接将整个数组直接拷贝形成一个临时变量(耗时,耗空间),所以在使用结构体传参时,要传结构体的地址

二、位段

位端的声明与结构体类似,有俩个不同

  • 位段的成员必须是int ,unsigned int 或 signed int或char(char也属于整形家族)。
  • 位段的成员名后边有一个冒号和一个数字

 

struct A

{

int _a:2;

int_b:5;

int _c:10;

int _d:30;

};

位段的内存分配:

  • 位段的成员都是整形家族
  • 位段的空间是按照需要以4字节(int)或者1个字节(char)的方式来开辟的
  • 位段涉及很多不确定因素,位段是不跨平台的,注重可一直的程序应该避免使用文段

位段跟结构体相比,位段可以达到相同的效果,但是可以很好的节省空间,但是有跨平台的问题存在

三、枚举

枚举顾名思义就是一一列举

{}中的内容是枚举类型的可能取值,这些值默认从0开始,依次递增,当然在定义的时候也可以赋初值

枚举的优点:

  1. 增加代码的可读性和可维护性
  2. 和#define定义的标识符比较枚举有类型检查,更加严谨
  3. 防止了命名污染(封装)
  4. 便于调试
  5. 使用方便,一次可以定义多个常量

四、联合

联合也是一种特殊的自定义类型,特征是这些成员共用一块空间(所以联合也叫共用体)

union Un

{

        char c;

        int i;

};

printf("%d\n",sizeof(un));//输出4

 

联合的特点:

  • 联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成原的大小(因为他要有能力保存最大的那个成员)
  • 对联合的每个成员取地址,是同一个地址

联合的大小:

  • 联合的大小至少是最大成员的大小
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值