下面有什么问题
int data[2][2] = { {1,1}, {2,2}};
int sum = sum(data, 2);
Sum定义为
int sum(int **data, int rows);
数据包含data[0]
的地址,因此可以将其视为指针。 *data
引导我到值,这是另一个类型为int
的数组。另一个数组应该被视为指向第一个元素的指针。那么为什么编译器会在int **data
的参数中抱怨?
我收到编译错误,如下所示。我理解错误,但我的问题是为什么**data
不可接受。
error: cannot convert int (*)[2] to int** for argument 1 to int sum(int**, int)
答案 0 :(得分: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)
。
答案 1 :(得分:2)
您应该在参数的定义中包含数组的大小。
int sum(int data[2][2], int rows);
注意:如果它是一个动态数组,那么你之前做的是正确的。
答案 2 :(得分: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;
}
答案 3 :(得分:0)
int ** data
是指向int
的指针。
将数据传递给sums第一个参数实际上只是将int*
传递给它,这与int **
不同。
此外,一旦你进入sum()
,它就不知道int **data
指向一个二维数组,它只知道它是一个指向int
指针的指针。 ..
第一次取消引用数据会为您提供指向int
的指针。
第二次取消引用数据会为您提供int
。
您需要将界面更改为sum()
功能。
答案 4 :(得分:0)
int data [2] [2] //它基本上是4个值的数组。它不是数组的阵列 维度只是解释了编译器如何访问一个值。
假设你有:
data[R][C]
data[X][Y] == *(&data)[X*C + Y]
按照这个解释,你应该定义你的功能:
int sum(int *data, int rows);
如果您想展示它的作用,我可以帮助您正确使用它。
答案 5 :(得分:0)
数组名称到指针的衰减只发生一次,所以你得到一个指针,而不是一个指向指针的指针。
C / C ++数组是数据元素的连续分配。数组数组仍然是一个连续的元素分配 - 只是元素更大。这就是您的错误消息“cannot convert int (*)[2] to int**
”所说的内容。
另一种看待它的方法:双引号只有在指向某处的指针数组时才有效。但是,C / C ++不会为你做这件事;你需要自己分配和填写一个。
int (*)[2]
类型允许您以data[i][j]
的形式访问数组数组。如果要以这种方式访问数组,则需要在任何使用它的地方传播该类型。