在以下十六进制代码逻辑中很难理解。谁能解释开关条件中的&符,以及以前的TagSize是如何计算的。
- (void)parse:(NSInputStream*)inputStream {
NSInteger MASK = 0x1f;
NSInteger Type1 = 8;
NSInteger Type2 = 9;
NSInteger Type3 = 18;
uint8_t header[11];
long len = [inputStream read:header maxLength:11];
//How does it work?
switch (header[0] & MASK) {
case Type1:
self.type = Type_1;
break;
case Type2:
self.type = Type_2;
break;
}
self.dataSize = ((header[1] & 0x000000FF) << 16) | ((header[2] & 0x000000FF) << 8) | (header[3] & 0x000000FF);
// read previous tag size
uint8_t tagSize[4];
[inputStream read:tagSize maxLength:4];
int previousTagSize = ((tagSize[0] & 0x000000FF) << 24) |
((tagSize[1] & 0x000000FF) << 16) |
((tagSize[2] & 0x000000FF) << 8) |
(tagSize[3] & 0x000000FF);
if (previousTagSize != 11 + self.dataSize) {
NSLog(@"Invalid .");
}
}
答案 0 :(得分:1)
在十六进制代码逻辑下很难理解。
“逻辑”不是十六进制,而是整数和按位逻辑的组合。
“十六进制”只是表示Objective-C程序文本中整数值的一种方法。无论程序文本中整数的文本表示形式如何,编译后的Objective-C在计算机上执行的顺序都是按位顺序。
例如,
104
(十进制),0x68
(十六进制)和0150
(八进制)(如果存储在一个字节中)都使用相同的{{1 }}。计算机还将UTF-8字符“ h”视为那些相同有序的位序列。(注意:我在此答案中使用字节或8位来保存键入的大量零,在64位计算机上的
01101000
是64位,但用于示例中的值这里的前56位全为零。)
位是否被视为整数,浮点数,字符等取决于上下文-这就是整数和按位逻辑的用处...
有人可以在开关状态下解释“&”符号吗?
Objective-C中的NSInteger
运算符是按位和,即两个操作数中的有序位序列使用逻辑(aka布尔)和函数({ {1}},&
,0 and 0 = 0
和0 and 1 = 0
)。代码片段:
1 and 0 = 0
使用1 and 1 = 1
进行 masking 操作-如果您查看和函数,如果一个操作数是header[0] & MASK
,则结果为另一个操作数,如果为&
,则结果为1
,因此和可以用于“屏蔽”序列的一部分。
例如,考虑如果
。0
从上方持有我们104的表示形式,则该表示形式为8位为0
。header[0]
的表示形式,其值为01101000
,为8位,是MASK
。使用按位合并这两种表示,并给出序列0x1F
,其中前3个零是由于第二个操作数(“掩码”)中的零引起的,而5位序列00011111
与由于第二个操作数全为1,因此第一个操作数的后五位为按位排列之后,如果将所得的位序列解释为整数,则值为
00001000
,恰好与程序中的01000
相同。
因此,8
的作用是基于Type1
的后5位的整数解释进行选择。例如,当将多个数据值打包到较大的存储单元中时发生这种类型的代码-在这种情况下,64位中的5位(64位计算机上switch
的存储大小)。>
以及以前的TagSize的计算方式。
同样,这只是按位运算,运算符header[0]
是按位或,运算符NSInteger
是左移,只剩下一位shift丢弃有序位序列的最左位,并在最右端附加一个|
位(因此该序列保持相同的长度)。完整的片段:
<<
将4个值(每个值被屏蔽为8位[*])组合为一个32位(Objective-C中0
的大小)。
HTH
[*]如果该值是带符号类型,则即使该值适合目标位数以除去多余的位(以4位二进制补码表示形式{{1 }}代表5,int previousTagSize = ((tagSize[0] & 0x000000FF) << 24) |
((tagSize[1] & 0x000000FF) << 16) |
((tagSize[2] & 0x000000FF) << 8) |
(tagSize[3] & 0x000000FF);
代表-3;在8位中分别为int
和0101
,在第二种情况下,掩码会删除那些多余的1,否则它们将影响包装。拆下的1's会在拆箱后恢复。请阅读2's的补码以获取更多详细信息。