创建指向二维数组的指针 [英] Create a pointer to two-dimensional array

查看:28
本文介绍了创建指向二维数组的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need a pointer to a static 2-dimensional array. How is this done?

static uint8_t l_matrix[10][20];

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

我收到各种错误,例如:

I get all kinds of errors like:

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

推荐答案

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

Here you wanna make a pointer to the first element of the array

uint8_t (*matrix_ptr)[20] = l_matrix;

使用 typedef,这看起来更干净

With typedef, this looks cleaner

typedef uint8_t array_of_20_uint8_t[20];
array_of_20_uint8_t *matrix_ptr = l_matrix;

然后你可以再次享受生活:)

Then you can enjoy life again :)

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

当心 C 中的 指针/数组世界,很多混乱是围绕这个.

Beware of the pointer/array world in C, much confusion is around this.

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

Reviewing some of the other answers here, because the comment fields are too short to do there. Multiple alternatives were proposed, but it wasn't shown how they behave. Here is how they do

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

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

If you fix the error and add the address-of operator & like in the following snippet

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

然后,创建一个指向不完整数组类型的指针,该数组类型为 20 uint8_t.因为指针指向一个数组数组,所以你必须使用

Then that one creates a pointer to an incomplete array type of elements of type array of 20 uint8_t. Because the pointer is to an array of arrays, you have to access it with

(*matrix_ptr)[0][1] = ...;

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

And because it's a pointer to an incomplete array, you cannot do as a shortcut

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

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

Because indexing requires the element type's size to be known (indexing implies an addition of an integer to the pointer, so it won't work with incomplete types). Note that this only works in C, because T[] and T[N] are compatible types. C++ does not have a concept of compatible types, and so it will reject that code, because T[] and T[10] are different types.

下面的替代方法根本行不通,因为数组的元素类型,当你把它看成一维数组时,不是 uint8_t,但是 uint8_t[20]

The following alternative doesn't work at all, because the element type of the array, when you view it as a one-dimensional array, is not uint8_t, but uint8_t[20]

uint8_t *matrix_ptr = l_matrix; // fail

<小时>

以下是一个不错的选择


The following is a good alternative

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

您可以使用

(*matrix_ptr)[0][1] = ...;
matrix_ptr[0][0][1] = ...; // also possible now

它的好处是它保留了外部尺寸的大小.所以你可以在上面应用 sizeof

It has the benefit that it preserves the outer dimension's size. So you can apply sizeof on it

sizeof (*matrix_ptr) == sizeof(uint8_t) * 10 * 20

<小时>

还有另一个答案是利用数组中的项目连续存储这一事实


There is one other answer that makes use of the fact that items in an array are contiguously stored

uint8_t *matrix_ptr = l_matrix[0];

现在,这正式只允许您访问二维数组的第一个元素的元素.即以下条件成立

Now, that formally only allows you to access the elements of the first element of the two dimensional array. That is, the following condition hold

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 的警告),如果你不能改变数组类型,这是最后一个救你的选择:)

You will notice it probably works up to 10*20-1, but if you throw on alias analysis and other aggressive optimizations, some compiler could make an assumption that may break that code. Having said that, i've never encountered a compiler that fails on it (but then again, i've not used that technique in real code), and even the C FAQ has that technique contained (with a warning about its UB'ness), and if you cannot change the array type, this is a last option to save you :)

这篇关于创建指向二维数组的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆