1

下面有什么问题

int data[2][2] = { {1,1}, {2,2}};
int sum = sum(data, 2);

总和定义为

int sum(int **data, int rows);

data 包含 的地址data[0],因此可以将其视为指针。将*data我引向值,它是另一个类型的数组int。这个另一个数组应该被视为指向第一个元素的指针。因此,为什么编译器会抱怨 int 的参数**data

我收到如下所示的编译器错误。我理解这个错误,但我的问题是为什么**data不可接受。

error: cannot convert int (*)[2] to int** for argument 1 to int sum(int**, int)
4

6 回答 6

3

无论数组是一维还是多维,都只能转换为指向第一个元素的指针,而不能转换为指向指针数组的指针。

要了解原因,请分析数组在内存中的布局方式。

int data[3]
0.......4.......8...... (assume sizeof(int)==4)
data[0] data[1] data[2]
^ &data[0]

int data[3][2]
0..........4..........8..........12.........16.........20........
data[0][0] data[0][1] data[1][0] data[1][1] data[2][0] data[2][1]
^ &data[0][0]

所有元素总是线性布局,因此每个数组(一维或多维)都可以表示为指向第一个元素 ( arr[0][0]...[0]) 的指针,只有这样。多维数组不能表示为指向指针数组的指针,因为这些指针数组在任何地方都不存在。

维度只是用于转换为地址(arr[i][j]变成*(array_memory + i*H + j))的编译时提示。指向指针的指针与数组的结构完全不同;索引它在语法上看起来相同,但它会导致完全不同的事情发生(ppi[i][j]变成*(*(ppi + i) + j).

于 2012-05-22T13:33:58.177 回答
2

您应该在参数定义中包含数组的大小。

    int sum(int data[2][2], int rows);

注意:如果它是一个动态数组,那么你之前所做的就是对的。

于 2012-05-22T13:27:50.570 回答
1

可能这有帮助:

int sum(int *i, int rows) {
    cout << *i << *(i+1) << *(i+2) << *(i+3);
    return 0;
}

int main() {
    int data[2][2] = { {1,1}, {2,2}};
    int sum1 = sum(data[0], 2);

    return 0;
}
于 2012-05-22T13:40:02.420 回答
0

int ** data是一个指向一个指针的指针int

将数据传递给 sums 第一个参数实际上只是将 a 传递int*给它,这与int **.

此外,一旦您进入sum(),它不知道int **data指向二维数组,它只知道它是指向指向int...的指针的指针

第一次取消引用数据会给你一个指向int. 第二次取消引用数据会为您提供int.

您需要将接口更改为sum()函数。

于 2012-05-22T13:33:48.153 回答
0

int data[2][2] // 它基本上是 4 个值的数组。它不是数组数组。
维度只是解释编译器如何访问一个值。

假设你有:

data[R][C]  
data[X][Y] == *(&data)[X*C + Y]  

按照这个解释,你应该定义你的功能:

int sum(int *data, int rows);

如果你想展示它的作用,我可以帮助你正确使用它。

于 2012-05-22T13:33:59.257 回答
0

数组名到指针的衰减只发生一次,所以你得到的是一个指针,而不是一个指向指针的指针。

AC/C++ 数组是数据元素的连续分配。数组数组仍然是元素的连续分配——只是元素更大。这就是您的错误消息“ cannot convert int (*)[2] to int**”所说的。

另一种看待它的方式:双重取消引用仅在它指向某处的指针数组时才有效。但是,C/C++ 不会为您做到这一点。您需要自己分配和填写一份。

int (*)[2]类型允许您以data[i][j]. 如果您想以这种方式访问​​数组,则需要将该类型传播到任何使用它的地方。

于 2012-05-22T16:09:13.503 回答