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

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

问题描述

我需要一个指针的静态2维阵列。如何做到这一点?

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 ++不具备的兼容类型的的概念,因此它会拒绝code,因为 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

它有它preserves外部尺寸大小的好处。所以,你可以把它应用的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 ,但如果你扔在别名分析和其他激进的优化,一些编译器可以作出一个假设,即可能打破code。话虽如此,我从来没有遇到一个编译器,它失败(但话又说回来,我没有用在真正的code,它的技术),甚至Ç常见问题有包含该技术(一个有关它的警告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天全站免登陆