Списки
Для печати элементов списка мы можем написать функцию, проходящую по списку и печатающую каждый элемент; для вычисления длины списка – функцию, проходящую по нему, увеличивая счетчик, и т. д. Альтернативный подход – написать одну функцию, apply, которая проходит по списку и вызывает другую функцию для каждого элемента. Мы можем сделать функцию apply более гибкой, предоставив ей аргумент, который нужно передавать при каждом вызове функции. Таким образом, у apply три аргумента: сам список, функция, которую нужно применить к каждому элементу списка, и аргумент для этой функции:
Второй аргумент apply – указатель на функцию, которая принимает два параметра и возвращает void. Стандартный, хотя и весьма неуклюжий, синтаксис:
* void (*fn)(Nameval*, void*)
Определяет fn как указатель на функцию с возвращаемым значением типа void, то есть как переменную, содержащую адрес функции, которая возвращает void. Функция имеет два параметра – типа Nameval * (элемент списка) и void * (обобщенный указатель на аргумент для этой функции).
Для использования apply, например для вывода элементов списка, мы можем написать тривиальную функцию, параметр которой будет восприниматься как строка форматирования:
Тогда вызывать мы ее будем так:
apply(nvlist, printnv, "%s: %x\n");
Для подсчета количества элементов мы определяем функцию, параметром которой будет указатель на увеличиваемый счетчик:
Вызывается она следующим образом: