[英]What does it mean the following C statement? ((int*) & var)
我在C中有以下代码来为某些数据流计算CRC16-USB:
uint16_t DRV_CANFDSPI_CalculateCRC16(uint8_t* data, uint16_t size)
{
uint16_t init = CRCBASE;
uint8_t index;
while (size-- != 0) {
index = ((uint8_t*) & init)[1] ^ *data++;
init = (init << 8) ^ crc16_table[index];
}
return init;
}
其中crc16_table是一些2字节的十六进制值的数组(如0xAFF3),而data是一个1字节的十六进制值的数组(如0xA3),代表数据流(通过其他方式求得)。 大小是数据数组的长度。
我想用Python重现这段代码,但我不知道该语句的意思是:
index = ((uint8_t*) & init)[1] ^ *data++;
我想了解这种说法的含义和作用,所以我可以在Python中重现它。 我不是C语言方面的专家,但是拥有一些知识,并且大部分时候我都不理解其余的代码,但是这一行让我头疼。
感谢,并有一个愉快的一天!
init
类型为uint16_t
,因此表达式 &init
类型为“指向uint16_t
指针”或uint16_t *
。 表达式(uint8_t *) &init
的意思是“得到的地址init
,但可以把它看成一个地址uint8_t
对象,而不是一个uint16_t
对象”。
然后将该地址与下标运算符- ((uint8_t *) &init)[1]
一起使用,该运算符基本上等效于“将init
为两个uint8_t
对象的数组,并给我该数组中第二个元素的值” 。
图形:
+---+
init: | | <-- ((uint8_t *) &init)[0]
+---+
| | <-- ((uint8_t *) &init)[1]
+---+
因此,基本上,您要抓取init
的低8位,将其与输入消息的当前字节的值按位进行XOR运算,然后前进data
以指向输入消息的下一个字节。
我使用以下代码找到了解决问题的方法:
def calculateCRC16(data):
init = 0xFFFF
for byte in data:
index = (init >> 8) ^ byte
init = ((init << 8) ^ crc16_table[index]) & 0xFFFF
return init
我认为这很简单。 我用C中的上述代码测试了此代码,结果是相同的。 必须使用Python中的变量init进行屏蔽,因为Python不会将int变量限制为固定的位大小。 同样,在C语言中,应包含lib以使代码起作用。
index = ((uint8_t*) & init)[1] ^ *data++;
的意图index = ((uint8_t*) & init)[1] ^ *data++;
声明是将init
的高八位与data
的下一个字节进行异或(并递增data)。 不幸的是,它写得不正确。
在语句中index = ((uint8_t*) & init)[1] ^ *data++;
:
& init
需要的地址init
(将其用定义uint16_t init = CRCBASE;
(uint8_t*)
将该地址转换为指向uint8_t
。 进一步使用此指针要求uint8_t
在C实现中为字符类型,这很可能但C标准不能保证。 [1]
应用于此指针将获取指针指向的下一个字节。 第二行使用init << 8
(其结果仅取决于init
的*低**八位)的事实表明,第一行的意图是获取init
的高八位。 但是,C标准不要求uint16_t
的字节采用任何特定顺序,因此不能保证使用[1]
会获取所需的位。 而且这是不必要的; 使用init >> 8
代替((uint8_t*) & init)[1]
将提供所需的位。
因此,代码本来可以很简单:
while (size--)
init = init << 8 ^ crc16_table[init>>8 ^ *data++];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.