简体   繁体   中英

How to modify an array inside a function in C

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.

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'.

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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM