0

I don't get it why you can alter the values inside the array, without using a reference or a pointer (&, *), I'm a freshmen student, and I don't know the reason behind, I hope someone can provide a logical answer, please refer to the code below, Thank You in Advance.

#include <iostream> 

using namespace std;

void a(int x[]){
    for(int i = 0; i < 5; i++){
        x[i] += 2;
    }
}
int main(){
    
    int x[5] = {1,2,3,4,5};
    a(x);
    for(auto b : x){
        cout << b << " ";
    }
    
    return 0;
}

3 Answers3

2

A function parameter is never an array in C++. When you declare a function parameter as an array, it is automatically adjusted to be a pointer to element of such array. These declarations are effectively identical:

void a(int x[]);     // looks like an array of int of unknown bound
void a(int* x);      // declaration above is adjusted to this
void a(int x[1234]); // the size is ignored completely

An array implicitly converts to a pointer to the first element of the array (such conversion is called decay). Hence, you can call the function that doesn't accept an array parameter by passing an array argument:

int* ptr1 = x;     // implicit conversion
int* ptr2 = &x[0]; // same conversion explicitly
a(x);              // same conversion happens here

These two rules (function parameter adjustment and array to pointer decay) make it so that what syntactically looks like passing arrays by value, is actually done using indirection. Within the function, you modify the elements by indirecting through the pointer parameter that points to the array that exists outside of the function.


Important note: The adjustment of array to pointer in function parameter does not apply in other contexts. Arrays and pointers are distinct types with different properties.

Another note: The adjustment does not apply to parts of compound types. For example, a function parameter of type "pointer to array" will not be adjusted to be "pointer to pointer" and "reference to array" will not be adjusted to be "reference to pointer".

eerorika
  • 232,697
  • 12
  • 197
  • 326
1

Beacuse

 void a(int x[]){

is the same as

 void a(int *x){

and so you are using a pointer


Why?

Because an array like

 int x[10];

'decays' to a pointer when passed to a function (and in other places). This can be very confusing but at the same time is very flexible

It mens that I can have a function like strlen that can accpet a 'real' array, or a pointer. These 'strings'

char *s1 = malloc(10);
strcpy(s1, "hello");
char s2[] = "hello";
char *s3 = "hello"; 

store their data in different ways but all can be handled by

size_t strlen(const char *s);

note that this is exactly the same as

 size_t strlen(const char s[]);

they are 2 different ways of writing the same thing. Personal preference is for the second type if its really is an 'array' vs a pointer to maybe an array.

One issue with this 'decay' is that inside strlen (or any pointer/array accepting function) it is impossible to 'know' the length just from the parameter. The compiler knows that the size of s2 is 6 but this information is not carried forward to the function.

Regularly SO sees this

  void my_func(int *arr){
      int len = sizeof(arr)/sizeof(arr[0]);
      ....
  }
  int a[10];
  my_func(a);

This will give len = 1 or 2 (depending on 32 or 64 bit machine), never 10

The flexibility costs a litle power

pm100
  • 48,078
  • 23
  • 82
  • 145
  • Why is it the same? Because the language is just dumb like that, basically. One of those weird language rules. – user253751 Mar 22 '22 at 16:41
1

The parameter having the array type in this function declaration

void a(int x[]){

is adjusted by the compiler to pointer type to array elements type. That is the above declaration is equivalent to

void a(int *x){

In this call of the function

 a(x);

the array designator is implicitly converted to pointer to its first element. That is the call is equivalent to

 a( &x[0]);

So within the function you have a pointer to the first element of the array declared in main.

Using the pointer arithmetic you can access elements of the array. That is the elements of the array are passed to the function by reference in the C meaning indirectly through a pointer to them.

Within the function the variable x has the type int *. And this expression statement

x[i] += 2;

is equivalent to

*( x + i ) += 2;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335