如何在Arduino C+中将大小为64的字节数组转换为双值列表+;? void管理器::ByteArrayToubleArray(字节ch[]){ int计数器=0; //临时数组,将字节数组拆分为8大小并读取它 字节温度[64]; //双结果值 双res[8]; int指数=0; int size=(sizeof(ch)/sizeof(*ch)); 对于(int i=0;i S.< /P> < P>你的问题是两件事。你有一些打字错误和误解。并且C++标准在这方面有点损坏。
这里的如何在Arduino C+中将大小为64的字节数组转换为双值列表+;? void管理器::ByteArrayToubleArray(字节ch[]){ int计数器=0; //临时数组,将字节数组拆分为8大小并读取它 字节温度[64]; //双结果值 双res[8]; int指数=0; int size=(sizeof(ch)/sizeof(*ch)); 对于(int i=0;i S.< /P> < P>你的问题是两件事。你有一些打字错误和误解。并且C++标准在这方面有点损坏。,c++,arduino,c++14,arduino-ide,C++,Arduino,C++14,Arduino Ide,这里的result将是一个双值列表,其中count=8您的问题是两件事。你有一些打字错误和误解。并且C++标准在这方面有点损坏。 我会试着把两者都修好 首先,一个名为洗衣房\u pods的助手函数。它获取原始内存并将其“清洗”到您选择的一种类型的数组中,只要您选择一种pod类型: void Manager::byteArrayToDoubleArray(byte ch[]) { int counter = 0; // temp array to break the byte array
result
将是一个双值列表,其中count=8
您的问题是两件事。你有一些打字错误和误解。并且C++标准在这方面有点损坏。
我会试着把两者都修好
首先,一个名为洗衣房\u pods
的助手函数。它获取原始内存并将其“清洗”到您选择的一种类型的数组中,只要您选择一种pod类型:
void Manager::byteArrayToDoubleArray(byte ch[]) {
int counter = 0;
// temp array to break the byte array into size of 8 and read it
byte temp[64];
// double result values
double res[8];
int index = 0;
int size = (sizeof(ch) / sizeof(*ch));
for (int i = 0; i < size; i++) {
counter++;
temp[i] = ch[i];
if (counter % 8 == 0) {
res[index] = *reinterpret_cast<double * const>(temp);
index++;
counter = 0;
}
}
}
模板
T*洗衣房(无效*ptr){
静态_断言(std::is_pod{});
优化的字符集[sizeof(T)*N];
标准::memcpy(优化的_-away、ptr、sizeof(T)*N);
T*r=::新的(ptr)T[N];
断言(r==ptr);
std::memcpy(r,优化的_-away,sizeof(T)*N);
返回r;
}
现在就做吧
template<class T, std::size_t N>
T* laundry_pods( void* ptr ) {
static_assert( std::is_pod<std::remove_cv_t<T>>{} );
char optimized_away[sizeof(T)*N];
std::memcpy( optimized_away, ptr , sizeof(T)*N );
T* r = ::new( ptr ) T[N];
assert( r == ptr );
std::memcpy( r, optimized_away, sizeof(T)*N );
return r;
}
void管理器::ByteArrayToubleArray(字节ch[]){
double*pdouble=洗衣房(ch);
}
而pdouble
是指向ch
内存的指针,被解释为8个双精度数组。(它不是它的副本,而是就地解释这些字节)
虽然洗衣房
似乎在复制周围的字节,但g++和clang都将其优化为二进制noop。对字节的复制是一种绕过C++标准中的混叠限制和对象生存规则的方法。
它依赖于POD数组,没有额外的记帐开销(C++实现是免费的,没有我知道的,这是非静态断言的双重检查),但是它返回一个指针,指向一个真正的“双精度”数组。如果要避免这种假设,可以将每个
doulbe
创建为单独的对象。然而,它们不是数组,就标准而言,非数组上的指针算法令人担忧
术语“清洗”的使用与绕过别名和对象生存期要求有关。函数在运行时不做任何事情,但是在C++抽象机中,它把内存转换为二进制相同的内存,现在是一组代码<双> /代码> S.< /P> < P>你的问题是两件事。你有一些打字错误和误解。并且C++标准在这方面有点损坏。 我会试着把两者都修好 首先,一个名为
洗衣房\u pods
的助手函数。它获取原始内存并将其“清洗”到您选择的一种类型的数组中,只要您选择一种pod类型:
void Manager::byteArrayToDoubleArray(byte ch[]) {
int counter = 0;
// temp array to break the byte array into size of 8 and read it
byte temp[64];
// double result values
double res[8];
int index = 0;
int size = (sizeof(ch) / sizeof(*ch));
for (int i = 0; i < size; i++) {
counter++;
temp[i] = ch[i];
if (counter % 8 == 0) {
res[index] = *reinterpret_cast<double * const>(temp);
index++;
counter = 0;
}
}
}
模板
T*洗衣房(无效*ptr){
静态_断言(std::is_pod{});
优化的字符集[sizeof(T)*N];
标准::memcpy(优化的_-away、ptr、sizeof(T)*N);
T*r=::新的(ptr)T[N];
断言(r==ptr);
std::memcpy(r,优化的_-away,sizeof(T)*N);
返回r;
}
现在就做吧
template<class T, std::size_t N>
T* laundry_pods( void* ptr ) {
static_assert( std::is_pod<std::remove_cv_t<T>>{} );
char optimized_away[sizeof(T)*N];
std::memcpy( optimized_away, ptr , sizeof(T)*N );
T* r = ::new( ptr ) T[N];
assert( r == ptr );
std::memcpy( r, optimized_away, sizeof(T)*N );
return r;
}
void管理器::ByteArrayToubleArray(字节ch[]){
double*pdouble=洗衣房(ch);
}
而pdouble
是指向ch
内存的指针,被解释为8个双精度数组。(它不是它的副本,而是就地解释这些字节)
虽然洗衣房
似乎在复制周围的字节,但g++和clang都将其优化为二进制noop。对字节的复制是一种绕过C++标准中的混叠限制和对象生存规则的方法。
它依赖于POD数组,没有额外的记帐开销(C++实现是免费的,没有我知道的,这是非静态断言的双重检查),但是它返回一个指针,指向一个真正的“双精度”数组。如果要避免这种假设,可以将每个
doulbe
创建为单独的对象。然而,它们不是数组,就标准而言,非数组上的指针算法令人担忧
术语“清洗”的使用与绕过别名和对象生存期要求有关。函数在运行时不执行任何操作,但是在C++抽象机中,它将内存转换为二进制相同的内存,现在是一组代码< double >代码> S.< /P> < P>这样做的“转换”的诀窍是始终将<代码>双*<代码>转换为<代码> char */COD>(或
unsigned char
或std::byte
)。决不能反过来
您应该能够执行以下操作:
void Manager::byteArrayToDoubleArray(byte ch[]) {
double* pdouble = laundry_pods<double, 8>(ch);
}
假设类型
byte
是char
或unsigned char
或std::byte
的别名,进行这种“转换”的诀窍是始终将double*
转换为char*
(或unsigned char
或std::byte
),而不是相反
您应该能够执行以下操作:
void Manager::byteArrayToDoubleArray(byte ch[]) {
double* pdouble = laundry_pods<double, 8>(ch);
}
假设类型
byte
是char
或unsigned char
或std::byte
的别名,我不能完全确定您在这里试图实现什么,因为代码(sizeof(ch)/sizeof(*ch))
对于未定义大小的数组没有意义
如果您有一个字节数组(POD数据类型;类似于typedef char byte;
),那么最简单的解决方案就是重新解释转换:
void byteArrayToDoubleArray(byte* in, std::size_t n, double* out)
{
for(auto out_bytes = (byte*) out; n--;)
*out_bytes++ = *in++;
}
// ...
byte ch[64];
// .. fill ch with double data somehow
double res[8];
byteArrayToDoubleArray(ch, 64, res);
因此,如果ch[]是一个包含64项的数组,而一个字节实际上是一个8位值,那么
std::vector<double> result(reinterpret_cast<double*>(ch), reinterpret_cast<double*>(ch) + itemsInCh * sizeof(*ch) / sizeof(double));
8个双精度值将占用与64字节值相同的内存。因此,您可以将字节值写入ByteToDuble.b[]
并从ByteToDuble读取结果双精度值。