簡體   English   中英

如何使用三重指針傳遞3D數組?

[英]How to pass 3D arrays using triple pointers?

真的有可能嗎?

我知道如何使用雙指針傳遞二維數組。 根據我的理解,它也應該適用於3-D陣列。 但是我很想被證明是錯誤的。 這個問題肯定會揭示如何解釋數組。

這里的事實是3-D數組是一個連續的塊,而不是較小塊的某些指針數組。

這個程序給我錯誤:

#include <iostream>

using namespace std;

void display(int ***arr, int l, int m, int n)
{
    for(int i=0; i<l; i++)
        for(int j=0; j<m; j++)
            for(int k=0; k<n; k++)
                cout << *(*(*(arr+i)+j)+k) << endl;
}

int main()
{
    int arr[][2][2] = {{{1,2},{3,4}},{{10,20},{30,40}}};
    display((int***)arr,2,2,2);
}

輸出值

test.cpp:17:19: error: cannot convert 'int (*)[2][2]' to 'int***' for argument '1' to 'void display(int***, int, int, int)'
  display(arr,2,2,2);
                   ^

傳遞給雙指針的2D數組我相信我也可以做類似於3D數組的操作,但這太糟糕了,難以閱讀。

#include <iostream>

using namespace std;

void display(int **arr, int m, int n)
{
    for(int i=0; i<m; i++)
        for(int j=0; j<n; j++)
            cout << *(*(arr+i)+j) << " " << arr[i][j] << endl;
}

int main()
{
    int arr[][3] = {{1,2,3},{4,5,6}};
    int *temp[2];
    for(int i=0; i<2; i++)
        temp[i] = *(arr+i);
    display(temp,2,3);
}
OUTPUT
1 1
2 2
3 3
4 4
5 5
6 6

對2D數組所做的操作是正確的,因為您已構建了一個輔助指針數組,並將該指針數組作為int **傳遞。 即使是2D陣列,

void display(int **arr, int m, int n);
...

int arr[][3] = {{1,2,3},{4,5,6}};
display(arr,2,3);            // WRONG! use a 2D array as an array of pointers

會錯的。

而且無論如何,C ++標准對多維數組並不友好:無法編寫傳遞未知維的多維數組的嚴格一致的程序。 許多編譯器都接受它作為擴展,但是它在其他編譯器上可能是不可移植的。

慣用的方法是僅將一維數組用作基礎數據結構,並通過內部進行索引計算來提供將其作為多維容器進行處理的方法。


順便說一句,我試圖構建一個具有任意運行時維度的多維連續容器,同時尊重標准容器的所有約束,並在意識到該標准不允許它之后放棄了:不可能在上面構建一個好的迭代器不擁有自己數據的對象。 這是我最好的嘗試 答案和評論解釋了為什么它沒有希望。

雖然可以像這樣傳遞一維數組

void pass1Darray(int a[])
    {
        statements;
    }

    int main()
    {
        int a[10];
        pass1Darray(a);
    }

實際上,編譯器會將int a[]視為int* a ,這就是人們懷疑是否有可能通過pointer_to_pointer傳遞二維數組的原因。

但這沒有意義!

如果要傳遞2D數組bob[5][10] ,則可以將bob視為一個數組,並且其元素是數組,然后像這樣傳遞它

void pass2Darray( int (*array) [10] )  // it means you pass a pointer which points to a int[10]
{
    statements;
}

int main()
{
    int bob[5][10];
    pass2Darray(bob);
}

這是關於傳遞二維數組。

順便說一句,英語不是我的母語,我也是c ++的初學者。

如果有什么問題,請告訴我,謝謝。

當在本地以int arr[][2][2]聲明數組時,編譯器將實例化一維向量並“記住”偏移量以獲取正確的索引。

此外,本地數組也存儲在堆棧中,如果您需要大型矩陣,則效果不好。 int arr[][2][2]另一個屬性是為什么當您嘗試將其作為參數傳遞給函數時,int arr [] [2] [2] 類型。 您必須指定所有尺寸。

指針的工作方式不同。 如果實例化2D數組,則需要為行分配一個指針數組,並分配每個行數組以分別保存數據。 在C ++中,我認為最好使用標准庫,該庫具有動態指針的標准實現,該指針負責所有分配。 std::vector

結論:

  • 當所需的內存很小並且不需要使用指針時,我將使用局部數組。 如果要避免使用堆,則使用本地數組是不錯的選擇。
  • 允許使用new / delete或malloc / free指針,但我認為最好使用C ++中的標准庫,因此在所有其他情況下我都將使用std :: vector。

我相信我也可以做類似於3D陣列的操作,但這太糟糕了,難以閱讀。

是的,正如nm在他們的評論中解釋的那樣

在2D代碼中,您創建了一個全新的指針數組,將其填充,然后將其傳遞給函數,而不是原始的2D數組。 在您的3D代碼中,您沒有嘗試過任何嘗試。

由於該問題被標記為C ++,因此我們可以使用與C編碼人員不同的工具箱。

在C ++中,不僅可以通過值,還可以通過引用將參數傳遞給函數,並且我們可以編寫模板 ,編譯器可以使用該模板來為使用的類型生成正確的函數。

#include <iostream>
#include <iomanip>

template <class T, size_t L, size_t M, size_t N>
void display( T const (&arr)[L][M][N], int width )
//                    ^^^^^^
{
    for (size_t i = 0; i < L; ++i) {
        for (size_t j = 0; j < M; ++j) {
            for (size_t k = 0; k < N; ++k) {
                std::cout << std::setw(width) << arr[i][j][k];
            }
            std::cout << '\n';
        }
        std::cout << '\n';
    }
}

int main()
{
    int arr[3][2][4] = {
        { {1,2,3,4},
          {5,6,7,8}
        },
        { {10,20,30,40},
          {50,60,70,80}
        },
        { {100,200,300,400},
          {500,600,700,800}
        }
    };

    display(arr, 5);
}

生活, 這里

當然,下一步將是編寫一個封裝多維數組概念的類。

暫無
暫無

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

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