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

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

问题描述

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

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.

下面的替代方法根本行不通,因为数组的元素类型,当你把它看成一维数组时,是notuint8_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天全站免登陆