下面的C语句是什么意思? ((int*) & 变量)
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)表示数据流(通过其他方式获取)。 Size 是 data 数组的长度。
我想在Python中重现这段代码,但不知道这个语句的意思是:
index = ((uint8_t*) & init)[1] ^ *data++;
我想了解此声明的含义和作用,因此我可以在 Python 中重现它。我不是 C 专家,但有一些知识,我大部分都看不懂其余的代码,但这行让我很头疼。
谢谢,祝你有愉快的一天!
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
的 *low** 八位,这表明第一行的目的是获取 high八位init
.
但是,C 标准不要求 uint16_t
的字节按任何特定顺序排列,因此不能保证使用 [1]
会获取所需的位。这是不必要的;使用 init >> 8
代替 ((uint8_t*) & init)[1]
将提供所需的位。
因此,代码可以很简单:
while (size--)
init = init << 8 ^ crc16_table[init>>8 ^ *data++];
init
的类型为 uint16_t
,因此 表达式 &init
的类型为 "pointer to uint16_t
",或 uint16_t *
.表达式 (uint8_t *) &init
表示 "get the address of init
, but treat that as the address of a uint8_t
object, rather than a uint16_t
object".
该地址然后与下标运算符一起使用 - ((uint8_t *) &init)[1]
,这基本上等同于 "treat init
as an array of two uint8_t
objects, and give me the value of the second element in that array"。
图形化:
+---+
init: | | <-- ((uint8_t *) &init)[0]
+---+
| | <-- ((uint8_t *) &init)[1]
+---+
所以,基本上,您是获取 init
的低 8 位,将其与输入消息的当前字节的值按位异或,然后前进 data
以指向输入消息的下一个字节。
我找到了解决问题的方法,代码如下:
def calculateCRC16(data):
init = 0xFFFF
for byte in data:
index = (init >> 8) ^ byte
init = ((init << 8) ^ crc16_table[index]) & 0xFFFF
return init
我认为这很简单。我在 C 中用上面的代码测试了这段代码,结果是一样的。变量 init 中的 Python 中的掩码是必要的,因为 Python 不会将 int 变量限制为固定的位大小。此外,在 C 中,应包含 lib 以使代码正常工作。
我在 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)表示数据流(通过其他方式获取)。 Size 是 data 数组的长度。
我想在Python中重现这段代码,但不知道这个语句的意思是:
index = ((uint8_t*) & init)[1] ^ *data++;
我想了解此声明的含义和作用,因此我可以在 Python 中重现它。我不是 C 专家,但有一些知识,我大部分都看不懂其余的代码,但这行让我很头疼。
谢谢,祝你有愉快的一天!
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
的 *low** 八位,这表明第一行的目的是获取 high八位init
.
但是,C 标准不要求 uint16_t
的字节按任何特定顺序排列,因此不能保证使用 [1]
会获取所需的位。这是不必要的;使用 init >> 8
代替 ((uint8_t*) & init)[1]
将提供所需的位。
因此,代码可以很简单:
while (size--)
init = init << 8 ^ crc16_table[init>>8 ^ *data++];
init
的类型为 uint16_t
,因此 表达式 &init
的类型为 "pointer to uint16_t
",或 uint16_t *
.表达式 (uint8_t *) &init
表示 "get the address of init
, but treat that as the address of a uint8_t
object, rather than a uint16_t
object".
该地址然后与下标运算符一起使用 - ((uint8_t *) &init)[1]
,这基本上等同于 "treat init
as an array of two uint8_t
objects, and give me the value of the second element in that array"。
图形化:
+---+
init: | | <-- ((uint8_t *) &init)[0]
+---+
| | <-- ((uint8_t *) &init)[1]
+---+
所以,基本上,您是获取 init
的低 8 位,将其与输入消息的当前字节的值按位异或,然后前进 data
以指向输入消息的下一个字节。
我找到了解决问题的方法,代码如下:
def calculateCRC16(data):
init = 0xFFFF
for byte in data:
index = (init >> 8) ^ byte
init = ((init << 8) ^ crc16_table[index]) & 0xFFFF
return init
我认为这很简单。我在 C 中用上面的代码测试了这段代码,结果是一样的。变量 init 中的 Python 中的掩码是必要的,因为 Python 不会将 int 变量限制为固定的位大小。此外,在 C 中,应包含 lib 以使代码正常工作。