[英]In C/C++: How can i implement a 2D int array using two single pointers (no use of **int)?
[英]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 細節不一定要寫在里面,而且這個(或任何其他)解釋不可能涵蓋這個問題,所以不要氣餒,如果你不明白這一切。
arr2d
是arr2dSize*4
整數的連續內存塊。 當乘以sizeof(int)
我們得到大小(以字節為單位)——我的代碼中的arr2dMem
。 聲明int (*arr2d)[4]
意味着arr2d
是int*[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 個整數。 因為rect
是int**
類型,表達式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 函數后, rects
是arr2d
精確副本,但類型適合您的Solution
結構,因此我們可以調用solutionCreate()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.