【问题标题】:How can you store a multi-dimensional array in a variable in C?如何将多维数组存储在 C 中的变量中?
【发布时间】:2014-08-10 21:07:39
【问题描述】:

我们有以下两个静态定义的字节数组...

unsigned char pixelBuffer1[32][6] = {/**/};
unsigned char pixelBuffer2[32][6] = {/**/};

我们想将当前缓冲区存储在一个变量中,但我们不确定如何声明它。这就是我们想要做的......

[SOMETYPE] activePixelBuffer;

activeBufferId == getOneOrTwoBasedOnSomeLogic();
activePixelBuffer = (activeBufferId == 1)
    ? pixelBuffer1
    : pixelBuffer2;

activePixelBuffer[17][4] = x;

activeBufferId == getOneOrTwoBasedOnSomeLogic();
activePixelBuffer = (activeBufferId == 1)
    ? pixelBuffer1
    : pixelBuffer2;

activePixelBuffer[23][2] = y;

(请注意,我们在整个代码中重新分配了 activePixelBuffer 的值) 但是,我们不确定要为 [SOMETYPE] 输入什么

我知道如果我们将 pixelBuffer1 或 pixelBuffer2 传递给一个函数,我们会这样定义它...

void someFunc(unsigned char (&myArray)[32][6])
{
    ...
}

...但这似乎不适用于局部变量声明类型。此外,这迫使我们对尺寸进行硬编码,这是可以的,但最好不必这样做。

我们也尝试过使用指针,但数组的二维方面也让我们望而却步。

那么我们使用什么类型呢?

【问题讨论】:

  • unsigned char **myArray 应该可以工作。
  • 使用typedef - 这样的事情会让生活变得更轻松。
  • @LeventeKurusa:不 - 它真的不起作用 - char ** 不等于 char[][]
  • unsigned char (&myArray)[32][6]这不是C++语法吗?
  • 嗯,是的,我不知何故认为它们是字符串...@MarquelV:您也可以尝试将其设为unsigned char *myArray,然后使用 myArray[x + y*WIDTH] 访问它

标签: c arrays types reference


【解决方案1】:

使用typedef

typedef unsigned char PixelBuffer[32][6];      // NB: SPOT principle, aka DRY!

PixelBuffer pixelBuffer1 = { ... };
PixelBuffer pixelBuffer2 = { ... };
PixelBuffer *activePixelBuffer = (activeBufferId == 1) ? &pixelBuffer1 :
                                                         &pixelBuffer2;

(*activePixelBuffer)[17][4] = x;

请注意,除了使语法更简洁之外,这也是 SPOT(单点真理)原则的一个例子,也就是 DRY(不要重复自己)——你的 2D 数组类型应该只定义一次——禁止复制粘贴unsigned char foo[32][6]

【讨论】:

  • 第一行的注释是什么意思? (即 NB:SPOT 等)您确定那里有 PixelBuffer1 而不仅仅是 PixelBuffer?
  • 也是(C/C++ 的新手),但我认为如果您引用一个没有维度的数组,则不需要地址 (&) 运算符,因为无论如何这就是您得到的。 ...或者你是说你想要指向数组的变量的地址而不是数组本身的地址? (我感觉是后者)
  • @MarqueIV: "你确定有 PixelBuffer1 ..." 你是对的,Paul R 偶然发现了臭名昭著的复制/粘贴自己的编程习惯... ;-) 它已被纠正。
  • @MarqueIV:我添加了一段解释 SPOT/DRY 以及为什么这是一个好主意。至于 & 取消引用 - PixelBuffer 是作为二维数组进行类型定义的,activePixelBuffer 是指向 PixelBuffer 的指针,因此在分配给指针时需要 &
  • @MarqueIV:SPOT 也称为 SSOT (en.wikipedia.org/wiki/Single_Source_of_Truth)。为了完整起见,这里也是对 DRY 主体的解释:en.wikipedia.org/wiki/Don%27t_repeat_yourself
【解决方案2】:

对数组的引用在 C++ 中起作用:

int activeBufferId = 1;
unsigned char pixelBuffer1[32][6] = {/**/};
unsigned char pixelBuffer2[32][6] = {/**/};
unsigned char (&activePixelBuffer)[32][6] = (activeBufferId == 1) ? pixelBuffer1 : pixelBuffer2;

activePixelBuffer[17][4] = '*';

在C语言中,你必须使用指针:

unsigned char (*activePixelBuffer)[32][6] = (activeBufferId == 1) ? &pixelBuffer1 : &pixelBuffer2;

(*activePixelBuffer)[17][4] = '*';
activePixelBuffer = &pixelBuffer2; // reassign the pointer to point to the other C-array.

无论如何,为了简化语法和可读性,我建议将此数组移动到struct/class,因此您只需使用类的引用/指针。

typedef struct PixelData { unsigned char buffer[32][6] } PixelData;

PixelData pixelData1 = {/**/};
PixelData pixelData2 = {/**/};
PixelData *activePixelData = (activeBufferId == 1) ? &pixelData1 : &pixelData2;

【讨论】:

  • 好的,但是在您的 C++ 答案中,您以后如何重新分配 activePixelBuffer? (我正在更新我的问题,因为根据你的回答,我显然不清楚我们在追求什么。)
  • 作为任何引用,您不能重新分配引用(指向其他变量)。当您希望能够指向其他变量时,您必须使用指针。
  • 只需做activePixelBuffer = &pixelBuffer2;
  • 我打算为您的彻底性和您的最后一个答案给出答案,这几乎是我们想要的,但不得不给另一个答案,因为他们也是使用 typedef 但不需要使用结构来实现相同的目的。不过,只是想让你知道你的答案也很好。
猜你喜欢
  • 2015-12-08
  • 1970-01-01
  • 2021-03-27
  • 2020-08-13
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
  • 2018-03-05
相关资源
最近更新 更多