这里你想创建一个指向数组第一个元素的指针
uint8_t (*matrix_ptr)[20] = l_matrix;
使用 typedef,这看起来更干净
typedef uint8_t array_of_20_uint8_t[20];
array_of_20_uint8_t *matrix_ptr = l_matrix;
然后你就可以再次享受生活了:)
matrix_ptr[0][1] = ...;
当心指针/数组世界 https://stackoverflow.com/questions/274865/pointer-question-in-c/274943#274943在 C 语言中,围绕这一点有很多混乱。
Edit
在这里查看一些其他答案,因为评论字段太短,无法在那里进行。提出了多种替代方案,但没有显示它们的行为方式。他们是这样做的
uint8_t (*matrix_ptr)[][20] = l_matrix;
如果您修复错误并添加地址运算符&
就像下面的代码片段一样
uint8_t (*matrix_ptr)[][20] = &l_matrix;
然后,它创建一个指向 20 uint8_t 数组类型元素的不完整数组类型的指针。因为指针指向数组的数组,所以必须使用
(*matrix_ptr)[0][1] = ...;
因为它是一个指向不完整数组的指针,所以你cannot作为捷径做
matrix_ptr[0][0][1] = ...;
因为索引需要知道元素类型的大小(索引意味着向指针添加一个整数,因此它不适用于不完整的类型)。请注意,这仅适用于C
, 因为T[]
and T[N]
是兼容类型。 C++没有这个概念兼容类型,所以它会拒绝该代码,因为T[]
and T[10]
是不同的类型。
下面的替代方法根本不起作用,因为当您将数组视为一维数组时,数组的元素类型是not uint8_t
, but uint8_t[20]
uint8_t *matrix_ptr = l_matrix; // fail
以下是一个不错的选择
uint8_t (*matrix_ptr)[10][20] = &l_matrix;
您可以通过以下方式访问它
(*matrix_ptr)[0][1] = ...;
matrix_ptr[0][0][1] = ...; // also possible now
它的优点是保留外部尺寸的大小。所以你可以对其应用 sizeof
sizeof (*matrix_ptr) == sizeof(uint8_t) * 10 * 20
还有另一个答案利用了数组中的项目是连续存储的这一事实
uint8_t *matrix_ptr = l_matrix[0];
现在,形式上只允许您访问二维数组的第一个元素的元素。即,满足以下条件
matrix_ptr[0] = ...; // valid
matrix_ptr[19] = ...; // valid
matrix_ptr[20] = ...; // undefined behavior
matrix_ptr[10*20-1] = ...; // undefined behavior
你会注意到它可能工作到10*20-1
,但是如果您进行别名分析和其他积极的优化,某些编译器可能会做出可能破坏该代码的假设。话虽如此,我从未遇到过失败的编译器(但话又说回来,我没有在实际代码中使用该技术),甚至 C FAQ 也包含该技术(带有关于其 UB'ness 的警告) ),如果您无法更改数组类型,这是拯救您的最后一个选项:)