C语言 二维动态数组指针访问


p = (int *)malloc(m * n * sizeof(int));

如果我使用p作为二维动态数组,我如何访问里面的元素?

如果你可以依靠你的C实现来支持可变长度数组(一个可选的特性),那么一个相当好的方法是将p声明为指向(可变长度)数组的指针,而不是指向int的指针:

int (*p)[n] = malloc(m * sizeof(*p));  // m rows, n columns

然后使用普通的双索引访问元素,就像声明了一个普通的2D数组一样:

p[0][0] = 1;
p[m-1][n-1] = 42;
int q = p[2][1];

大多数广泛使用的C实现都支持vla,但微软的是一个明显的例外。

我个人更喜欢使用wohlstad的方法,但您也可以对类型进行变量修改,这是C11的可选功能,但可能在C2x中是强制的:

int (*p)[m] = malloc(n * sizeof *p);

现在可以像一个普通的2d数组一样使用,具有自动存储时间。

int n = 12, m = 9;
int (*p)[m] = malloc(n * sizeof *p);
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
p[i][j] = i * m + j;

printf("%dn", p[4][2]);
free(p);

我假设m为列数,n行数(如果答案相反,你可以用n代替m)
为了访问二维数组,您需要两个索引-让我们将它们称为xandy:
x索引将在0范围内。m - 1
y索引将在0的范围内。n - 1

你可以用下面的方法计算p数组的索引:

int p_idx = y * m + x

然后你可以访问你的数组元素,例如:

p[p_idx] = 111;   // set an element value
int a = p[p_idx]; // get an element value

不能将p用作二维数组。它是一个整型指针。二维(动态分配)意味着嵌套指针。但是,您可以以"扁平化"方式表示二维数组。的形式。下面的一些代码可能会提供一个有用的解释:

#include <stdio.h>
#include <stdlib.h>
int main(){
// Populating a 10x5 matrix
int m = 10;
int n = 5;
int* p = (int*) malloc(m*n*sizeof(int));

for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
// Each row has n elements; to get the
// "flattened" index, treating the MxN
// matrix as row-major ordered (reading
// left-to-right, and THEN down the rows):
int flattened_index = (i * n) + j;
// E.g., populate with multiplication table data
p[flattened_index] = (i + 1) * (j + 1);
printf("%dt", p[flattened_index]);
}
printf("n");
}
// Inversely, to convert a flattened index to a
// row and column, you have to use modulus
// arithmetic
int flattened_index = 21;
int row = flattened_index / n; // Rounded-down integer division
int column = flattened_index % n; // Remainder after division

printf("%d * %d = %dn", row + 1, column + 1, p[flattened_index]);
return 0;
}

这个输出:

1   2   3   4   5   
2   4   6   8   10  
3   6   9   12  15  
4   8   12  16  20  
5   10  15  20  25  
6   12  18  24  30  
7   14  21  28  35  
8   16  24  32  40  
9   18  27  36  45  
10  20  30  40  50  
5 * 2 = 10

您实际上正在创建一个单维数组。但是,我们仍然可以用它来保存一个矩阵,考虑到在C语言中一个多维数组,例如int mat[m][n],本身就存储在连续内存中。

#include <iostream>
int main()
{
int m, n;
std::cin >> m >> n;
int* mat_ptr = (int*)malloc(m * n * sizeof(int));
if (mat_ptr)
{
for (int row = 0; row < m; ++row)
{
for (int col = 0; col < n; ++col)
{
*(mat_ptr + ((row * n) + col)) = (row * n) + col;
}
}
for (int row = 0; row < m; ++row)
{
for (int col = 0; col < n; ++col)
{
std::cout << *(mat_ptr + ((row * n) + col)) << " ";
}
std::cout << std::endl;
}
}
return 0;
}

最新更新