82
#include <iostream>
using namespace std;

void printarray (int arg[], int length) {
    for (int n = 0; n < length; n++) {
        cout << arg[n] << " ";
        cout << "\n";
    }
}

int main ()
{
     int firstarray[] = {5, 10, 15};
     int secondarray[] = {2, 4, 6, 8, 10};
     printarray(firstarray, 3);
     printarray(secondarray, 5);

     return 0;
}

此代码有效,但我想了解数组是如何传递的。

printarray从主函数调用该函数时,将传递数组的名称。数组名是指数组第一个元素的地址。这怎么等同int arg[]

4

5 回答 5

60

语法

int[]

int[X] // Where X is a compile-time positive integer

完全一样

int*

在函数参数列表中时(我省略了可选名称)。

此外,当传递给函数(而不是通过引用传递)时,数组名称衰减为指向第一个元素的指针,因此两者都int firstarray[3]衰减int secondarray[5]int*s。

当您使用相同的索引时,数组取消引用和使用下标语法(下标语法是x[y])的指针取消引用也会产生相同元素的左值。

这三个规则结合起来使代码合法并按您的期望工作;它只是将指针传递给函数,以及在数组衰减到指针后您无法知道的数组长度。

于 2013-01-13T22:49:59.717 回答
23

我只想添加这个,当您访问数组的位置时

arg[n]

是相同的

*(arg + n) than 表示从 de arg 地址开始的 n 的偏移量。

arg[0]也会如此*arg

于 2013-01-13T22:52:58.417 回答
19

这个问题已经得到解答,但我想我会用更精确的术语和对 C++ 标准的引用添加一个答案。

这里发生了两件事,数组参数被调整为指针参数数组参数被转换为指针参数。这是两种完全不同的机制,第一种是对参数实际类型的调整,而另一种是标准转换,它引入了一个指向第一个元素的临时指针。

对函数声明的调整:

dcl.fct#5

在确定每个参数的类型后,将任何类型为“T 数组”(...) 的参数调整为“指向 T 的指针”。

所以int arg[]调整为int* arg

函数参数的转换:

转换数组#1

“NT 数组”或“T 的未知边界数组”类型的左值或右值可以转换为“指向 T 的指针”类型的纯右值。应用临时实现转换。结果是指向数组第一个元素的指针。

所以在 中printarray(firstarray, 3);,“3 int 数组”类型的左值firstarray被转换为“指向 int 的指针”类型的纯右值(临时),指向第一个元素。

于 2018-03-10T22:29:42.290 回答
11

firstarraysecondarray在传递给 . 时转换为指向 int 的指针printarray()

printarray(int arg[], ...)相当于printarray(int *arg, ...)

但是,这并不特定于 C++。C 具有将数组名称传递给函数的相同规则。

于 2013-01-13T22:51:10.853 回答
0

简单的答案是数组总是通过引用传递,而 int arg[] 只是让编译器知道期待一个数组

于 2019-11-24T04:09:25.860 回答