Funkce vyššího řádu v LISPu
Funkce vyššího řádu je funkce, která bere jako parametr funkci nebo vrací funkci. Příkladem jsou funkce mapcar a filter
(mapcar (lambda (x) (* x x)) '(1 2 3 4 5))
;; -> (1 4 9 16 25)
(filter (lambda (x) (evenp x)) '(1 2 3 4 5))
;; -> (2 4)
Funkce vyššího řádu v C
Deklarace ukazatele na funkci
Obecná deklarace ukazatele na funkci má tvar:
navratovy_typ (*nazev)(typ1, typ2, ..., typn);
Kde navratovy_typ
je návratový typ funkce a nazev
je název proměnné,
do které budeme funkci ukládat. Pomocí typ1
a další definujeme datové typy parametrů
funkce, pokud funkce nějaké parametry má. Následující proměnná fun
by tak byla deklarace ukazatele na funkci,
která vrací typ double
a bere dva parametry: první typu char*
a druhý typu int
.
int add(int x, int y) {
return x + y;
}
int multiply(int x, int y) {
return x * y;
}
int main() {
// promenna "function" je ukazatelem na fci, ktera
// vraci int a bere dva parametry, oba typu int
int (*function)(int, int) = add;
printf("%i\n", function(10, 20));
function = multiply;
printf("%i\n", function(10, 20));
}
Předání funkce v parametru funkce
int is_small_letter(char letter) {
return letter >= 'a' && letter <= 'z';
}
void print(int (*condition)(char), const char* ret) {
if (condition(ret[0])) {
printf("%s\n", ret);
}
}
int main() {
print(is_small_letter, "ahoj");
print(is_small_letter, "LuSteLa");
}
Pojmenování pomocí typedef
Pomocí typedef
si můžeme vytvořit alias pro ukazatel.
typedef int (*COND)(char);
void print(COND condition, const char* ret) {
if (condition(ret[0])) {
printf("%s\n", ret);
}
}
int main() {
print(is_small_letter, "ahoj");
print(is_small_letter, "LuSteLa");
}
Pole funkcí
Aby vše bylo krášně nepřehledné, tak můžeme ukazatele na funkce uloži do pole
int add(int x, int y) {
return x + y;
}
int multiply(int x, int y) {
return x * y;
}
int main() {
int (*func_array[2])(int, int);
func_array[0] = add;
func_array[1] = multiply;
// Volání fukncí
printf("%i\n", func_array[0](2, 8)); // 10
printf("%i\n", func_array[1](2, 8)); // 16
}
Úkoly
Napište v jazyku C funkci double *map(double (*fce)(double), double *input, int length), která na hodnoty pole vstup
(definiční obor) aplikuje funkci fce a vrátí pole výsledných hodnot. Velikost definičního oboru je specifikována parametrem délka.
Napište v jazyku C funkci double **map(double(*fce[])(double),double *vstup,int pocet_fce, int pocet_vstup), která
na prvky pole vstup (definiční obor) mapuje postupně jednotlivé funkce z pole fce. Z vypočtených hodnot vytvoří dvourozměrné
pole, které bude návratovu hodnotou z této funkce. První řádek výstupního pole bude odpovídat definičnímu oboru, druhý
řádek hodnotám první funkce a tak dále, až poslední řádek bude odpovídat hodnotám poslední předané funkce. Počet funkcí je
specifikován parametrem pocet_fce, velikost definičního oboru pak parametrem pocet_vstup.
Napište v jazyku C funkci double akumulator(double (*fce)(double, double), double cisla[], int pocet), která
zpracuje pomocí předané funkce fce hodnoty z pole cisla, jehož velikost je dána parametrem pocet. Vytvořenou
funkci otestujte ve funkci main; použitými akumulačními funkcemi mohou být například funkce pro součet nebo
součin dvou reálných čísel, které je ovšem pro testování potřeba dodefinovat.