簡體   English   中英

二維動態數組指針訪問

[英]Two-dimensional dynamic array pointer access

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,但 Microsoft 是一個明顯的例外。

我個人更喜歡使用 wohlstad 的方法,但您也可以可變地修改類型,這是 C11 的可選功能,但可能會在 C2x 中強制執行

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

現在可以像使用具有自動存儲持續時間的普通二維數組一樣使用它。

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("%d\n", p[4][2]);

free(p);

我假設m是列數,而n是行數(如果相反,您可以在我的答案中使用 n 而不是 m )。
為了訪問 2D 數組,您需要 2 個索引 - 我們稱它們為xy
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("%d\t", 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 = %d\n", 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM