Вывод самой длиной строки

K&R (41-43). В книге в данном разделе опущен момент о том, как происходит обмен данными между функциями (хотя оговаривается перед этим об особенностях передачи массивов в качестве аргументов). Все переменные локальные и поэтому с первого взгляда не понятно, почему функция getline() меняет значение переменной line в функции main(), а copy() - значение longest. Массивы в качестве аргументов передаются не по значению. Переменные в getline() и copy() получают ссылки на массивы, определенные в main(), а не содержимое этих массивов.

#include <stdio.h>
#define MAXLINE 1000
 
/* Не надо использовать getline, иначе будет сообщение о
несовпадении типов. Видимо getline определена в stdio */
int getline2 (char s[], int lim);
void copy(char to[], char from[]);
 
main () {
	int len; // длина текущей строки
	int max; // максимальная длина
	char line[MAXLINE]; // текущая строка
	char longest[MAXLINE]; // самая длиная строка
 
	max = 0; // сначала макс.длина равна нулю
	/* Пока длина строки больше 0 вызывать getline2, передавать
	ей в качестве аргументов массив символов для строки и 
	максимально возможную длину строки. getline2 возвращает
	целое число, которое записывается в len, а также по ходу
	выполнения заполняет массив line. */
	while ((len = getline2(line, MAXLINE)) > 0)
		/* copy будет вызываться только, если длина 
		текущей строки больше значения в max */
		if (len > max) {
			max = len;
			/* copy передается массив символов самой
			длиной строки до этого и текущая строка */ 
			copy (longest, line);
		}
	if (max > 0)
		printf("%s", longest);
	return 0;
}
 
int getline2 (char s[], int lim) {
	int c, i; // символ и счетчик массива
 
	/* Происходит заполнение массива символами текущей строки до тех
	пор, пока не будет превышен лимит, встречен конец файла или 
	конец строки. i - счетчик, который после каждой итерации цикла 
	указывает на следующий элемент массива */
	for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
		s[i] = c; // c - это введенный очередной символ
	/* Если цикл for был прерван из-за конца строки, то
	записать символ конца строки в массив. */
	if (c == '\n') {
		s[i] = c;
		++i; // индекс надо увеличить для записи \0
	}
	s[i] = '\0'; // обозначение конца строки в языке Си
	return i; // длина строки
}
 
/* Переменная to связана с longest. Массивы в качестве аргументов
передаются по ссылке, а не по значению. В результате происходит
изменение longest. from связана с line. */
void copy (char to[], char from[]) {
	int i;
 
	i = 0;
	/* Происходит перезапись и дозаполнение  to до тех пор, 
	пока в from не встретится символ конца строки. Перед этим он
	также копируется в to. */
	while ((to[i] = from[i]) != '\0')
		++i;
}

Создано