В языке C все аргументы функций передаются по значению.

По необходимости, можно сделать так, чтобы функция модифицировала переменные в вызывающем модуле программы. Для этого взывающая функция должна передать адрес переменной (в понятиях C - указатель на переменную), а вызываемая - объявить параметр указателем и обращаться к переменной косвенно, по ссылке через указатель. Если же, имя массива используется в качестве аргумента, то передаваемое в функцию значение как раз и является местонахождением (адресом) начала массива. Копирования элементов массива не происходит.

#include <stdio.h>

/* Прототип функции power (возведение в степень) */
int power(int, int);

/* С функции main начинает выполняться программа */
int main()
{
  /* значения 2 и i используемые при вызове функции power(2, i) -
  аргументы, передаваемые в функцию */
  for(int i = 0; i <= 10; ++i)
    printf("2 ** %d = %d\n", i, power(2, i));
  return 0;  // Нормальное завершение программы
}

/* Определение функции power (возведение в степень).
   По стандарту ANSI C
*/
int power(int base, int n)
{
  /* переменные base и n - параметры функции power */
  /* переменные p - локальные параметры функции power */
  int p;
  for(p = 1; n > 0; --n)
    p = p * base;
  return p; // Возвращаемое функцией значение
}

Лист. 1.

gcc -o 1.8_arguments 1.8_arguments.c

Лист. 2.

./1.8_arguments

2 ** 0 = 1
2 ** 1 = 2
2 ** 2 = 4
2 ** 3 = 8
2 ** 4 = 16
2 ** 5 = 32
2 ** 6 = 64
2 ** 7 = 128
2 ** 8 = 256
2 ** 9 = 512
2 ** 10 = 1024

Лист. 3.

Литература: Брайн Керниган, Деннис Ритчи "Язык программирования C (ANSI C)"