Давайте сделаем map
-подобную функцию для C.
void apply(int *arr, size_t len, int (*func)(int))
{
for(size_t i = 0; i < len; i++)
arr[i] = func(arr[i]);
}
Таким образом, мы можем преобразовать функцию, которая работает с целыми числами, для работы с массивами целых чисел. Мы могли бы также сделать аналогичную версию:
void apply_enumerated(int *arr, size_t len, int (*func)(size_t, int))
{
for(size_t i = 0; i < len; i++)
arr[i] = func(i, arr[i]);
}
Это делает то же самое, но позволяет нашей функции знать, на каком элементе она находится. Мы могли бы использовать это, например:
int cube(int i) { return i * i * i }
void print_array(int *array, size_t len, char *sep)
{
if(sep == NULL) sep = ", ";
printf("%d", *array);
for(size_t i = 1; i < len; i++) printf("%s%d", sep, array[i])
}
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
int main(void)
{
int array[5] = { 1, 2, 3, 4, 5 };
print_array(array, ARRAY_SIZE(array), NULL);
apply(array, ARRAY_SIZE(array), cube);
print_array(array, ARRAY_SIZE(array), NULL);
return 0;
}
Этот код напечатает:
1, 2, 3, 4, 5
1, 8, 27, 64, 125
Для нашего примера перечисления:
int mult(size_t i, int j) { return i * j }
// print_array and ARRAY_SIZE as before
int main(void)
{
int array[5] = { 1, 2, 3, 4, 5 };
print_array(array, ARRAY_SIZE(array), NULL);
apply_enumerated(array, ARRAY_SIZE(array), mult);
print_array(array, ARRAY_SIZE(array), NULL);
return 0;
}
Это печатает:
1, 2, 3, 4, 5
0, 2, 6, 12, 20
В качестве более реального примера строковая библиотека может иметь функцию, которая применяет функцию, которая работает с одиночными символами, ко всем символам в строке. Примером таких функций являются функции стандартной библиотеки toupper()
и tolower()
в ctype.h
- мы могли бы использовать эту функцию string_apply()
, чтобы сделать функцию string_toupper()
легкой.