1

Let's consider the following example :

#include <stdio.h>

void change_byte(int *byte);

int main()
{
    int byte = 0;
    change_byte(&byte);
    printf("Byte : %d \r\n", byte);
}

void change_byte(int *byte)
{
    *byte= 5;
}

I am simply changing the value of an integer inside a function by passing the integer as a pointer to the function. It yields :

Byte : 5

Everything's fine.


I want to generalize the function to modify an array of integer instead of an integer. Here is the code :

#include <stdio.h>
#define SIZE_ARRAY 10

void change_array(int *array, int size);

int main()
{
    int array[SIZE_ARRAY] = {0};
    change_array(array, SIZE_ARRAY);
    
    printf("Array : ");
    for(int i = 0 ; i < SIZE_ARRAY ; i++)
    {
        printf("%d ", array[i]);
    }
}

void change_array(int *array, int size)
{
    for(int i = 0 ; i < size ; i++)
    {
        array[i] = 5;
    }
}

It yields :

Array : 5 5 5 5 5 5 5 5 5 5 

I like it because it does not make use of dynamic allocation, but I have trouble understand how it works. From what I understand, array gets converted into a pointer when entering the function change_array. But when I was changing the value of byte in the previous example, I was doing *byte = 5. Here, I am doing array[i] = 5 and not *array[i] = 5.


Finally, I want to change the previous example to modify array based on a global array :

#include <stdio.h>
#define SIZE_ARRAY 10

int global_array[10] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};

void change_array(int *array, int size);

int main()
{
    int array[SIZE_ARRAY] = {0};
    change_array(array, SIZE_ARRAY);
    
    printf("Array : ");
    for(int i = 0 ; i < SIZE_ARRAY ; i++)
    {
        printf("%d ", array[i]);
    }
}

void change_array(int *array, int size)
{
    array = global_array;
}

It yields :

Array : 0 0 0 0 0 0 0 0 0 0   

Why is it so ? What to I need to change to make it work ?

Thanks.

  • 1
    A few links that provide basic discussions of pointers may help. [Difference between char *pp and (char*) p?](https://stackoverflow.com/a/60519053/3422102) and [Pointer to pointer of structs indexing out of bounds(?)...](https://stackoverflow.com/a/60639540/3422102) (ignore the titles, the answers discuss pointer basics) For your last example: `array = global_array;` Arrays are NOT assignaable. (not an lvalue), You are assigning the address of `global_array` to the local pointer `array` which goes out of scope when the function returns. – David C. Rankin Mar 30 '21 at 07:05
  • Of possible interest: Difference Between `*(Pointer + Index)` and `Pointer[]` [here](https://stackoverflow.com/questions/4622461/difference-between-pointer-index-and-pointer). Your `*array[i] = 5` is incorrect. – Weather Vane Mar 30 '21 at 07:07
  • `*byte` is the same as `byte[0]`, likewise `a[0]` is the same as `*a` ... and, generally, `a[i]` is the same as `*(a + i)`. These are just different ways to write **the same thing**. – pmg Mar 30 '21 at 07:45
  • All of these questions can and should be answered by reading a C programming book. You aren't doing yourself a favour fiddling around with trial & error without understanding what you are doing. – Lundin Mar 30 '21 at 07:46

2 Answers2

0

For a better understanding (and exercise), edit your function

void change_array(int *array, int size)
{
    array = global_array;
}

to

void change_array(int *array, int size)
{
    array = global_array;
    for (int i=0; i < size; ++i)
        printf("%d ", array[i]);
}

Ask yourself, what the output 'means'.

Erdal Küçük
  • 4,810
  • 1
  • 6
  • 11
0

Consider your first program.

#include <stdio.h>

void change_byte(int *byte);

int main()
{
    int byte = 0;
    change_byte(&byte);
    printf("Byte : %d \r\n", byte);
}

void change_byte(int *byte)
{
    *byte= 5;
}

In this program the object byte is passed to the function change_byte by reference through a pointer to it

change_byte(&byte);

In C passing by reference means passing an object indirectly through a pointer tp it.

So dereferencing the pointer byte declared as a function parameter

void change_byte(int *byte);

you get a direct access to the pointed object byte of the type int defined in main.

Now let's consider your second program

#include <stdio.h>
#define SIZE_ARRAY 10

void change_array(int *array, int size);

int main()
{
    int array[SIZE_ARRAY] = {0};
    change_array(array, SIZE_ARRAY);
    
    printf("Array : ");
    for(int i = 0 ; i < SIZE_ARRAY ; i++)
    {
        printf("%d ", array[i]);
    }
}

void change_array(int *array, int size)
{
    for(int i = 0 ; i < size ; i++)
    {
        array[i] = 5;
    }
}

In main you declared an integer array

int array[SIZE_ARRAY] = {0};

Array designators used in expressions with rare exceptions are converted to pointers to their first elements.

Thus this call

change_array(array, SIZE_ARRAY);

is equivalent to

change_array( &array[0], SIZE_ARRAY);

So dereferencing the pointer within the function you can change the first element of the array defined in main.

But array elements are stored in a continuous extent of memory. So using the pointer arithmetic and having a pointer to the first element of an array you can access all elements of the array.

In fact all elements of the array array are passed to the function change_array by reference through a pointer to the first element of the array.

For example the for loop within the function you could rewrite like

    for(int i = 0 ; i < size ; i++)
    {
        *( array + i ) = 5;
    }

Now let's consider your third program.

#include <stdio.h>
#define SIZE_ARRAY 10

int global_array[10] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};

void change_array(int *array, int size);

int main()
{
    int array[SIZE_ARRAY] = {0};
    change_array(array, SIZE_ARRAY);
    
    printf("Array : ");
    for(int i = 0 ; i < SIZE_ARRAY ; i++)
    {
        printf("%d ", array[i]);
    }
}

void change_array(int *array, int size)
{
    array = global_array;
}

As it was pointed out already the array array passed to the function change_array is converted to a pointer to its first element.

You may imagine the function call and its definition the following way (I will rename the first function parameter that to avoid name ambiguity).

change_array(array, SIZE_ARRAY);

//...

void change_array( /* int *parm_array, int size */)
{
    int * parm_array = array;
    int size = SIZE_ARRAY;

    parm_array = global_array;
}

That is function parameters are its local variables. The parameter parm_array is alive until the function stops its execution.

Thus this statement

    parm_array = global_array;

assign the pointer to the first element of the global array global_array to the local variable parm_array of the function. This assignment does not touch in any way the array array defined in main. It only changes the local variable parm_array declared in the function change_array.

To achieve the expected by you result you could define in main a pointer that is initialized by the array array. And in the function change_array you could reassigned the pointer with the array global_array passing it to the function by reference the same way as you passed the object byte in your first program.

Here is a demonstrative program.

#include <stdio.h>
#define SIZE_ARRAY 10

int global_array[10] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};

void change_array( int **array_ptr );

int main()
{
    int array[SIZE_ARRAY] = {0};
    int *array_ptr = array;
    
    change_array( &array_ptr );
    
    printf("Array : ");
    for(int i = 0 ; i < SIZE_ARRAY ; i++)
    {
        printf("%d ", array_ptr[i]);
    }
}

void change_array( int **array_ptr )
{
    *array_ptr = global_array;
}

The program output is'

Array : 5 5 5 5 5 5 5 5 5 5 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335