**运算符不能将二维数组作为参数

**operator does not work on 2-dimensional array as parameter

本文关键字:参数 运算符 不能 二维数组      更新时间:2023-10-16

我搜索并发现'如何在c/c++中使用2d数组作为参数',但我遇到了奇怪的事情。

void print2darr3 (int row, int column, int **arr){
    int i,j;
    for( i = 0; i<row ;i++ ){
            for( j=0 ; j<column ;j++ ){
                printf("%d ", **(arr++))  ;    //printf("%d ", *(arr++)); WORKS WELL.
            }
            printf("n");
    }
}
int main(void){
   int arr[3][3] = {
                        {10,20,30},
                        {40,50,60},
                        {70,80,90}
                    };
    print2darr3(3,3, arr);
return 0;
}

这是我写的。我希望输出如下

10 20 30
40 50 60
70 80 90

但是我的代码不工作。

令人惊讶的是,当我在第5行更改代码printf("%d ", * (arr++));而不是printf("%d ", ** (arr++));时,它运行良好。

我不明白这种情况。

因为arr[3][3]是二维数组,所以我写了int **arr作为参数

因此,我使用printf("%d ", **(arr++))打印出每个元素。

为什么只有一个*在这段代码中工作得很好?而不是** ?

作为函数参数传递的数组不能调整为第一维以外的指针。您需要将函数头更改为:

void print2darr3 (int col, int *arr[3]); // removed row because it is known to be 3.

如果您希望函数更通用,并适用于指针到指针到int(或int**)类型,则需要动态创建数组。这是用C中的malloc()/free()和c++中的new/delete完成的。从技术上讲,您可以在c++中使用malloc(),但强烈建议这样做。

(C,而不是c++) :

int 
    nrows = 3, 
    ncols = 3;
int **arr = malloc(nrows * sizeof(int*));
int i;
for(i = 0; i < nrows; ++i) {
    arr[i] = malloc(ncols * sizeof(int));
}
// now you can use the arr as a 2D array in your original function
print2darr3(nrows, ncols, arr);

编辑

正如@Neil在评论中指出的那样,释放用malloc()分配的内存是很重要的。否则,您将创建内存泄漏。为了做到这一点,您可以使用free() .

for(i = 0; i < nrows; ++i) {
    free(arr[i]);
}
free(arr);

注意

我选C的原因是因为在我看来你用的是C。在c++中,malloc()的这种使用将不起作用,因为您需要在那里进行显式强制转换,并且没有C/c++这样的语言,它们几乎兼容,但不是完全兼容。

c++解决方案(已标记)

void print2darr3 (const vector<vector<int>>& arr){
    int i,j;
    for( i = 0; i<arr.size() ;i++ ){
            for( j=0 ; j<arr[i].size() ;j++ ){
                printf("%d ", arr[i][j]) 
            }
            printf("n");
    }
}
int main(void){
vector<vector<int>> arr = {
                    {10,20,30},
                    {40,50,60},
                    {70,80,90}
                };
print2darr3(arr);
}

如果你有一个数组

int arr[3][3];

传递给函数意味着第一个维度"衰减"为指针。它只是第一个维度会衰减,所以你想要的参数不是int **arr(指向指针的指针,或者指针的数组),而是int (*arr)[3](指向包含3个元素的数组的指针,或者数组的数组,每个数组包含3个元素)。

您可以在其他地方阅读更多内容(我在这里有一个很长的答案,描述了更多内容,comp.lang.c FAQ的问题6.18甚至更好),但是理解数组的数组/指针到数组的数组和指针的数组/指针到指针的数组之间的区别是很重要的。

数组不是指针!

它们恰好被自动降级为指向第一个元素的指针。


例如,如果我们有int arr[2],那么arr在内存中表示两个连续的整数,并且它被降级为指向第一个元素的指针(因此它的类型为int*):

         arr ---+        +--- arr + 1
                v        v
memory: ... | arr[0] | arr[1] | ...


但是如果我们有int arr[2][2],那么arr代表内存中四个连续的整数,它被降级为指向第一个元素的指针(所以它的类型是int (*)[2]):

           arr ---+            arr + 1 ---+
                  v                       v
memory: ... | arr[0][0] | arr[0][1] | arr[1][0] | arr[1][1] | ...


另一方面,如果我们有int *(arr[2])(为了清晰起见添加了括号),那么arr表示内存中两个连续int指针的数组,并且它被降级为指向第一个元素的指针(因此它的类型为int**):

         arr ---+        +--- arr + 1
                v        v
memory: ... | arr[0] | arr[1] | ...
                |        |     
           ... -+        +- ...



在您的示例中,print2darr3期望类似于第三个示例的内容,但您给它的是类似于第二个示例的内容。

你可以选择:

#include <stdio.h>
void print2darr3(int rows, int columns, int *arr) {
    int i,j;
    for (i = 0; i < rows ; i++) {
        for (j = 0; j < columns; j++) {
            printf("%d ", arr[i * columns + j]);
        }
        printf("n");
    }
}
int main(void) {
    int linear_array[3][3] = {
        {10,20,30},
        {40,50,60},
        {70,80,90},
    };
    print2darr3(3, 3, (int*)linear_array);
    return 0;
}


或:

#include <stdio.h>
void print2darr3(int rows, int columns, int **arr) {
    int i,j;
    for (i = 0; i < rows ; i++) {
        for (j = 0; j < columns; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("n");
    }
}
int main(void) {
    int linear_array[3][3] = {
        {10,20,30},
        {40,50,60},
        {70,80,90},
    };
    int *pointer_array[3] = {
        (int*)(linear_array + 0),
        (int*)(linear_array + 1),
        (int*)(linear_array + 2),
    };
    print2darr3(3, 3, pointer_array);
    return 0;
}


同样,在C(但不是c++)中,你可以这样做:

#include <stdio.h>
void print2darr3(int rows, int columns, int arr[rows][columns]) {
    int i,j;
    for (i = 0; i < rows ; i++) {
        for (j = 0; j < columns; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("n");
    }
}
int main(void) {
    int linear_array[3][3] = {
        {10,20,30},
        {40,50,60},
        {70,80,90},
    };
    print2darr3(3, 3, linear_array);
    return 0;
}