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

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

以下是一个很好的 Select

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次,但如果您使用别名分析和其他激进的优化,一些编译器可能会做出一个可能会 destruct 代码的假设.话虽如此,我从来没有遇到过一个编译器在它上面失败(但话说回来,我没有在实际代码中使用这种技术),甚至C FAQ也包含了这种技术(带有关于其UB’ness的警告),如果您无法更改数组类型,这是最后一个保存您的选项:)

C++相关问答推荐

Mise()在虚拟内存中做什么?

DPDK-DumpCap不捕获端口上的传入数据包

在c++中使用堆栈的有效括号

进程已完成,退出代码为138 Clion

加密解密工作正常,但返回错误0x80090005

在循环中复制与删除相同条件代码的性能

判断X宏的空性

如何在STM8项目中导入STM8S/A标准外设库(ST VisualDeveloper)?

==284==错误:AddressSaniizer:堆栈缓冲区下溢

从C文件中删除注释

致命错误:ASM/rwan ce.h:没有这样的文件或目录.符号链接还不够

在函数外部使用内联ASM时无法指定操作数

Caesar密码调试:输出文本末尾的问号和随机字符

为什么GCC-O1优化破解了这个代码,为了一个GameBoy高级只读存储器而修改了VRAM的循环?

如何将两个uint32_t值交织成一个uint64_t?

如何修复我的qsort()算法?它每次都给出不同的结果

隐藏测试用例无法在c程序中计算位数.

'printf("%s", user_input)' 危险吗?

通过修改c中的合并排序对数组的偶数索引进行排序

C 中从 Unix 纪元时间转换的损坏