我正在用我需要转换的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方法,因为它没有被使用。但主要是,我只想了解我指出的路线。
答案 0 :(得分:1)
该行
temp = (scratchVal[0] & 0xff) | ((scratchVal[1] << 8) & 0xff00);
从源自scratchVal
的两个字节创建无符号的16位整数值。此上下文中的单个&
不是地址运算符,而是按位AND。因此,temp
的低字节是从scratchVal
中包含的第一个字节设置的,temp
的高字节是通过左移scratchVal
中包含的第二个字节来设置的。 。两个结果数字使用按位OR |
连接在一起。为避免符号扩展或其他不需要的位,使用掩码0xff
和0xff00
来确保所有不受欢迎的值都为零。
直观地显示,如果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
。