There are already very informative answers above. I am just sharing a test case in the following in hope that the future readers may find it helpful:
#include <iomanip>
#include <iostream>
#include <vector>
struct MyStruct
{
MyStruct(int val = 1) :dim(val) { c = new double[dim]; }
int a = 0;
double b[3] = { 1,2,3 };
double* c;
std::vector<int> vec_i;
std::vector<double> vec_d;
int get_dim() { return dim; }
private:
int dim;
};
static void test_w_val(MyStruct ms, double arr[5])
{
for (int i = 0; i < 5; i++)
arr[i] = 2 * i + 1;
ms.a = 10;
ms.b[0] = 100;
ms.b[1] = 200;
ms.b[2] = 300;
for (int i = 0; i < ms.get_dim(); i++)
ms.c[i] = 1000 + i;
ms.vec_d.push_back(1e4);
ms.vec_d.push_back(2e4);
ms.vec_i.push_back(50);
ms.vec_i.push_back(60);
}
static void test_w_ref(MyStruct& ms, double (&arr)[5])
{
for (int i = 0; i < 5; i++)
arr[i] = 2 * i + 1;
ms.a = 10;
ms.b[0] = 100;
ms.b[1] = 200;
ms.b[2] = 300;
for (int i = 0; i < ms.get_dim(); i++)
ms.c[i] = 1000 + i;
ms.vec_d.push_back(1e4);
ms.vec_d.push_back(2e4);
ms.vec_i.push_back(50);
ms.vec_i.push_back(60);
}
int main()
{
using std::cout;
using std::endl;
double my_arr1[5] = { 1.,2.,3.,4.,5. }, my_arr2[5] = { 1.,2.,3.,4.,5. };
MyStruct s1(2), s2(2);
#pragma region Prior to calls
cout << "Before calling functions\n";
cout << "Array:\n";
for (int i = 0; i < 5; i++)
cout << my_arr1[i] << " ";
cout << endl;
cout << "Struct:\n";
cout << "dim: " << s1.get_dim() << endl;
cout << "a: " << s1.a << "\n";
cout << "b: ";
for (int i = 0; i < 3; i++)
cout << s1.b[i] << " ";
cout << endl;
cout << "c: ";
for (int i = 0; i < s1.get_dim(); i++)
cout << s1.c[i] << " ";
cout << endl;
cout << "vec_i: ";
for (int i = 0; i < s1.vec_i.size(); i++)
cout << s1.vec_i[i] << " ";
cout << endl;
cout << "vec_d: ";
for (int i = 0; i < s1.vec_d.size(); i++)
cout << s1.vec_d[i] << " ";
cout << endl;
#pragma endregion
#pragma region val.
test_w_val(s1, my_arr1);
cout << "\nTest with Val.\n";
cout << "Array:\n";
for (int i = 0; i < 5; i++)
cout << my_arr1[i] << " ";
cout << endl;
cout << "Struct:\n";
cout << "dim: " << s1.get_dim() << endl;
cout << "a: " << s1.a << "\n";
cout << "b: ";
for (int i = 0; i < 3; i++)
cout << s1.b[i] << " ";
cout << endl;
cout << "c: ";
for (int i = 0; i < s1.get_dim(); i++)
cout << s1.c[i] << " ";
cout << endl;
cout << "vec_i: ";
for (int i = 0; i < s1.vec_i.size(); i++)
cout << s1.vec_i[i] << " ";
cout << endl;
cout << "vec_d: ";
for (int i = 0; i < s1.vec_d.size(); i++)
cout << s1.vec_d[i] << " ";
cout << endl;
#pragma endregion
#pragma region Ref
test_w_ref(s2, my_arr2);
cout << "\nTest with Ref.\n";
cout << "Array:\n";
for (int i = 0; i < 5; i++)
cout << my_arr2[i] << " ";
cout << endl;
cout << "Struct:\n";
cout << "dim: " << s2.get_dim() << endl;
cout << "a: " << s2.a << "\n";
cout << "b: ";
for (int i = 0; i < 3; i++)
cout << s2.b[i] << " ";
cout << endl;
cout << "c: ";
for (int i = 0; i < s2.get_dim(); i++)
cout << s2.c[i] << " ";
cout << endl;
cout << "vec_i: ";
for (int i = 0; i < s2.vec_i.size(); i++)
cout << s2.vec_i[i] << " ";
cout << endl;
cout << "vec_d: ";
for (int i = 0; i < s2.vec_d.size(); i++)
cout << s2.vec_d[i] << " ";
cout << endl;
#pragma endregion
return 0;
}
Here is the output:
Before calling functions
Array:
1 2 3 4 5
Struct:
dim: 2
a: 0
b: 1 2 3
c: -6.27744e+66 -6.27744e+66
vec_i:
vec_d:
Test with Val.
Array:
1 3 5 7 9
Struct:
dim: 2
a: 0
b: 1 2 3
c: 1000 1001
vec_i:
vec_d:
Test with Ref.
Array:
1 3 5 7 9
Struct:
dim: 2
a: 10
b: 100 200 300
c: 1000 1001
vec_i: 50 60
vec_d: 10000 20000
Finally, from this:
The mechanism by which the array is passed into the function (a
pointer to the first element of the array is passed to the function)
functions similarly to pass-by-reference
That is, any changes you make to array within the function mutates the original array even if you don't explicitly pass in a reference to it.
In case, you want to pass an array into a function and protect it from mutations, you may manually make a copy of it and pass the copy to the function. Alternatively, you may use containers wrapping an array, e.g std::array
and std::vector
. [Source]
&
in it). – Euratomstd::vector<int> myVariable
parameter, adding to it inmyFunction
and printing out there, and then printing it inmain
. The modifications will not be reflected inmain
's output. But C++ can be bent beyond these conventions; that's part of its madness and charm. Read up, don't despair! – Nicole