联合与枚举

联合:

也是一种由程序员设计的复合数据类型,使用语法与结构一模一样,与结构不同的是,结构中的成员各自拥有独立的内存,而联合中的所有成员共用一块内存(也叫共用体),所以只要有一个成员的值发生变化,其它成员的也会跟着一起变化。

union 联合名
{
    成员类型 成员名;
    ...
};
​
#include <stdio.h>
typedef union Data
{
    char ch; 
    int num;
    long ld; 
}Data;
​
int main(int argc,const char* argv[]) 
{
    printf("%d\n",sizeof(Data));
    Data d;
    printf("%p %p %p\n",&d.ch,&d.num,&d.ld);
    d.ch = 123;
    printf("%hhd %d %ld\n",d.ch,d.num,d.ld);
    d.num = 6666;
    printf("%hhd %d %ld\n",d.ch,d.num,d.ld);
    d.ld = 3456;
    printf("%hhd %d %ld\n",d.ch,d.num,d.ld);
}  

联合的总字节数:

由于联合的所有成员共用一块内存,所有成员是天然对齐的,不需要考虑内存对齐,但要考虑内存补齐。

情况1:所有联合的成员都是基本类型,则联合的总字节数就是最大成员的字节数。

情况2:如果联合的成员有数组类型,则联合的总字节数应该是最大成员的整数倍。

#include <stdio.h>
​
typedef union Data1
{
    char ch;
    int num;
}Data1;
​
typedef union Data2
{           
    long num;
    char arr[5];
}Data2;
​
int main(int argc,const char* argv[])
{
    printf("%d\n",sizeof(Data1)); // 结果是4
    printf("%d\n",sizeof(Data2)); // 结果是8
}

使用联合的意义:

1、使用少量的内存对应若干个标识符,只要不同时使用联合的成员,就不会冲突,能大大节约内存,在早期计算机内存比较小时,该技术使用较多,现在随着计算机内存越来越大已经基本不再使用。

2、联合可以对一块内存进行不同格式的解释,所以在网络通信时还存在着少量的使用(使用网络协议中已经设计好的联合体)。

枚举:

是一种值受限的整数类型,由程序员设置它的值的范围,并且还可以给这些值取一个名字。

设计枚举:

typedef enum 枚举名
{
    枚举值1,
    枚举值2,
    枚举值3,
    ...
}枚举名;
​
注意:使用标识符作为枚举值
    
// enum与struct、union一样,使用typedef重定义省略enum关键字

定义枚举变量:

enum 枚举名 枚举变量;

1、理论上枚举变量只能使用枚举值赋值,这样可以提高代码的可读性和安全性。

2、C语言编译器为了提高编译速度,不会检查枚举变量的赋值,全靠程序员的自觉(枚举变量就是int类型变量)。

3、C++编译器类型检查比较严格,所以使用C++编译器编译C代码时,枚举变量只能由枚举值赋值、比较。

#include <stdio.h>
​
enum DirectionKey
{
    Up,
    Down,
    Right,
    Left
};
​
int main(int argc,const char* argv[])
{
    enum DirectionKey key;
    key = 123;  // C++编译器会报错
    
    printf("%d\n",key);
    
    if(183 == key) // C++编译器会报错
}

枚举值:

1、第一个枚举值的默认值是0,之后的枚举值逐渐递增+1。

#include <stdio.h>
​
enum DirectionKey
{
    Up,
    Down,
    Right,
    Left
};
​
int main(int argc,const char* argv[])
{
    enum DirectionKey key;
    key = Up;
    printf("%d\n",key); // 0
    key = Down;
    printf("%d\n",key); // 1
    key = Right;
    printf("%d\n",key); // 2
    key = Left;  
    printf("%d\n",key); // 3
}

2、可以使用=设置枚举值,没有进行设置的枚举值是上一个枚举值递增+1。

#include <stdio.h>
​
enum DirectionKey
{
    Up = 123,
    Down,
    Right = 456,                  
    Left
};
​
int main(int argc,const char* argv[])
{
    enum DirectionKey key;
    key = Up;
    printf("%d\n",key); // 123
    key = Down;
    printf("%d\n",key); // 124
    key = Right;
    printf("%d\n",key); // 456
    key = Left;
    printf("%d\n",key); // 457
}

3、枚举值可以单独使用,这种用法可以给没有意义的字面值数据取一个有意义的名字,这样可以提高代码的可读取性,也可以定义匿名的枚举,只使用枚举值。

#include <stdio.h>
​
enum
{
    Up = 123,
    Down,
    Right = 456,
    Left
};
​
int main(int argc,const char* argv[])
{
    printf("%d %d %d %d\n",Up,Down,Right,Left);       
}

4、枚举值是常量,所以可以与switch语句配合使用,枚举值可以写在case的后面。

#include <stdio.h>
#include <getch.h>
​
enum
{
    Up = 183,
    Down,
    Right,
    Left
};
​
int main(int argc,const char* argv[])
{
    for(;;)
    {
        switch(getch())
        {
            case Up: puts("上"); break;
            case Down: puts("下"); break;
            case Right: puts("右"); break;
            case Left: puts("左"); break;    
        }
    }
}

5、枚举值的作用域是全局的(尽量名字取的复杂一些),所以它不能与全局变量、函数、结构、联合重名。

#include <stdio.h>       
#include <getch.h>
​
int num;
enum 
{
    Up = 183,
    Down,
    Right,
    Left,
    num,
    main
};
​
int main(int argc,const char* argv[])
{
    
}

注意:

枚举是一种锦上添花的技术,使用它能让代码的可读性、安全性更高,但直接使用字面值数据也不影响代码的编写和运行。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值