我在C#中有以下代码来计算CRC,它的工作方式与我想要的一样。
public byte crc_8(byte[] byteArray)
{
ushort reg_crc = 0;
for(int i = 0; i<byteArray.Length; i++)
{
reg_crc ^= byteArray[i];
for(int j = 0; j < 8; j++)
{
if((reg_crc & 0x01) == 1)
{
reg_crc = (ushort)((reg_crc >> 1) ^ 0xE5);
}
else
{
reg_crc = (ushort)(reg_crc >> 1);
}
}
}
reg_crc = (byte)(reg_crc & 0xFF);
return (byte)reg_crc;
}
我还需要将此相同的功能添加到C ++中的代码项目中,但是我是C ++的新手。据我所知,我不确定如何继续for循环内的代码。还请注意,RX_PACKET_SIZE
与byteArray.Length
等效,因为它可以用于相同的目的。我知道那没关系。
static uint8_t crc_8(unit8_t array_to_process [])
{
uint16_t reg_crc = 0;
for(int i = 0; i < RX_PACKET_SIZE; i++)
{
}
}
答案 0 :(得分:1)
数组在C ++中的工作方式略有不同。它们不是对象。它们基本上只是在存储器中n
重复一次的数据类型。在您的情况下,将uint_8
重复RX_PACKET_SIZE
次。您不传递数组本身;而是传递数组本身。相反,您将指针传递给数组的第一个元素。这是您代码的C ++版本:
uint8_t crc_8(uint8_t* byteArray, size_t length)
{
uint8_t reg_crc = 0;
for(int i = 0; i < length; i++)
{
reg_crc ^= byteArray[i];
for(int j = 0; j < 8; j++)
{
if((reg_crc & 0x01) == 1)
{
reg_crc = (reg_crc >> 1) ^ 0xE5;
}
else
{
reg_crc = reg_crc >> 1;
}
}
}
return reg_crc;
}
我将reg_crc
的类型更改为uint8_t
,因为您对其执行的任何操作都不使用后一半的位。假设您知道长度为RX_PACKET_SIZE
,我们也可以给length
一个默认值:
uint8_t crc_8(uint8_t* byteArray, size_t length = RX_PACKET_SIZE)
{
uint8_t reg_crc = 0;
for(int i = 0; i < length; i++)
{
reg_crc ^= byteArray[i];
for(int j = 0; j < 8; j++)
{
if((reg_crc & 0x01) == 1)
{
reg_crc = (reg_crc >> 1) ^ 0xE5;
}
else
{
reg_crc = reg_crc >> 1;
}
}
}
return reg_crc;
}
对将来有用的提示:
C ++标准库提供了一个名为std::vector
的类。 std::vector
具有与ArrayList在C#中相同的功能,但是由于C ++模板的工作方式,它可能会更快。
您可以为crc_8
写一个重载,这样就可以将其传递给向量:
// The & after std::vector<uint8_t> means that it'll pass
// by reference, instead of passing by value. Passing by
// reference is usually the preferable option because nothing
// gets copied, making it much faster.
uint8_t crc_8(std::vector<uint8_t>& bytes) {
//This calls the the version shown above
return crc_8(bytes.data(), bytes.size());
}
如果编译器说未定义uint8_t
,那是因为您需要将#include <cstdint>
放在文件的顶部。