В C передача по ссылке означает косвенную передачу объекта через указатель на него. Если вы передадите объект непосредственно в функцию, то функция будет иметь дело с копией значения объекта.
Сравните два вызова функции в этой демонстрационной программе.
#include <stdio.h>
void f( int x )
{
x = 10;
}
void g( int *x )
{
*x = 10;
}
int main(void)
{
int x = 0;
printf( "Before call f: x = %d\n", x );
f( x );
printf( "After call f: x = %d\n", x );
putchar( '\n' );
printf( "Before call g: x = %d\n", x );
g( &x );
printf( "After call g: x = %d\n", x );
return 0;
}
вывод программы
Before call f: x = 0
After call f: x = 0
Before call g: x = 0
After call g: x = 10
То есть мы напрямую передали функции f
объект x
. Таким образом, функция имеет дело с копией объекта x
. Изменение копии не влияет на исходный объект x
, объявленный в main.
Что касается функции g
, то она получает доступ к объекту x
косвенно через указатель на него. Таким образом, изменяя указанный объект, мы изменили объект x
, объявленный в main.
Что касается массивов, то когда массив передается функции, он неявно преобразуется в указатель на свой первый элемент. Таким образом, функция фактически получает элементы массива по ссылке через этот указатель. Используя указатель и арифметику указателя c, мы можем изменить любой элемент массива.
Это объявление функции
void set_array(int array[4]);
эквивалентно следующему объявлению
void set_array(int array[]);
и оба объявления корректируются компилятором в соответствии с объявлением
void set_array(int *array);
Таким образом, функция имеет дело с указателем - указателем на первый элемент массива, используемый в качестве аргумента вызова функции.
Вызов функции set_array в вашей программе
set_array(b);
эквивалентен следующему вызову
set_array( &b[0] );
, поскольку массивы используются в выражениях, например, в качестве аргумента функции выражения неявно преобразуются в указатели на их первые элементы.