iOS 的与、或运算及操作字节数组基础

1,103 阅读4分钟

前言 笔者在 iOS 蓝牙的基本使用iOS 蓝牙的基本使用(二) 中记录了iOS蓝牙的基本使用的内容。
笔者会先介绍下位运算中的 或、与运算;
记录下从字节数组和二进制数据的转换的内容;

或、与运算

笔者主要说明或、与运算,是因为我们可以在组包和拆包的的过程中经常用到这2个位运算。 笔者简单说明下二进制的值是由0、1组成。 我们比较熟悉的十进制是由0-9组成。 16进制的前是由0-9、a、b、c、d、e、f 分别表示10进制的0-15。

或运算

或运算的操作结果是由运算的值中如果有一个为1就会得到1。就像咱们计算机运算中 1 | 0 为1 ,0 | 0 结果为0,1 | 1 结果为1。这种或运算就是有一个值为1,结果就为1。 大家知道计算机语言中或运算符用 | 表示。 笔者以二进制为例说明下或运算 0001 | 0011 结果为0011,0011的十进制为3,0011的十六进制表示形式为0x03。 0x70 | 0x71 的结果为0x71 0x80 | 0x71 的结果为0xf1。这里笔者可以简单说明下0x80 | 0x71 的计算过程。 0x80 为二进制的1000 0000 0x71为二进制的0111 0001 所以0x80 | 0x71 的二进制结果为 1111 0001,所以其16进制的结果为0xf1。

与运算

与运算的操作结果是由运算的值中两个值同事为1才会会得到结果1。就像咱们计算机运算中 0 & 1 或 1&0为1 ,0 | 0 结果为0,1 & 1 结果为1。这种或运算就是有一个值为1,结果就为1。 大家知道计算机语言中或运算符用 & 表示。 笔者以二进制为例说明下或运算 0001 & 0011 结果为0001,0001的十进制为1,0001的十六进制表示形式为0x01。 0x70 & 0x71 的结果为0x70 0x80 & 0x71 的结果为0x01。这里笔者可以简单说明下0x80 & 0x71 的计算过程。 0x80 为二进制的1000 0000 0x71为二进制的0111 0001 所以0x80 & 0x71 的二进制结果为 0000 0000,所以其16进制的结果为0x00。

字节数组和二进制数据的转换

    Byte bytes[] = {0x10, 0x11, 0x12, 0x13};
    NSData *data = [[NSData alloc] initWithBytes:bytes length:sizeof(bytes)];

上述代码的二进制数据为相应的字节数组的ASCII码。即data的值为:<10111213>

下列代码的用于从二进制数据得到字节数组。有个注意事项是指针指向内容的长度的取值方式,笔者这里使用的是data.length;因为笔者尝试过使用指针名字bytes2取长度的话,使用 sizeof(bytes2) 每次取出来的值都是8,因为bytes2是指针,指针的占用8个字节的内存。不像上边的bytes数组,使用sizeof(bytes)可以取出数组的内存占用空间。

    NSInteger dataLength = data.length;
    Byte *bytes2 = (Byte *)data.bytes;
    // 注意不能用 sizeof(bytes2); 结果为8 // 因为指针的字节数为8
    for (NSInteger i = 0; i < dataLength; i++) {
        NSLog(@"byte:%02x", bytes2[i]);
    }

通过上述代码,我们可以知道取字节数组中相应的字节,直接使用数组名相应下标即可取出对应位置的字节。

结合上边的内容,我们可以利用或、与运算做更多尝试。 笔者这里先举个例子

    Byte bytes3[] = {0x01, 0x01, 0xf0, 0x02};
    Byte bytes4[] = {0x10, 0x10, 0x0f, 0x20};
    Byte bytes5[] = {0x00, 0x00, 0x00, 0x00};
    for (NSInteger i = 0; i < sizeof(bytes3); i++) {
        bytes5[i] = bytes3[i] | bytes4[i];
        NSLog(@"byte5:%02x", bytes5[i]);
    }

上述代码的结果为

2021-01-15 22:33:42.621638+0800 WDemo[31816:2925863] byte5:11
2021-01-15 22:33:46.018359+0800 WDemo[31816:2925863] byte5:11
2021-01-15 22:33:46.018685+0800 WDemo[31816:2925863] byte5:ff
2021-01-15 22:33:46.018888+0800 WDemo[31816:2925863] byte5:22

我们在拆包组包的时候还可能会用到左移、右移的运算。笔者会在后续的文章中做更多介绍。