如何使用指针表达式访问C中二维数组的元素?

Tud*_*los 37 c pointers multidimensional-array

我知道对于单维数组 x=a[i]来说相当于x=*(a+i),但是如何使用指针访问二维数组的元素呢?

ant*_*ijn 53

简介:如果您将多维数组定义为int [][],则x = y[a][b]相当于x = *((int *)y + a * NUMBER_OF_COLUMNS + b);


无聊细节:

上面的(int *)演员y应该得到一些解释,因为它的必要性可能不是直观的.要了解为什么必须考虑以下因素:

  1. C/C++中的类型指针算术总是通过标量添加/减去/递增/递减时的类型大小(以字节为单位)调整类型指针值(即地址).

  2. 多维数组声明的基本类型(不是元素类型; 变量类型)是比最终维度少一个维度的数组类型.

后者(#2)确实需要一个固化的例子.在下面,变量ar1ar2等效声明.

int ar1[5][5]; // an array of 5 rows of 5 ints.

typedef int Int5Array[5];  // type is an array of 5 ints
Int5Array ar2[5];          // an array of 5 Int5Arrays.
Run Code Online (Sandbox Code Playgroud)

现在是指针运算部分.正如类型结构指针可以按字节结构的大小前进,因此可以跳过数组的完整维度.如果你想到我在上面声明的ar2的多维数组,这更容易理解:

int (*arptr)[5] = ar1; // first row, address of ar1[0][0].
++arptr;               // second row, address of ar[1][0].
Run Code Online (Sandbox Code Playgroud)

所有这一切都消失了:

int *ptr = ar1; // first row, address of ar1[0][0].
++ptr;          // first row, address of ar1[0][1].
Run Code Online (Sandbox Code Playgroud)

因此,在对二维数组执行指针运算时,以下方法无法在多维数组中获取元素[2][2]:

#define NUMBER_OF_COLUMNS   5
int y[5][NUMBER_OF_COLUMNS];
int x = *(y + 2 * NUMBER_OF_COLUMNS + 2); // WRONG
Run Code Online (Sandbox Code Playgroud)

当你记得那y是一个数组数组(声明性地说)时,原因很明显.添加定标器的指针运算(2*5 + 2)y将添加12 ,从而计算和地址等同于&(y[12]),这显然是不正确的,而事实上,要么在编译时抛出一个脂肪警告或彻底失败完全编译.使用强制转换来避免这种情况,(int*)y并且表达式的结果类型基于裸指针到int:

#define NUMBER_OF_COLUMNS   5
int y[5][NUMBER_OF_COLUMNS];
int x = *((int *)y + 2 * NUMBER_OF_COLUMNS + 2); // Right!
Run Code Online (Sandbox Code Playgroud)


tot*_*dli 25

桌子

在C中,2D阵列是连续的一系列线(不像Pascal那样).
当我们创建一个包含4行和5列的整数表时: 一个5*4整数表.

到达元素

我们可以通过以下方式与大家联系:

int element = table[row-1][column-1];
Run Code Online (Sandbox Code Playgroud)

但我们也可以使用以下代码执行此操作:

int element = *(*(table+row-1)+column-1);
Run Code Online (Sandbox Code Playgroud)

在这些例子中row,column从1开始计算,这就是-1的原因.
在以下代码中,您可以测试两种技术是否正确.在这种情况下,我们从0开始计算行和列.

#include <stdio.h>
#include <stdlib.h>
#define HEIGHT 4
#define WIDTH 5

int main()
{
    int table[HEIGHT][WIDTH] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    int row = 2;
    int column = 2;
    int a = *(*(table+row)+column);
    printf("%d\n",a);//13
    printf("%d\n",table[row][column]);//13
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

说明

这是一个双精度算术,所以table指向第一行并*table指向第一个元素,如果你取消它将**table返回第一个元素的值.在以下示例中,您可以看到*tabletable指向相同的内存地址.

printf("%d\n",table);//2293476
printf("%d\n",*table);//2293476
printf("%d\n",**table);//1
Run Code Online (Sandbox Code Playgroud)

在内存中,表的所有行都是相互跟随的.因为table如果我们在表中添加所需元素所在的行号,则指向第一行,我们将获得指向该行的指针.在这种情况下,*(table+row)将包含给定行的第一个元素的地址.现在我们只需添加列号*(table+row)+column,我们就可以得到给定行和列中元素的地址.如果我们取消这个,我们得到这个元素的确切值.
因此,如果我们从零开始计算行和列,我们可以像这样从表中获取元素:

int element = *(*(table+row)+column);
Run Code Online (Sandbox Code Playgroud)

在记忆中

内存中的表.


nbs*_*nbs 19

2D阵列被视为一维阵列的阵列.也就是说,2D阵列中的每一行都是一维阵列.因此给定2D阵列A,

int A[m][n].
Run Code Online (Sandbox Code Playgroud)

一般来说,

A[i][j] = *(A[i]+j) 
Run Code Online (Sandbox Code Playgroud)

A[i] = *(A+i)
Run Code Online (Sandbox Code Playgroud)

所以,

A[i][j] = *(A[i]+j) = * ( *(A+i)+j).
Run Code Online (Sandbox Code Playgroud)

  • Sooo接近一个upvote,但最后一句话太不正确而不能投票.2D数组(`int arr [rows] [cols];`)不要与双指针混淆(`int**pp;`).如果你删除它,我会很高兴upvote. (2认同)

Eri*_*ang 6

之前的答案已经解释得很好,我只会根据我的理解列出指针表达式,并将它们与arr [i] [j]格式进行比较.

Pointer expression of 2-D array:
    the array name itself is a pointer to first sub array,

    arr:
        will be pointer to first sub array, not the first element of first sub 
        array, according to relationship of array & pointer, it also represent 
        the array itself,

    arr+1:
        will be pointer to second sub array, not the second element of first sub 
        array,

    *(arr+1):
        will be pointer to first element of second sub array,
        according to relationship of array & pointer, it also represent second
        sub array, same as arr[1],

    *(arr+1)+2:
        will be pointer to third element of second sub array,

    *(*(arr+1)+2):
        will get value of third element of second sub array,
        same as arr[1][2],

与二维数组类似,多维数组具有相似的表达式.