簡體   English   中英

如何使用 int** 在 C 中傳遞二維數組

[英]How can I use int** to pass a 2D array in C

嘗試在我的 vscode 上使用 C 語言處理 leetcode #497。 在編寫 main() 時,我不確定如何處理 leetcode 提供的int** 是否可以使用int**傳遞二維數組?


#include <stdio.h>
#include <stdlib.h>


typedef struct {
    
    int rectsSize;
    int * rectsColSize;
    int** rects;    
} Solution;

int points[100];

Solution* solutionCreate(int** rects, int rectsSize, int* rectsColSize) {
    
    Solution* sol = malloc(sizeof(Solution));
    sol->rects = rects;
    sol->rectsSize = rectsSize;
    sol->rectsColSize = rectsColSize;
    //some codes
    }
    return sol;
}

int* solutionPick(Solution* obj, int* retSize) {
    //some codes
    return ret;
}

void solutionFree(Solution* obj) {
    free(obj);
}

int main(void)
{
    int rects[2][4] = {{1, 1, 5, 5}, {6, 6, 9, 9}};
    int rectsSize = 2;
    int rectsColSize = 4;
    int retSize;
    Solution* obj = solutionCreate(rects, rectsSize, &rectsColSize);
    int* param_1 = malloc(sizeof(int));
    param_1 = solutionPick(obj, &retSize);
    solutionFree(obj);
    return 0;
}

雖然通常有許多不同的方法來處理二維數組,但簡單的答案是否定的。 C中有很多關於二維數組的信息: 1 , 2 , 3等。原則上,在處理二維數組時,除了左邊的第一個維度之外的每個維度都需要精確指定。 在您的情況下,每個矩形都由 4 個整數定義,因此int** rects考慮int*[4] rects 這使得rectsColSize無用,因為現在每列都有 4 個整數的常量大小。

只是為了完整性:您想要做的是數組的第二種方法,其中每列都有獨立的大小,以及(通常)額外的 malloc 調用。 雖然這種方法也有效並且需要int**類型,但您的任務不需要它。 很好地描述了這里的差異。

編輯

以下是遍歷2d數組的方法:

#define col 4
void print_2d(int (*a)[col], int aSize){
    for(size_t i = 0; i < aSize; i++){
        for(size_t j = 0; j < col; j++){
            printf("%d ", a[i][j]);
        }
    printf("\n");
    }
}

這里是int**

void print_pp(int** a, int aSize, int* aiSize){
    for(size_t i = 0; i < aSize; i++){
        for(size_t j = 0; j < aiSize[i]; j++){
            printf("%d ", a[i][j]);
        }
    printf("\n");
    }
}

看來你要轉換int*[4]int** ,或者更准確地說, int*[4] arr2d它的大小int arr2dSize來構建Solution 在這種情況下,這里是solutionCreate包裝器。

Solution* solutionCreateWrap(int (*arr2d)[4], int arr2dSize) {
    int* rectsColSize = malloc(arr2dSize * sizeof(int));
    int** rects = malloc(arr2dSize * sizeof(int*));
    size_t arr2dMem = arr2dSize * 4 * sizeof(int);
    rects[0] = malloc(arr2dMem);
    memcpy(rects[0], arr2d, arr2dMem);
    rectsColSize[0] = 4;
    for(size_t i = 1; i < arr2dSize; i++){
        rects[i] = rects[0] + i*4;
        rectsColSize[i] = 4;
    }
    sol->rects = rects;
    sol->rectsSize = rectsSize;
    sol->rectsColSize = rectsColSize;
    //some codes
    }
    return solutionCreate(rects, arr2dSize, rectsColSize);
}

現在對於int rects[2][4] = {{1, 1, 5, 5}, {6, 6, 9, 9}}; 調用solutionCreateWrap(rects, 2)將返回初始化結構Solution 它看起來很可怕,它的細節更糟糕,所以如果它有效,你可以跳過解釋。 理解低級 C 細節不一定要寫在里面,而且這個(或任何其他)解釋不可能涵蓋這個問題,所以不要氣餒,如果你不明白這一切。

arr2darr2dSize*4整數的連續內存塊。 當乘以sizeof(int)我們得到大小(以字節為單位)——我的代碼中的arr2dMem 聲明int (*arr2d)[4]意味着arr2dint*[4]類型。 知道這一點,我們可以將它轉換為int*像這樣: int* arr = (int*)arr2d和表達式arr2d[i][j]被翻譯為arr[i*4+j]

rects的翻譯如下; int**是指針數組,因此每個rect[i]都必須是指向arr2d的第 i 行的arr2d 知道了這一點,其他一切都是指針算術。 rects[0] = malloc(arr2dMem); memcpy(rects[0], arr2d, arr2dMem); 將整個arr2d復制到rect[0] ,然后每個下一個rects[i] = rects[0] + i*4; 向前移動 4 個整數。 因為rectint**類型,表達式rects[i][j]轉換為*(rects[i]+j) ,並用rects[0] + i*4替換rects[i] ,我們得到*((rects[0] + 4*i)+j) ,即rects[0][4*i+j] 請注意最后一個表達式和arr[i*4+j]之間驚人的相似性。 在這種情況下, rectsColSize有點多余,但在一般int**數組中它是必不可少的,因為每個子數組都可能具有不同的大小。 完成 wrap 函數后, rectsarr2d精確副本,但類型適合您的Solution結構,因此我們可以調用solutionCreate()

暫無
暫無

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

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