iOS学习笔记-132.位移枚举

位移枚举

一、枚举的定义

1.1 普通枚举的定义

我们使用到的普通枚举,定义如下

/*第一种定义方式*/
typedef enum{
    QWMDemoTypeTop,
    QWMDemoTypeBottom
}QWMDemoType;

/*第二种定义方式*/
typedef NS_ENUM(NSInteger,QWMType) {
    QWMTypeTop,
    QWMTypeBottom
};

1.2 位移枚举的定义

定义如下

//第三种枚举 ,位移枚举
//一个参数可以传递多个值
//如果是位移枚举,观察第一个枚举值,如果该枚举值!=0 那么可以默认传0做参数,如果传0做参数,那么效率最高
typedef NS_OPTIONS(NSInteger, QWMActionType){
    //第三种枚举 ,位移枚举
//一个参数可以传递多个值
//如果是位移枚举,观察第一个枚举值,如果该枚举值!=0 那么可以默认传0做参数,如果传0做参数,那么效率最高
typedef NS_OPTIONS(NSInteger, QWMActionType){
    QWMActionTypeTop = 1<<0 ,    //  1  代表1右移0位   ...00000001(二进制)
    QWMActionTypeBottom = 1<<1 , //  2  代表1右移1位   ...00000010(二进制)
    QWMActionTypeLeft = 1<<2 ,   //  4  代表1右移2位   ...00000100(二进制)
    QWMActionTypeRight = 1<<3    //  8  代表1右移3位   ...00001000(二进制)
};

二、右移、左移、位与、位或运算

2.1 二进制

我们计算机所能识别的是二进制,当时我们我们现实中使用的是十进制。这个可以看

二进制如何转十进制,十进制如何转二进制

2.2 右移和左移

为了看着我们方便讨论,我们只讨论一个字节也就是8位二进制,这样我们更直观。

现在我们有十进制的数 1 ,我们现在来通过右移和左移来讨论一把。

1 = 00000001B 十进制 1 等于二进制的 1 这里为了我们讨论方便,所以加上了前面的0.


“<<” 这个符号代码左移,1<<2 这个就是代表我们 把1这个数据左移2位。这里的移动的位数是以二进制为准的。

那么现在回到我们的上面的 00000001B 这个数据上来。

1 << 0 (00000001B << 0) —> 其实就是没有移动,那么就是 1 = 00000001B

1 << 1 (00000001B << 1) —> 向左移动一位,那么数据就变成了 00000010B = 2

同理下下

1 << 2 (00000001B << 2) —> 00000001B << 2 = 00000100B = 4

1 << 3 (00000001B << 3) —> 00000001B << 3 = 00001000B = 8

1 << 4 (00000001B << 4) —> 00000001B << 4 = 00010000B = 16

1 << 5 (00000001B << 5) —> 00000001B << 5 = 00100000B = 32

1 << 6 (00000001B << 6) —> 00000001B << 6 = 01000000B = 64

1 << 7 (00000001B << 7) —> 00000001B << 7 = 10000000B = 128

1 << 8 (00000001B << 8) —> 00000001B << 8 = 00000000B = 0


下面我们来讨论 右移(“>>”代表右移),其实道理是一样的,好的,那么我们来看一个数据 128 这个数据。

128 >> 1 (00000001B >> 1) —> 向右移动一位,那么数据就变成了 01000000B = 64

同理如下

128 << 2 (10000000B << 2) —> 10000000B << 2 = 00100000B = 32

128 << 3 (10000000B << 3) —> 10000000B << 3 = 00010000B = 16

128 << 4 (10000000B << 4) —> 10000000B << 4 = 00001000B = 8

128 << 5 (10000000B << 5) —> 10000000B << 5 = 00000100B = 4

128 << 6 (10000000B << 6) —> 10000000B << 6 = 00000010B = 2

128 << 7 (10000000B << 7) —> 10000000B << 7 = 00000001B = 1

128 << 8 (10000000B << 8) —> 10000000B << 8 = 00000000B = 0


2.3 位与 和 位或

位与(&) 和 位或(|) 中的位都是针对二进制的。其中:


位与

位与 我们可以把它看做是 位相乘,特点就是只有两个都是1那么才会是1,不然都是0。如下

我们取两个数据 1(00000001B) 和 2(00000010B) 来计算一把

0 0 0 0 0 0 0 1 B  = 1
&
0 0 0 0 0 0 1 0 B  = 2
-----------
0 0 0 0 0 0 0 0 B  = 0

上面这个原酸中,我们发现,第一个数据 1 和第二个数据 2 与运算的时候,我们可以看作是 位上面相乘。

两个数据的第一位数据分析: 1 * 0 = 0,所以为结果第一位为 0

两个数据的第二位数据分析: 0 * 1 = 0,所以为结果第二位为 0
。。。。

最后我们得到了数据 就是 00000000B = 0。

下面我们再来看一组数据 1(00000001B) 和 7(00000111B)

0 0 0 0 0 0 0 1 B  = 1
&
0 0 0 0 0 1 1 1 B  = 7
-----------
0 0 0 0 0 0 0 1 B  = 1

两个数据的第一位数据分析: 1 * 1 = 1,所以为结果第一位为 1

两个数据的第二位数据分析: 0 * 1 = 0,所以为结果第二位为 0

。。。
最后我们得到了数据 就是 00000001B = 1。


位或

位或(|) 特点是只要其中一个为 1 ,那二个结果就为1,或者说,只要两个不是不全为0,就是1

下面我们取 9(0 0 0 0 1 0 0 1 B )和 7(0 0 0 0 0 1 1 1 B )来运算一把

0 0 0 0 1 0 0 1 B  = 9
|
0 0 0 0 0 1 1 1 B  = 7
-----------
0 0 0 0 1 1 1 1 B  = 15

三、位移枚举的位与、位或分析

我们现在使用,我们上面提到的 位移枚举,如下

typedef NS_OPTIONS(NSInteger, QWMActionType){
    QWMActionTypeTop = 1<<0 ,    //  1  代表1右移0位   ...00000001(二进制)
    QWMActionTypeBottom = 1<<1 , //  2  代表1右移1位   ...00000010(二进制)
    QWMActionTypeLeft = 1<<2 ,   //  4  代表1右移2位   ...00000100(二进制)
    QWMActionTypeRight = 1<<3    //  8  代表1右移3位   ...00001000(二进制)
};

下面我们只讨论 最低的一个字节。

我们现在想拥有 QWMActionTypeTopQWMActionTypeBottom
的功能,

那么怎么处理,也即是我们需要二者都存在,这个不就是我们所说的 位或 吗?

于是我们就有


(QWMActionTypeTop | QWMActionTypeBottom)-->( 00000001B | 00000010B) = (00000011B)=3

好的,这样我们就是实现了这个功能。

现在我们有个需求是,别人给我们传递了 一个值过来,我们想知道,它里面有没有有没有

QWMActionTypeTop这个功能呢,其实就是通过运算以后得到有没有 QWMActionTypeTop这个值,

这个不是就是我们说的 位与 吗? 假设我们传递过来了一个值 5(00000101B),那么我们如下操作

00000101B & QWMActionTypeTop ---> 00000101B & 00000001B = 00000001B = QWMActionTypeTop

通过验证我们发现 5 有 QWMActionTypeTop这个功能。

==注意:为什么我们在定义枚举值得时候,使用的只是数据,只有一个位数上有1的,而不是多个位数上有1的呢? 这其实为了避免,位与、位或的时候产生枚举值之间的污染==


四、示例代码

//
//  ViewController.m
//  03_UIView90_位移枚举
//
//  Created by 杞文明 on 17/9/9.
//  Copyright © 2017年 杞文明. All rights reserved.
//

#import "ViewController.h"

/*第一种定义方式*/
typedef enum{
    QWMDemoTypeTop,
    QWMDemoTypeBottom
}QWMDemoType;

/*第二种定义方式*/
typedef NS_ENUM(NSInteger,QWMType) {
    QWMTypeTop,
    QWMTypeBottom
};

//第三种枚举 ,位移枚举
//一个参数可以传递多个值
//如果是位移枚举,观察第一个枚举值,如果该枚举值!=0 那么可以默认传0做参数,如果传0做参数,那么效率最高
typedef NS_OPTIONS(NSInteger, QWMActionType){
    QWMActionTypeTop = 1<<0 ,    //  1  代表1右移0位   ...00000001(二进制)
    QWMActionTypeBottom = 1<<1 , //  2  代表1右移1位   ...00000010(二进制)
    QWMActionTypeLeft = 1<<2 ,   //  4  代表1右移2位   ...00000100(二进制)
    QWMActionTypeRight = 1<<3    //  8  代表1右移3位   ...00001000(二进制)
};

@interface ViewController ()

@end

@implementation ViewController

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self test: QWMActionTypeRight | QWMActionTypeLeft ];
}

-(void)test:(QWMActionType)type{
    NSLog(@"%zd",type);

    if (type & QWMActionTypeTop) {
        NSLog(@"向上---%zd",type & QWMActionTypeTop);
    }

    if (type & QWMActionTypeRight) {
        NSLog(@"向右---%zd",type & QWMActionTypeRight);
    }
    if (type & QWMActionTypeBottom) {
        NSLog(@"向下---%zd",type & QWMActionTypeBottom);
    }

    if (type & QWMActionTypeLeft) {
        NSLog(@"向左---%zd",type & QWMActionTypeLeft);
    }

}

@end

五、运行结果

2017-09-10 00:19:00.947 03_UIView90_位移枚举[24230:104789] 12
2017-09-10 00:19:00.947 03_UIView90_位移枚举[24230:104789] 向右---8
2017-09-10 00:19:00.948 03_UIView90_位移枚举[24230:104789] 向左---4
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值