In C arguments passed to functions by coping their values.
Consider for example
#include <stdio.h>
void f( int x )
{
x += 10;
printf( "Inside f x = %d\n", x );
}
int main(void)
{
int x = 5;
printf( "Before call of f x = %d\n", x );
f( x );
printf( "After call of f x = %d\n", x );
}
The program output is
Before call of f x = 5
Inside f x = 15
After call of f x = 5
That is the function deals with a copy of the value of the original variable x. The original variable x itself is not changed.
Now consider a modified program
#include <stdio.h>
void f( int *px )
{
*px += 10;
printf( "Inside f x = %d\n", *px );
}
int main(void)
{
int x = 5;
printf( "Before call of f x = %d\n", x );
f( &x );
printf( "After call of f x = %d\n", x );
}
The program output is
Before call of f x = 5
Inside f x = 15
After call of f x = 15
In this case the argument is passed by reference that is the function gets the address of the original variable x and consequently it changes the variable.
Arrays could be also passed by value as arguments to functions. That is functions could deal with copies of arrays. But creating a copy of a whole array is a very expensive and time-consuming operation.
So in C when an array is passed to a function then its designator is implicitly converted to pointer to its first element. And correspondingly the parameter is adjusted to pointer.
For example these function declarations are equivalent and declare the same one function
void f( int a[] );
void f( int a[10] );
void f( int a[100] );
void f( int *a );
Thus the elements of the array in fact are passed by reference. You can change any element of an array the same way as it is shown in the second demonstrative program in my post.
For example
#include <stdio.h>
void f( int *a, size_t n )
{
for ( size_t i = 0; i < n; i++ ) *( a + i ) = i;
printf( "Inside f array a is " );
for ( size_t i = 0; i < n; i++ ) printf( "%d ", *( a + i ) );
printf( "\n" );
}
int main(void)
{
int a[] = { 0, 0, 0, 0, 0 };
const size_t N = sizeof( a ) / sizeof( *a );
printf( "Before call of f array a is " );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", *( a + i ) );
printf( "\n" );
f( a, N );
printf( "After call of f array a is" );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", *( a + i ) );
printf( "\n" );
}
The program output is
Before call of f array a is 0 0 0 0 0
Inside f array a is 0 1 2 3 4
After call of f array a is0 1 2 3 4
%s.