我開始在嵌入式設備的背景關系中學習 C 和 C,最近我開始制作自己的庫,以稍微清理我的代碼。我在將二維陣列傳遞給我的函式時遇到問題。問題如下:
uint8_t cardSectors[8][16];
cardsClient.readDataBlocks(uid, uidLength, *cardSectors, 8, 16);
如您所見,我將cardSectors作為指向陣列的指標傳遞。稍后在讀取卡片的函式中,我使用以下方法將卡片資料寫入指標:
mifareclassic_ReadDataBlock(currentBlock, &cardSectors[currentBlock]);
它有效!我可以使用以下方法讀取資料:&cardSectors[currentBlock]。
但這就是問題所在。從原始變數中讀取資料怎么樣uint8_t cardSectors[8][16]?無論我做什么,我都無法獲取我想要的資料。我不知道我是不是真的沒有保存這些資料還是有其他問題。基本上這是一個呼叫堆疊:
uint8_t cardSectors[8][16];
cardsClient.readDataBlocks(uid, uidLength, *cardSectors, blocks, blockSize);
Serial.println("Do something with this data!");
執行 readDataBlocks 后如何訪問這些資料?
uj5u.com熱心網友回復:
在 C 中,這可能是最簡單的
#include <vector>
template <class T>
using Arr2D = std::vector<std::vector<T>>;
并傳遞這種型別。
由于 C 僅略高于匯編語言的水平,缺乏模板和其他方便的概念,處理 2D 陣列的一種方法是擁有一個線性記憶體塊,并使用諸如ìndex = row * ncols col. 這為您節省了一些構建和清理指向某些結構的指標陣列的作業,并且與在堆上單獨分配每一行相比,它還提供了更好的快取區域性。
typedef struct Arr2D_tag {
void* data;
size_t element_size;
size_t nrows;
size_t ncols;
} Arr2D_t;
void* arr2d_at(Arr2D_t *array, size_t row, size_t col) {
if (NULL == array) return NULL;
if (NULL == array->data) return NULL;
if (row >= array->nrows) return NULL;
if (col >= array->ncols) return NULL;
size_t index = row * array->ncols col;
return (char*)array->data array->element_size * index;
}
連同通常的 C 風格狂野轉換為您期望的型別。您可以通過對事物具有每個型別的外觀(用于特定型別陣列上的操作的函式指標結構,由一些前處理器宏或其他東西構造)來進一步美化這一點。它仍然看起來很難看,但使用起來可能會更方便一些。
如果您只有固定大小的矩陣,例如在計算機圖形環境中經常使用的 3x3 或 4x4,您可以替代使用第一個給定的 C 版本std::array,從而為您提供不必使用堆和擁有的額外好處與 C 版本相同的快取位置:
#include <array>
template <size_t NROW, size_t NCOL>
using Arr2D_f32 = std::array<std::array<float,NCOL>, NROW>;
// ad lib for other types, e.g.
template <size_t NROW, size_t NCOL>
using Arr2D_f64 = std::array<std::array<double,NCOL>, NROW>;
一旦你有了這些型別,填充它們就很容易了:
void populate_my_array2d(Arr2D_size_t<7,13>& a) {
size_t value = 1;
for (auto& row : a) {
for (auto& col : row) {
col = value ;
}
}
}
在 C 情況下,由于底層存盤只是一個 1d 陣列,因此只需用單個值填充矩陣,您只需要 1 個回圈,而不是 2 個嵌套回圈。這里的一般情況:
#include <stdbool.h>
bool populate_my_array( Arr2D_t * array, const void* value) {
if (NULL == array) return false;
for (size_t r = 0; r < array->nrows; r ) {
for (size_t c = 0; c < array->ncols; c ) {
void* cell = arr2d_at(array,r,c);
if (NULL != cell) {
memcpy(cell,value,array->element_size);
} else {
return false;
}
}
}
return true;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/512402.html
標籤:C 数组嵌入式平台
