**运算符不能作为参数在二维数组上运行

时间:2014-07-20 14:31:04

标签: c++ c parameter-passing

我搜索并发现如何在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++))打印出每个元素。

为什么只有一个*在此代码中运行良好?而不是**

4 个答案:

答案 0 :(得分:4)

作为函数参数传递的数组不会调整到第一个维度之外的指针。您需要将函数标题更改为:

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()分配的内存很重要。否则,您将创建memory leak。为此,您可以使用free()

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

free(arr);

注意

我回答C的原因是因为在我看来,这就是你所使用的。在C ++中,malloc()的使用不起作用,因为你需要在那里进行显式转换,并且没有C / C ++之类的语言,它们几乎兼容,但不完全兼容。

答案 1 :(得分:2)

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

答案 2 :(得分:1)

如果您有阵列

int arr[3][3];

将其传递给函数意味着第一个维度“衰减”到指针。它只是衰变的第一个维度,因此您需要int **arr(指向3个元素的数组的指针),而不是int (*arr)[3](指向指针的指针或指针数组)。 ,或数组数组,每个数组包含3个元素。)

你可以在其他地方阅读更多内容(我有一个冗长的答案here,它描述了更多,而Question 6.18 of the comp.lang.c FAQ甚至更好),但了解数组/数组之间的区别很重要到数组和指针数组/指针到指针。

答案 3 :(得分:0)

数组不是指针!

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


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

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


但是如果我们有int arr[2][2],那么arr表示内存中有四个连续的int,它会降级为指向第一个元素的指针(因此它的类型为int (*)[2]):< / p>

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