我是C++编程的初学者。我写了一个简单的程序。我定义了一个名为“myFunction”的函数,它得到一个数组及其大小作为输入参数。在函数内部,数组的第一个元素变为100。然而,在主函数中,数组的第一个元素的值发生了变化。为什么会这样?我认为它不应该改变。我知道,在类似的情况下,对于一个int变量,它不会发生。
#include <iostream>
using namespace std;
void myFunction(int a[],int b)
{
a[0] = 100;
}
void myFunction2 (int a)
{
a = a+2;
}
main()
{
int size_of_array = 5;
int myArray[size_of_array] = {7,8,2,3,5};
int c = 2;
myFunction(myArray,5);
myFunction2(c);
cout << myArray[0]<< endl;
cout << c;
}
我期望在调用“myFunction”之后,“myArray”的第一个元素应该是7
2条答案
按热度按时间fhity93d1#
在C中,数组本身不会作为值传递,而是在
main
中作为一系列5个顺序(可能)32位int
值分配。你的
myFunction
函数得到一个 * 指针 *,指向内存块的开始,而不是整个数组的副本。a[0] = 100;
在功能上与*(a + 0) = 100;
相同。您正在取消引用指针并向其赋值。这会更改该地址的内存中的值。此更改反映在main
after you'中。我调用了myFunction
,因为内存地址从未更改。您传递给
myFunction2
的int
值已被复制。在该函数中对a
所做的更改对main
中的c
没有影响。值得注意的是,像你所展示的可变长度数组并不是C标准的一部分。虽然有些编译器可能支持它们,但最好不要依赖这种支持。
编写以下代码并让编译器计算出大小就足够了。
现在,如果我们离开原始数组的领域,开始使用像
std::vector
这样的容器,我们可以通过值或引用传递,如果我们通过值传递,你 * 确实 * 得到了一个副本。输出:
在调用
foo
之后,main
中的v
没有变化。但是因为v
通过引用传递给bar
,所以当我们打印数组时,赋值给它的第一个元素确实会反映在main
中。enyaitl32#
这是C++从C继承的一个糟糕的特性:原始数组不能作为副本传递给函数,尽管有一些语法看起来像是这样。
在C和C++中只是
这就是为什么引入
std::array
的原因之一。它可以像原始数组一样使用,但在用作函数参数时提供了正常规则。一个二个一个一个
为了使混淆更彻底,很可能将指针或对原始数组的引用作为函数参数传递。然而,语法不是很好,特别是指针变体很容易被错误地使用。
在
call_by_pointer
中,(*array)[1]
中的括号对于访问特别重要!这个程序编译没有问题!但是元素访问是错误的。访问操作符
[x]
的优先级高于解引用操作符*
。因此,根据访问内存中元素1的指针算法,地址被提前了两个元素的int
数组的大小,然后被解引用。但是这已经在数组之外了,因此输出内存垃圾。std::array
再次改善了这种情况。参数语法易于阅读,忘记指针变量中的括号将导致编译错误。