我正在装箱我需要转换的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方法,因为未使用它。但主要是,我只是想了解我指出的内容。
最佳答案
线
temp = (scratchVal[0] & 0xff) | ((scratchVal[1] << 8) & 0xff00);
正在从
scratchVal
起源的两个字节创建一个无符号的16位整数值。在这种情况下,单个&
不是地址运算符,而是按位与。因此,temp
的低字节是从scratchVal
中包含的第一个字节开始设置的,而temp
的高字节是通过将scratchVal
中包含的第二个字节左移来设置的。使用位或|
将两个结果数字连接在一起。为了避免符号扩展或其他不需要的位,使用掩码0xff
和0xff00
来确保所有不希望的值均为零。直观显示,如果
scratchVal
在前两个字节中包含位aaaaaaaa bbbbbbbb
,则temp最终将成为具有位模式bbbbbbbbaaaaaaaa
的无符号整数。第二个问题问为什么他们要呼叫
-getBytes:length:
。线[data getBytes:&scratchVal length:data.length];
将
data
中的字节读取到scratchVal
临时缓冲区中。回应评论中的问题
为什么需要左移位以连接它们
一个简单的任务是行不通的。再次假设
scratchVal
是包含char
位的aaaaaaaa bbbbbbbb
缓冲区,代码temp = scratchVal[0];
将使temp等于
UInt16
位的aaaaaaaa
等价物。您不能使用加法,因为结果将是将两个字节加在一起(aaaaaaaa
+ bbbbbbbb
)所得的任何值。以实数为例,假设
scratchVal
的前两个字节等于0x7f 0x7f
。temp = scratchVal[0] + scratchVal[1];
原来是
0x7f + 0x7f
= 0xfe
,这不是此代码的目的。通过将OR分解为多个步骤,可以更好地理解其价值。
表达式的第一部分是
scratchVal[0] & 0xff
= 0x7f & 0xff
= 0x7f
第二部分是
(scratchVal[1] << 8) & 0xff00
= (0x7f << 8) & 0xff
= 0x7f00 & 0xff
= 0x7f00
在这种情况下,最终结果为
0x7f | 0x7f00
= 0x7f7f
。关于ios - 代码片段缺乏理解,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28067525/