创建指向二维数组的指针

标签 c arrays pointers

我需要一个指向静态二维数组的指针。这是怎么做到的?

static uint8_t l_matrix[10][20];

void test(){
   uint8_t **matrix_ptr = l_matrix; //wrong idea 
}

我遇到各种错误,例如:

  • 警告:来自不兼容指针类型的赋值
  • 下标值既不是数组也不是指针
  • 错误:灵活数组成员的使用无效

最佳答案

这里你想创建一个指向数组第一个元素的指针

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] = ...;

当心pointer/array world在 C 语言中,对此有很多困惑。


编辑

在此处查看其他一些答案,因为评论字段太短而无法在此处进行。提出了多种替代方案,但没有显示它们的行为方式。这是他们的做法

uint8_t (*matrix_ptr)[][20] = l_matrix;

如果您修复错误并添加地址运算符 &,如下面的代码片段

uint8_t (*matrix_ptr)[][20] = &l_matrix;

然后,它创建了一个指向 20 uint8_t 类型数组元素的不完整数组类型的指针。因为指针指向数组的数组,所以您必须使用

访问它
(*matrix_ptr)[0][1] = ...;

因为它是一个指向不完整数组的指针,所以您不能作为快捷方式来做

matrix_ptr[0][0][1] = ...;

因为索引需要知道元素类型的大小(索引意味着向指针添加一个整数,所以它不适用于不完整的类型)。请注意,这仅适用于 C,因为 T[]T[N] 是兼容类型。 C++ 没有兼容类型 的概念,因此它会拒绝该代码,因为T[]T[10] 是不同的类型。


以下替代方案根本不起作用,因为数组的元素类型,当您将其视为一维数组时,不是 uint8_t,但是 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 的警告), 如果你不能改变数组类型,这是最后一个拯救你的选择:)

关于创建指向二维数组的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1052818/

相关文章:

c - 将 int[][] 形式的变量传递给 int 类型的方法**

c - 给定一条编码消息,计算它可以被解码的方式的数量

java - 将 PriorityQueue 转换为排序数组的最佳方法

arrays - 将数据打印到 TableView 时出现问题(Swift)

c - C语言中初始化数组的方法

C While 循环显示 Max 和 Min 并以 0 结尾,但我不想考虑 0

c - 为 'struct ** record' 的属性赋值

c - 链表实现内存分配

c - 返回全局字符串变量的地址

C- 找到我打开的文本文件的当前行