C++通过引用传递静态数组和动态数组
C++ Passing Static Array and Dynamic Array By Reference
为了完全理解指针、值和引用是如何工作的,我正在制作一个基本的C++程序,试图篡改一些静态和动态数组,并准确地理解它们应该如何传入。
首先,我生成一个由3个元素组成的静态数组。然后,我将其传递到一个修改所有元素的函数中。然后,我将其传递给另一个具有稍微不同签名的函数,但也可以更改数组的值。
接下来,我生成一个动态大小的数组,通过引用将其传递到一个函数中,以便可以更改这个动态大小数组中的所有值。
代码如下:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
void changeIndexStaticArrayMethod1(int* stat);
void changeIndexStaticArrayMethod2(int (&stat)[3]);
void changeIndexDynamicArrayMethod1(int* dyn, int size);
int main() {
const int MAX = 3;
int arr[MAX] = { 1,2,3 };
changeIndexStaticArrayMethod1(arr);
cout << arr[0] << endl;
cout << arr[1] << endl;
cout << arr[2] << endl;
cout << endl;
changeIndexStaticArrayMethod2(arr);
cout << arr[0] << endl;
cout << arr[1] << endl;
cout << arr[2] << endl;
int SIZE;
cout << "Please choose a size for the array" << endl;
cin >> SIZE;
int *ne = new int[SIZE];
//Build array
for (int i = 0; i < SIZE; i++) {
ne[i] = i;
}
changeIndexDynamicArrayMethod1(ne, SIZE);
for (int i = 0; i < SIZE; i++) {
cout << "ne[" << i << "] = " << ne[i] << endl;
}
//To hang program
cin >> SIZE;
delete[] arr;
delete[] ne;
return 0;
}
void changeIndexStaticArrayMethod1(int* stat) {
stat[0] = 10;
stat[1] = 20;
stat[2] = 30;
}
void changeIndexStaticArrayMethod2(int (&stat)[3]) {
stat[0] = 40;
stat[1] = 50;
stat[2] = 60;
}
void changeIndexDynamicArrayMethod1(int* dyn, int size) {
for (int i = 0; i < size; i++) {
dyn[i] = i * 10;
}
}
上面所有的代码都按照我的意愿工作,我只是有几个问题,为什么(我在其他SO问题上发现了一些通过引用传递数组的方法)。
在changeIndexStaticArrayMethod1()和changeIndexDynamicArrayMethod1()函数中,为什么我们能够使用数组的解引用
*
运算符作为引用?我的下意识反应是,这实际上是通过值传递数组,因为它是解引用运算符。我知道使用数组与使用变量有很大不同,但是,为什么以下内容对单个int
变量无效:void changeStaticNumber(int*num){num=100;}
显然,如果我们使用&num
而不是int* num
,上面的内容会起作用,而且显然我不完全理解指针和数组之间的关系,但我不明白为什么当我们通过引用传递数组时,int* staticArray
是可以的。
如果能对我遇到的这些问题作出任何解释,我将不胜感激。谢谢
为什么我们能够使用数组的deseference*运算符作为引用?
C中的*
有很多含义。它可以表示一元间接("contents of")运算符,也可以表示二进制乘法运算符,还可以表示指针声明。int* stat
是一个指针声明。
由于您没有使用*
来取消引用该函数中指针的内容,所以我不太确定您在问什么。
当您在main()中获取数组的数组名称时,它会"衰减"为指向第一个元素的指针。因此,这些函数的作用是按值获取指针。如果您通过键入*stat = something;
来取消引用指针,则可以访问main中的实际数组。
如果您做一些奇怪的事情,比如更改指针本身,例如stat++;
,那么它不会影响main中使用的地址。您通过值传递了指针本身,因此指针是本地副本。
我的下意识反应是,这实际上是通过值传递数组,因为它是解引用运算符。
在C或C++中,如果不使用肮脏的技巧(将数组存储在结构或类中),就无法真正按值传递数组。例如,如果您的函数被写成void changeIndexStaticArrayMethod1(int stat[3])
,它仍然会给您一个指向第一个元素的指针。它不会按值传递数组,因为语法可能会欺骗你。
为什么以下内容对单个int变量无效:
void changeStaticNumber(int* num){ num = 100; }
因为num
是指针本身,而不是它的内容。为了编写这样的代码,您可以通过引用int& num
来传递变量。在字里行间,这实际上与传递指针是一样的,只是使用了简化的语法。
要更好地理解指针和数组之间的关系,请从阅读整章开始:http://c-faq.com/aryptr/index.html(C和C++在指针方面是相同的)。
让我看看是否可以尝试一下。
指针只是地址持有者。一旦你做了int*ptr=myarray;---在tern中,您要做的是将指针my数组的地址存储到ptr中——数组名称实际上是指向数组中第一个内存位置的指针。您可以使用指针算术来获取其他所有内容,例如myarray+1将指向下一个位置或myarray[1]。
当您需要修改数组时,传递值不是很有用。通过引用传入本质上是制作一个指向数组的指针并将其传递出去。由于像矢量这样的数组是连续的内存块,所以可以很容易地对它们进行索引。
就您的示例而言,void changeStaticNumber(int*num){num=100;}将不起作用,因为您要做的是将100存储到指针的地址中。如果您尊重num并使其无效更改StaticNumber(int*num){*num=100;},它会起作用,因为您实际上更进一步,访问num所指向的数据;num本质上是一样的东西&只是给你一些东西的地址。
例如,如果你想把一个指针指向一个int,你会做的是
int num = 5;
int *ptr = #
此时,ptr在num.中具有相同的地址。要打印出num中的数据或ptr所指向的数据,您需要取消引用或更进一步,因为我喜欢告诉自己并取消引用到这样的cout << *ptr;
在changeIndexStaticArrayMethod1
和changeIndexDynamicArrayMethod1
中,您都没有传递数组,也没有传递引用(只有当参数类型是引用类型时才会发生这种情况,即&
)。该参数的类型为int *
(指向int
的指针)。您正在按值传递指向int
的指针。两个函数中都没有"取消引用运算符"。
ne
已经是int *
了,所以传递它并没有什么特别的。arr
是int [3]
,是一个数组,而不是指针。在C中,当-T
的数组用于期望指向-T
的指针的上下文时,它会隐式转换(无需执行任何操作)为指向其第一个元素的指针。因此,当您执行changeIndexStaticArrayMethod1(arr)
时,编译器会获得一个指向arr
的第一个元素的指针,并将其传递给函数。
[]
运算符处理指针。CCD_ 31总是保证与CCD_ 32相同。在changeIndexStaticArrayMethod1
和changeIndexDynamicArrayMethod1
函数内部,[]
用于使用指向第一个元素的指针来访问后续元素。
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 静态数组的自由动态数组
- 如何在C++函数中声明静态 2D 数组?
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- 基于字节数组生成静态范围整数值
- 如何在C++中删除静态数组?
- 为什么 &a 和 c++ 中的静态数组相同?
- 为什么静态数组成员变量在调用对象的实例后不显示任何内容?
- C++ 返回指向函数内定义的静态数组的指针是否有效?
- 将在堆栈上声明的元素添加到静态数组
- const_cast静态数组以添加恒常性
- C++访问静态 constexpr 数组
- 初始化类中的静态 const 数组 - C++
- 将静态字符数组中的字符分配给动态分配的字符数组 - 访问冲突
- 动态分配的数组和静态数组之间的区别
- 如何在 C++ 中使用 NULL(或 0)初始化静态字符数组
- C++编译时使用 constexpr 字符数组指针分配静态数组?
- 我可以使用 constexpr 函数声明一个静态数组吗?
- 如何在静态函数中使用成员函数数组
- 具有大的2d数组:静态int与int