代码段缺乏理解

时间:2015-01-21 12:42:13

标签: ios objective-c

我正在用我需要转换的C代码片段装箱。 其中一项功能如下:

+(float) calcTemp:(NSData *)data {
    char scratchVal[data.length];
    [data getBytes:&scratchVal length:data.length];
    UInt16 temp;
    temp = (scratchVal[0] & 0xff) | ((scratchVal[1] << 8) & 0xff00);
    return (float)temp;
}

这句话我似乎无法掌握:

temp = (scratchVal[0] & 0xff) | ((scratchVal[1] << 8) & 0xff00);

我知道这可能是一个新的问题(但我是一个菜鸟^),如果有人能向我解释这条线,我会非常感激。特别是带地址引用和运算符的东西。

在代码段中,我不明白为什么他们为数据调用getBytes:length方法,因为它没有被使用。但主要是,我只想了解我指出的路线。

1 个答案:

答案 0 :(得分:1)

该行

temp = (scratchVal[0] & 0xff) | ((scratchVal[1] << 8) & 0xff00);

从源自scratchVal的两个字节创建无符号的16位整数值。此上下文中的单个&不是地址运算符,而是按位AND。因此,temp的低字节是从scratchVal中包含的第一个字节设置的,temp的高字节是通过左移scratchVal中包含的第二个字节来设置的。 。两个结果数字使用按位OR |连接在一起。为避免符号扩展或其他不需要的位,使用掩码0xff0xff00来确保所有不受欢迎的值都为零。

直观地显示,如果scratchVal在前两个字节中包含位aaaaaaaa bbbbbbbb,则temp将以位模式bbbbbbbbaaaaaaaa的无符号整数结束。

第二个问题是他们为什么要打电话给-getBytes:length:。这条线

[data getBytes:&scratchVal length:data.length];

data中的字节读入scratchVal临时缓冲区。

回应评论中的问题

  

为什么需要左移位来连接它们

简单的作业无法奏效。再次假设scratchVal是包含位char的{​​{1}}缓冲区,代码

aaaaaaaa bbbbbbbb

会使temp等于位temp = scratchVal[0]; 的{​​{1}}等价物。您无法使用加法,因为结果将是将两个字节加在一起的任何值(UInt16 + aaaaaaaa)。

以实数为例,假设aaaaaaaa的前两个字节等于bbbbbbbb

scratchVal

原来是0x7f 0x7f = temp = scratchVal[0] + scratchVal[1]; ,这不是此代码的目的。

使用OR构建值可以通过将其分解为步骤来更好地理解。

表达式的第一部分是0x7f + 0x7f = 0xfe = scratchVal[0] & 0xff

第二部分是0x7f & 0xff = 0x7f = (scratchVal[1] << 8) & 0xff00 = (0x7f << 8) & 0xff

此案例的最终结果是0x7f00 & 0xff = 0x7f00