В языке C параметры в функции всегда передаются по значению — то есть копия значения из вызывающего кода передаётся в функцию. Если требуется изменить значение переменной вне функции, используют передачу по указателю.
При передаче скаляра (например, int) функция получает свою копию:
void foo(int a) { a = 10; } int main() { int x = 5; foo(x); // x == 5, не изменится! }
Для изменения значения переменной используют указатель:
void foo(int* a) { *a = 10; } int main() { int x = 5; foo(&x); // x == 10, значение изменилось! }
Является ли массив параметром функции, передаваемым по ссылке?
Многие отвечают, что "по ссылке", однако в C массив в сигнатуре функции не может быть передан по ссылке, фактически он деградирует в указатель.
Правильный ответ:
Когда массив передаётся в функцию, фактически передаётся указатель на его первый элемент. То есть вызываемая функция не знает реального размера массива, а любые изменения элементов массива отражаются на оригинальном массиве.
void foo(int arr[]) { arr[0] = 100; } int main() { int a[3] = {1,2,3}; foo(a); // a[0] будет 100! }
История
int arr[10], но в вызывающем коде массив был меньшего размера. Из-за того, что функция не знала фактический размер, произошло переполнение буфера и повреждение памяти.