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

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

当心C中的pointer/array world,围绕这一点有很多困惑.


编辑

在这里查看一些其他答案,因为注释字段太短,不能在那里做.人们提出了多种替代方案,但没有展示它们的行为方式.他们是这样做的

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[]T[N]是兼容类型.C++没有compatible types的概念,所以它会拒绝该代码,因为T[]T[10]是不同类型.


以下替代方案根本不起作用,因为当您将数组视为一维数组时,它的元素类型是not 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的警告),如果您无法更改数组类型,这是最后一个保存您的选项:)

C++相关问答推荐

使用指针调用函数并在参数中传递它

将C中的2D char数组写入/读取到二进制文件

这两个具有递归函数和静态变量的 C 程序谁有不同的输出?

在 Macbook M1 上为 Tensorflow 安装 C API

在链表中动态存储数据的问题

libcurl 放置数据流而不是文件

C unsigned long 与转换未正确添加

使用 realloc() 进行无效插入

新手:定义的字符串是否设置为所有 NULL?

我们可以使用变量根据需要给出数组中元素的数量吗?

如何正确解决 C 中的 memset() 函数 MISRA 错误?

指针似乎与 printf 的输出不同步

找到一种在 C 中调用具有不同参数的函数的方法

我怎样才能在另一个宏中使用一个宏来将宏的定义连接到某个东西? C/C++

OpenSSL 3 Diffie-Hellman 密钥交换 C++

编译后的C代码对R'给出了不同的结果;他在用deSolve

为什么快速整数类型比其他整数类型快?

程序是 32 位还是 64 位意味着什么?

C语言中i++和(i)++的区别

C 与 C++ 编译不兼容 - 未命名类型