我正在装箱我需要转换的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中包含的第二个字节左移来设置的。使用位或|将两个结果数字连接在一起。为了避免符号扩展或其他不需要的位,使用掩码0xff0xff00来确保所有不希望的值均为零。

直观显示,如果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/

10-10 08:40