【问题标题】:c++ pass array by value or pointer to function syntaxc++ 通过值或指针传递数组到函数语法
【发布时间】:2018-06-04 06:00:06
【问题描述】:
有人能解释一下下面这两个函数声明之间的区别吗?据我所知,aDecay() 将指针作为参数,如果您有整数 int a[5],则可以调用 aDecay(a) 或 aDecay(&a[0],因为数组会衰减为指针。
现在如果我想打电话给pDecay(),我必须使用pDecay(&a)。
pDecay 如何强制您使用&。
void aDecay(int *p)
void pDecay(int (*p)[7])
【问题讨论】:
标签:
c++
arrays
pointers
reference
【解决方案1】:
对于普通的a(或与其相同的&a[0]),您有一个指向数组中单个元素的指针。单个元素的类型为int,因此指向它的指针必须是int*。
如果你有一个指向实际数组的指针,就像你用&a 得到的那样,你不再有一个指向单个int 元素的指针,而是指向整个数组的指针。数组的类型是int[5],指向它的指针是int(*)[5]。
还请注意,在 既不 情况下,您通过值传递 array。你通过值传递一个指针。
【解决方案2】:
这不是指向函数语法的指针,而是指向数组语法的指针。
在第一个示例中,p 是一个指向整数数组的指针。 p[i] 是单个 int。它不能被进一步索引。
在第二个示例中,p 是一个指向由七个整数数组组成的数组的指针。 p[i] 是一个可以进一步索引的数组,即p[i][0] 是有效的。
这是使用第二种方法的示例:
void fill_data(int (*p)[7], size_t n) {
for (size_t i = 0 ; i != n ; i++) {
for (size_t j = 0 ; j != 7 ; j++) {
p[i][j] = (int)(7*i+j);
}
}
}
int main() {
int data[10][7];
fill_data(data, 10);
}
Demo
【解决方案3】:
aDecay 采用指向int 的指针。
int 的数组可以衰减为指向数组第一个元素的指针。
pDecay 接受一个指向由七个ints 组成的数组的指针。
数组不会隐式转换为指向自身的指针。
【解决方案4】:
传递p 会将数组p 转换为指针,而不是将其保留为数组(这称为数组衰减,因为数组衰减为指针)。
传递&p 不会将p 转换为指针,因为它会将指针to p 转换为通用指针,这没什么大不了的,因为它实际上是一个指针。
为什么我们不想将p 转换为指针是因为数组不是只是 指针。如果您认为数组只是指针,请尝试将sizeof(myArray) 与sizeof(myPointer) 进行比较。数组还嵌入了它的大小,而不仅仅是指向第一个元素的指针。
【解决方案5】:
pDecay 如何强制你使用&。
因为数组不会衰减到任何指针。它特别衰减为指向第一个元素的指针。指向int(即int[n])数组第一个元素的指针类型为:指向int(即int*)的指针。
pDecay 的参数是 int (*p)[7],它是一个指向 7 个数组的指针 int。 int* 不能隐式转换为 (int (*p)[7];它们是独立的、不兼容的类型。请注意,pDecay(&a) 也不起作用,因为 &a 的类型是 (int (*p)[5],这也是与 (int (*p)[7] 不同的类型。
pDecay 通常不会强制您使用&。您可以传递一个数组数组,然后将其衰减为指向第一个数组的指针,这是 pDecay 接受的:
int arr[n][7];
pDecay(arr);
有人能解释一下下面这两个函数声明之间的区别吗?
int* 是一个指向int 对象的指针。 int (*p)[7] 是一个指向 int[7] 对象的指针,即 7 个 int 的数组。
【解决方案6】:
首先,您对问题有一个误解:如果a 是一个数组,那么a 始终是指向该数组的指针,即您使用pDecay(a) - 而不是pDecay(&a)。现在,[ ] 是一个取消引用操作,所以如果你说 a[5] - 你取消引用指向 a + 5 * bytes in memory occupied by the array's unit 的指针。因此,a 和 &a[0] 完全相同。 a[5] 和 &(a + 5) 是一样的。
回答您的问题,aDecay(int *p) 接受一个指向整数的指针 - 这里没有要求数组。 int (*p)[7] 是一个由 7 个整数组成的数组,编译器会检查是否是这种情况。