在C++中将数组传递给函数

89
#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[]有什么关系呢?


具体来说,数组的名称指的是数组本身。它可以转换为指向第一个元素的指针,在大多数情况下都是这样处理的。 - Joseph Mansfield
2
我建议将knatten的答案设为被采纳的答案。 - wally
5个回答

65

语法

int[]

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

完全与

int*

在函数参数列表中(我忽略了可选名称)时,数组名会在传递给函数时(未通过引用方式传递)衰减为指向第一个元素的指针,因此 int firstarray [3] int secondarray [5] 都衰减为int *

同时,当你使用相同的索引时,数组解引用和指针解引用的下标语法(下标语法是x [y])都将产生同一元素的左值。

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


4
好的。但是你如何在函数内部访问数组呢?如果你使用 printArray(int* arg),那么你如何在函数体内访问arg? - Gilbert

23

我想补充一点,当你访问数组的位置时,如

arg[n]

*(arg + n) 相同,这意味着从 arg 地址开始偏移 n。

因此,arg[0] 将是 *arg


20
这个问题已经得到了回答,但我想补充一下更精确的术语和对C++标准的引用。这里有两个不同的机制:将数组参数调整为指针参数将数组实参转换为指针实参。第一个是对参数实际类型的调整,而另一个是引入指向第一个元素的临时指针的标准转换。 你的函数声明的调整: 根据dcl.fct#5的规定:
在确定每个参数的类型之后,任何类型为“T的数组”的参数(...)都会被调整为“T的指针”。
因此,int arg [] 被调整为 int* arg将函数实参转换: 根据conv.array#1的规定:
类型为“N T 的数组”或“未知大小的T的数组”的左值或右值可以转换为类型为“T的指针”的prvalue。应用临时材料化转换。结果是指向数组第一个元素的指针。
因此,在printarray(firstarray, 3);中,类型为“三个int的数组”的lvalue firstarray 被转换为类型为“int指针”的prvalue(临时值),指向第一个元素。

如何将指针中的值赋给数组,例如在printArray(int* arr)函数内部将其赋给已定义的另一个数组,例如int myArray[5]。如何执行myArray = arr操作? - Gilbert

11

printarray()函数接收firstarraysecondarray参数时,它们会被转化为指向整型的指针。

printarray(int arg[], ...)printarray(int *arg, ...)等效。

不过这并不只适用于C++,C语言的数组传参规则也是如此。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接