Search code examples
carraysparameter-passingfunction-call

Why do C Functions Alter Arrays Automatically?


I'm learning C, and I was just curious as to why C functions, when given arguments like int, char, double etc., don't change the values of those arguments when called, but when they are passed array arguments, they do alter array elements.

For example:

void conversion(int array[])
{
    array[0] = 0;
}

void numeric(int m)
{
    m = 0;
}

When you declare and initialize int array[1] = {1} and int m = 1, call the functions with these arguments, the array[0] gets changed, but the int m does not. Is there a reason that array arguments are changed, but int arguments remain the same? Is it something to do with pointers?


Solution

  • Instead of this function

    void numeric(int m)
    {
        m = 0;
    }
    

    consider the following code snippet

    void numeric(int *m_ptr)
    {
        *m_ptr = 0;
    }
    
    //...
    
    int m = 1;
    
    numeric( &m );
    

    As you can see the variable m will be changed in the function.

    Now let's use the same function with an array

    int m[1] = 1;
    
    numeric( &m[0] );
    

    And in this case the object m[0] will be changed in the function.

    Now this function

    void numeric(int *m_ptr)
    {
        *m_ptr = 0;
    }
    

    can be rewritten like

    void numeric(int m_ptr[])
    {
        *m_ptr = 0;
    }
    

    because a parameter declared as having an array type is adjusted to pointer. For example these function declarations

    void numeric(int m_ptr[1]);
    void numeric(int m_ptr[10]);
    void numeric(int m_ptr[100]);
    void numeric(int m_ptr[]);
    

    are equivalent each other and in turn are equivalent to the function declaration

    void numeric(int *m_ptr);
    

    and declare the same one function. You may include all these declaration in one compilation unit.

    On the other hand an array passed to a function is implicitly converted to pointer to its first element. So the call of the function above

    numeric( &m[0] );
    

    is equivalent to the call

    numeric( m );
    

    Thus then array is used as a parameter and correspondingly as an argument its element can be changed because the elements passed to the function by reference. If you will pass a single object by reference as it is shown in the first code snippet example above then it will be also changed.

    So the difference exists between whether a function accepts an argument by reference or by value. In case when arrays are used then their elements in fact are passed to functions by reference and hence can be changed in the function.