动态大小的多维数组的 C++ 解决方法
Posted
技术标签:
【中文标题】动态大小的多维数组的 C++ 解决方法【英文标题】:C++ Workaround for multidimensional arrays of dynamic size 【发布时间】:2018-05-31 14:24:00 【问题描述】:我正在寻找一种简单的解决方法,将动态大小的二维数组作为 5 年级学生可以轻松使用的参数。我目前正在为微控制器研讨会编写一个库,并希望它尽可能易于使用,而无需解释指针、模板等,因为没有时间这样做。
我有以下类,称为 LEDBitmap
,由于另一个库中的限制,它的最大宽度为 8,并表示 LED 矩阵的 1 和 0 位图:
头文件:
#ifndef LEDBITMAP_H
#define LEDBITMAP_H
#include <Arduino.h>
class LEDBitmap
public:
LEDBitmap(uint8_t width, uint8_t height, uint8_t data[][8]);
LEDBitmap(uint8_t width, uint8_t height);
virtual ~LEDBitmap()
delete [] _data;
;
public: //methods
uint8_t* getBitmap();
uint8_t getPixelValue(uint8_t x, uint8_t y)
return _data[y][x];
;
void setPixelValue(uint8_t x, uint8_t y, uint8_t value)
_data[y][x] = value;
;
uint8_t getHeight()
return _height;
;
uint8_t getWidth()
return _width;
;
uint8_t getSize()
return _width * _height;
;
void clear();
private: //members
uint8_t _width;
uint8_t _height;
uint8_t _data[][8];
;
#endif
还有cpp文件:
#include "LEDBitmap.h"
LEDBitmap::LEDBitmap(uint8_t width, uint8_t height)
_width = width;
_height = height;
_data = new uint8_t[width][height];
clear();
LEDBitmap::LEDBitmap(uint8_t width, uint8_t height, uint8_t data[][8])
_width = width;
_height = height;
_data = data;
uint8_t* LEDBitmap::getBitmap()
uint8_t result[_height];
for (uint8_t h = 0; h < _height; h++)
uint8_t binary = 0;
for (uint8_t w = 0; w < _width; w++)
binary |= _data[h][w] << (_width - w+1);
result[h] = binary;
return result;
void LEDBitmap::clear()
for (uint8_t h = 0; h < _height; h++)
for (uint8_t w = 0; w < _width; w++)
_data[h][w] = 0;
我的问题是第一个构造函数,其中参数uint8_t data[][8]
应该是任意高度和最大宽度为 8 但可能更小的数组。
我曾尝试使用模板,但意识到这会导致代码的其他部分出现更大的问题。如果我要使用模板,那么它们只能在构造函数中使用,而不必执行 LEDBitmap<5, 5> image = ...
之类的操作,而只需使用 LEDBitmap image = LEDBitmap<5, 5>(...)
我无法使用向量,因为它们不是 Arduino IDE 的一部分,它是用 C 编写的。我的库是用 C++ 编写的,因为我正在使用其他一些 C++ 库和最初想使用不同的平台,但由于一些问题,我最近不得不切换到 Arduino。
我目前遇到的错误是:no known conversion for argument 3 from 'uint8_t [3][3] aka unsigned char [3][3]' to 'uint8_t (*)[8] aka unsigned char (*)[8]'
提前感谢您的提示和帮助。
【问题讨论】:
std::vector<std::vector<char>>
应该是此类问题的默认解决方案。如果LEDBitmap
被正确封装,则不需要更改任何其他代码。
“为了简单起见,我也想尽量远离向量……” 这就是问题所在。 std::vector
应该是第一选择的容器。你应该使用std::vector<std::vector<>>
。或者教C
而不是C++
是的,应该是,但如上所述,为了简单起见,我想尽量远离那些,因为五年级学生使用数组更容易
C 数组有各种各样的问题,衰减到指针;动态大小需要使用new
;不知道自己的大小。
看起来这适用于 Arduino,而且 afaik,它不支持 vector
(或 std lib 的其余部分)oob。
【参考方案1】:
C++ 不喜欢可变长度数组(即使在某些实现中支持,也从未在标准中定义)也不喜欢原始 2D 数组。如果您不需要真正的[]
运营商支持,我的建议是使用访问器函数:
class Array2D
size_t width, height;
uint8_t *data;
public:
Array2D(size_t width, size_t height): width(width), height(height()
data = new uint8_t[width * height];
~Arrayt2D()
delete[] data;
// copy/move ctor-assignment operator omitted for brievety but REQUIRED (law of three/five)
uint8_t getVal(size_t i, size_t j) const
return data[i + j * width];
uint8_t setVal(uint8_t val, size_t i, size_t j)
data[i + j * width] = val;
/* alternatively to use arr.val(i, j) = value :
uint8_t& val(size_t i, size_t j)
return data[i + j * width];
*/
// other accessors (height, width) omitted but probably useful...
;
相当 C-ish,但由于您不能使用向量并且更喜欢避免使用模板,因此它可能是一个基本骨架...
【讨论】:
以上是关于动态大小的多维数组的 C++ 解决方法的主要内容,如果未能解决你的问题,请参考以下文章