C语言指针和多维数组

可以将多维数组的一部分看做子数组。比如说,二维数组的每一行都可以当做一维数组。这种行为会对我们用指针处理多维数组有所影响。

为了说明这种行为,我们创建一个二维数组并初始化,如下所示:

int matrix[2][5] = {{1,2,3,4,5},{6,7,8,9,10}};

然后打印元素的地址和值:

for(int i=0; i<2; i++) {
    for(int j=0; j<5; j++) {
        printf("matrix[%d][%d] Address: %p Value: %d\n",
                    i, j, &matrix[i][j], matrix[i][j]);
    }
}

输出如下所示:

matrix[0][0] Address: 100 Value: 1
matrix[0][1] Address: 104 Value: 2
matrix[0][2] Address: 108 Value: 3
matrix[0][3] Address: 112 Value: 4
matrix[0][4] Address: 116 Value: 5
matrix[1][0] Address: 120 Value: 6
matrix[1][1] Address: 124 Value: 7
matrix[1][2] Address: 128 Value: 8
matrix[1][3] Address: 132 Value: 9
matrix[1][4] Address: 136 Value: 10

数组按行–列顺序存储,也就是说,将第一行按顺序存入内存,后面紧接着第二行。内存分配如下图所示。

二维数组的内存分配

我们可以声明一个指针处理这个数组,如下所示:

int (*pmatrix)[5] = matrix;

(*pmatrix)表达式声明了一个数组指针,上面的整条声明语句将pmatrix定义为一个指向二维数组的指针,该二维数组的元素类型是整数,每行有5个元素。如果我们把括号去掉就声明了5个元素的数组,数组元素的类型是整数指针。如果声明的列数不是5,用该指针访问数组的结果则是不可预期的。

如果要用指针表示法访问第二个元素(就是2),下面的代码看似合理:

printf("%p\n", matrix);
printf("%p\n", matrix + 1);

但输出却是:

100
120

matrix+1返回的地址不是从数组开头偏移了4,而是偏移了第一行的长度,20字节。用matrix本身返回数组第一个元素的地址,二维数组是数组的数组,所以我们得到是一个拥有5个元素的整数数组的地址,它的长度是20。我们可以用下面的语句验证这一点,它会打印出20:

printf("%d\n",sizeof(matrix[0])); // 显示20

要访问数组的第二个元素,需要给数组的第一行加上1,像这样:*(matrix[0] + 1)。表达式matrix[0]返回数组第一行第一个元素的地址,这个地址是一个整数数组的地址,于是,给它加1实际加上的是一个整数的长度,得到的是第二个元素。输出结果是104和2。

printf("%p %d\n", matrix[0] + 1, *(matrix[0] + 1));

我们可以用图文的形式来说明数组,如图4-11所示。

二维数组图示

上图可以解释二维数组表示法。

二维数组表示法

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程