1
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

void func(int arr[5], int n1, int n2)
{   
    cout << "INSIDE func()" << endl;
    arr[0]++, arr[3]++;
    for(int i = 0; i < 5; i++)
    {
        cout << arr[i] << ' ';
    }
    cout << endl;
    n1++, n2++;
    cout << n1 << ' ' << n2 << endl;
}

int main()
{
    int a = 3, b = 4;
    int arr[5] = {0,0,0,0,0};
    
    func(arr,a,b);
    cout << "INSIDE main()" << endl;
    for(int i = 0; i < 5; i++)
    {
        cout << arr[i] << ' ';
    }
    cout << endl;
    cout << a << ' ' << b << endl;

    return(0);
}

So, why does arr[5] changes it's values in func() function, but variables a,b don't. Why does that happen? I know that to a,b change it's values i have to pass the reference of variables a , b to function func().

F.e:
fill(int arr[5], int &n1, int &n2)
{
   /* code */
}

But why don't we pass arrays to functions in the same way?

OUTPUT:

INSIDE func()
1 0 0 1 0
4 5
INSIDE main()
1 0 0 1 0
3 4
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
fonabyatzz
  • 41
  • 5
  • Because you're passing a copy of `a` and `b` and not the original variables `a` and `b`. Note also that you're passing an `int*` by value as the first argument. – Jason Jun 22 '22 at 11:36
  • 1
    Because those are C arrays which not only can't be directly copied but also when declared as parameters silently became pointers. When using C++ I suggest to use `std::array` when possible instead. – AnArrayOfFunctions Jun 22 '22 at 11:39
  • Thanks, that explains about everything – fonabyatzz Jun 22 '22 at 11:41

3 Answers3

1

When you pass a built-in type (such as int, double) by value to a function, the function gets a copy of that value, so change to the copy in side the function makes no change to the original.

But (built-in) array is special in C/C++. When you pass a built-in array name, you are actually passing a pointer (by value) to the first element in the array. So inside the function, indirect access via the pointer can change the original array's elements.

Peng
  • 1,393
  • 13
  • 19
1

why does arr[5] changes it's values in func() function, but variables a,b don't.

Because you're passing the variables by value. This means that you're passing a copy of the variables instead of the original objects themselves which in turn means that whatever changes you make to a and b won't be reflected back in the original objects inside main.

The reason the array elements are changing their value is because you've passed a pointer to an int as the first argument. And that pointer points to the first element of the original array. This is because the first parameter named arr is actually of type int* and is not an array.

//-------------vvv--------->note arr is an int*
void func(int* arr, int n1, int n2) //equivalent to what you wrote
{
  //other code here
}

Jason
  • 36,170
  • 5
  • 26
  • 60
1

This function declaration

void func(int arr[5], int n1, int n2);

is adjusted by the compiler to the declaration

void func(int *arr, int n1, int n2);

That is parameters having array types are adjusted by the compiler to pointers to array element types.

On the other hand, this call

 func(arr,a,b);

is equivalent to the call

 func( &arr[0], a, b );

That is the array designator arr used as the function argument is implicitly converted to a pointer to its first element.

So in fact elements of the array are passed to the function through a pointer to them because using the pointer arithmetic and dereferencing pointer expressions the function has a direct access to elements of the array. For example these expressions

arr[0]++, arr[3]++;

by the definition are equivalent to

( *( arr + 0 ) )++, ( *( arr + 3 ) )++;

As for the variables a and b then the function deals with copies of the values of these variables. If you want to get the same effect as with elements of the array you should define the function like

void func(int arr[5], int *n1, int *n2)
{   
    cout << "INSIDE func()" << endl;
    arr[0]++, arr[3]++;
    for(int i = 0; i < 5; i++)
    {
        cout << arr[i] << ' ';
    }
    cout << endl;
    ( *n1 )++, ( *n2 )++;
    cout << *n1 << ' ' << *n2 << endl;
}

and call it like

 func( arr, &a, &b );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335