如何使用int**在C中传递2D数组

如何使用int**在C中传递2D数组,c,C,尝试在我的vscode上使用C语言编写leetcode#497。在编写main()时,我不知道如何处理leetcode提供的int**。是否可以使用int**传递2D数组 #include <stdio.h> #include <stdlib.h> typedef struct { int rectsSize; int * rectsColSize; int** rects; } Solution; int points[

尝试在我的vscode上使用C语言编写leetcode#497。在编写main()时,我不知道如何处理leetcode提供的
int**
。是否可以使用
int**
传递2D数组


#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;
}


#包括
#包括
类型定义结构{
int-rectsize;
int*rectsColSize;
整数**rects;
}解决方案;
整数分[100];
解决方案*解决方案创建(int**rects、int rectsize、int*rectscolize){
溶液*sol=malloc(sizeof(溶液));
sol->rects=rects;
sol->rectsize=rectsize;
sol->rectsColSize=rectsColSize;
//一些代码
}
返回溶胶;
}
int*solutionPick(解决方案*obj,int*retSize){
//一些代码
返回ret;
}
无孔隙溶液(溶液*obj){
免费(obj);
}
内部主(空)
{
int rects[2][4]={{1,1,5,5},{6,6,9,9};
int rectsize=2;
int rectsColSize=4;
整数大小;
解决方案*obj=解决方案创建(RECT、RECTSIZE和rectsColSize);
int*param_1=malloc(sizeof(int));
参数1=解决方案拾取(对象和尺寸);
无溶剂(obj);
返回0;
}

虽然通常有许多不同的方法来处理二维数组,但简单的答案是否定的。C:、等中有很多关于二维数组的信息。原则上,在处理二维数组时,除了左边的第一个维度外,每个维度都需要精确指定。在您的例子中,每个矩形都由4个整数定义,因此,代替<代码> int *> 考虑<代码> INT*(4)Reuts< /Cord>。这使得
rectsColSize
无用,因为现在每个列的大小都是4个整数

只是为了完整性:您尝试的是第二种数组方法,其中每个列都有独立的大小,并且(通常)有额外的malloc调用。虽然这种方法也是有效的,需要
int**
type,但您的任务不需要它。很好地描述了这种差异

编辑 下面是如何在
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*[4]
转换为
int**
,或者更准确地说,将
int*[4]arr2d
的大小
int arr2dSize
转换为结构
解决方案
。在这种情况下,这里是
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);
}
Solution*solutionCreateWrap(int(*arr2d)[4],int arr2dSize){
int*rectsColSize=malloc(arr2dSize*sizeof(int));
int**rects=malloc(arr2dSize*sizeof(int*);
大小\u t arr2dMem=arr2dSize*4*sizeof(int);
rects[0]=malloc(arr2dMem);
memcpy(rects[0],arr2d,arr2dMem);
rectsColSize[0]=4;
对于(大小i=1;irects=rects;
sol->rectsize=rectsize;
sol->rectsColSize=rectsColSize;
//一些代码
}
返回solutionCreate(rects、arr2dSize、rectsColSize);
}
现在对于
int rects[2][4]={{1,1,5,5},{6,6,9,9}
call
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行的指针。知道了这一点,其他一切都是指针算法<代码>矩形[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[i]
替换为
rects[0]+i*4
,我们得到
*((rects[0]+4*i)+j)
,即
rects[0][4*i+j]
。注意最后一个表达式和arr[i*4+j]
之间惊人的相似性<在这种情况下,code>rectsColSize有些多余,但它在通常
int**
数组中是必不可少的,因为每个子数组可能有不同的大小。完成wrap函数后,
rects
arr2d
的精确副本,但其类型适合您的
解决方案
结构,因此我们可以调用
solutionCreate()

我对您的问题所在感到有点困惑。你是在问将
int[][]
传递给需要
int**
的对象是否有效?@DavidSullivan我猜这是无效的,但我想知道leetcode如何使用它来传递数组,因为我想离线测试我的解决方案,所以我需要自己编写main()函数。
int**rects
从技术上讲不是2D数组,即使可以使用2D数组语法(例如,
rects[0][0]
works)。相反,它是一个指针数组。每个指针都指向一个
int
数组。因此,如果想要一个3行5列的数组,首先需要为一个包含三个指针的数组分配内存。然后,对于这三个指针中的每一个,您需要分配一个由五个
int
组成的数组。“是否可以使用int**传递一个2D数组?”-->否。
int**
匹配指向
int*
的指针。使用
int**rects
,在

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);
}