自定义类型:位段/枚举/联合

位段

位段的介绍

位段与结构体很类似,只有些许不同。

struct A
{
    int a:1;
    int b:5;
    int c:10;
};

从形式上看,位段和结构体大体相同

a,b,c是位段的成员

位段的成员类型只能是signed int ,unsigned int, int,char,整型类型(char是特殊的整型类型)

每个成员名后面有一个":"和数字。

数字代表这个成员占几个二进制位(bit).

1字节=8bit.

int类型在结构体里开辟的空间有32bit,但是有些数字根本用不了那么大的空间,而位段里面就可以手动限制所开辟空间的大小。在已知成员占用不大时,就能用位段进行限制。

位段的内存分配

位段不像结构体,不用对齐。

位段按照需要,以int(4字节),char(1字节)进行开辟空间,然后依次放入成员(成员大小是自己限制的),不够了再按需求,开辟int(4字节),char(1字节)大小的空间。

在VS环境下

struct A
{
    char a:3;
    char b:4;
    char c:5;
    char d:4;
};

int main()
{
    struct A X={10,12,3,4};
    return 0;
}

位段的跨平台问题

1.int位段被当成有符号数还是无符号数是不确定的。

2.位段中最大位的数目不能确定(在32位机器上,限制位可以写27位,但是在16位机器上就会错

3.位段中的成员在内存中从左往右分配,还是从右往左分配的标准尚未定义,所以上述的例子只能在vs环境下才能100%生效。、

4.当开辟的一个空间位置不够,要开辟下一个空间时,上一个空间剩下的位置是舍弃还是利用是不确定的,像这里vs环境下是舍弃。

综上所述,位段能和结构体达到相同的效果,而且能更加节省空间,但是不好跨平台。

枚举

枚举就是把可能的值一一列举,它的作用是定义常量

枚举类型的定义

enum Sex
{
    male,
    female,
    secret
};

male,female.secret是枚举常量,是常量,拥有常量的所有性质

!注意!最后一个枚举常量后面是没有","的。

可以写成

enum Sex
{
    male=1,//注意这里
    female,
    secret
};

int main()
{
    enum Sex a = male;
}

能在定义枚举类型时,就给与这些枚举常量一个值(虽然常量的规则时不能被赋值,但是这里时给常量最开始的值)。

emun Sex a = male;等价于int a = 1;

一样的效果,都是初始化a。

如果定义了male = 1,后面的female和secret就会自动依次递增,female = 2  ,secret = 3.

如果既没有被定义,上面也没有别的以及定义的枚举变量,那这个枚举变量就是默认值=0.

枚举的优点

之前了解到,#define 也能用来定义常量 ,枚举相比之下有些优点

1.可以增加代码的可维护性和可读性。

比如分支功能switch case,一般使用case1....case2...这样写,现在可以用枚举定义case1对应的操作的名字为常量1,假设操作时开始游戏,就可以定义常量start为1,然后就可以改成  case 1----->case start,这样分支作用就一目了然了。

2.相比于#define,枚举常量是有类型的,有类型检

查,#define的本质是替换,枚举更加严谨

3.便于调试,枚举是能调试的,能看到定义常量的过程。

4.防止命名污染

5.使用更加方便,能一次性定义多个常量。

联合(共用体)

联合也是一种特殊的自定义类型

这种类型定义的变量也包含一系列成员,特征是这些成员公用同一块空间(所以联合体也叫共用体

联合的类型定义

union UN
{
    char c;
    int i;
};

int main()
{
    union UN X;
    return 0;
}

联合体特点

两个成员共用空间,蓝色部分即时c的空间,又是c与i重叠的空间。

所以量成员不能同时使用,因为在使用一个的时候,必定会影响另外一个

联合体大小计算

1.联合体大小至少是最大成员大小。

  从上面的图可以看出,要想联合体能容纳的下所有成员,至少要大于最大的成员大小。

2. 当最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍

union UN
{
    char c[5];//可以看成是5个char类型的成员,每个对齐数是1,但是整体大小是5
    int i;
};

  最大成员大小是5,5不是最大对齐数4的整数,所以对齐到8,大小是8.

用联合体的特性,来判断电脑是大端还是小端。

union UN
{
    char c;
    int i;
}un;

int main()
{
    un.i=1;
    if(un,c==1)
      printf("是小端");
    else
      printf("是大段");
    return 0;
}

在执行un.i=1;这个代码后,内存中存储如下。 

(此时是小端)小端存储,高位在低地址处,01就会跑到c能访问的空间里。

  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值