Hledání žáka
Lenka si přišla stěžovat: učitelka jí v první písemce špatně sečetla body. Místo 27 jich má mít 35. Program potřebuje funkci, která žákovi opraví body podle jména. Nejdřív ale musí žáka v poli najít.
Hledání je vzor, který znáte: cyklus prochází žáky, a když najde toho správného, hned vrátí ukazatel na něj (return ukončí i cyklus). Když cyklus doběhne a nikoho nenajde, funkce vrátí NULL, ukazatel, který nikam neukazuje. Jména porovnáte funkcí strcmp z hlavičkového souboru string.h, která pro stejné texty vrátí 0:
#include <stdio.h>
#include <string.h>
typedef struct {
char nazev[20];
int cena;
} Zbozi;
Zbozi *najdi_zbozi(Zbozi polozky[], int pocet, const char nazev[]) {
for (int i = 0; i < pocet; i++) {
if (strcmp(polozky[i].nazev, nazev) == 0) {
return &polozky[i];
}
}
return NULL;
}
int main(void) {
Zbozi obchod[] = {
{"Chléb", 35},
{"Mléko", 24},
};
Zbozi *mleko = najdi_zbozi(obchod, 2, "Mléko");
if (mleko != NULL) {
mleko->cena = 22;
}
printf("Mléko: %d\n", obchod[1].cena);
if (najdi_zbozi(obchod, 2, "Sýr") == NULL) {
printf("Sýr dnes nemáme.\n");
}
return 0;
}Mléko: 22
Sýr dnes nemáme.Funkce vrací &polozky[i], adresu zboží v poli volajícího, ne kopii. Proto změna mleko->cena změnila cenu v poli obchod. Parametr je Zbozi polozky[] bez const, protože se přes vrácený ukazatel zboží mění.
Časté chyby:
zaci[i].jmeno == jmenoneporovnává texty, ale jejich adresy, takže nenajde nikoho. Použijtestrcmp.strcmpvrátí0, když jsou texty stejné, takže podmínka jestrcmp(...) == 0. Bez== 0platí pro každé jiné jméno.- Bez
#include <string.h>překladač ohlásíerror: call to undeclared library function 'strcmp'(volání neznámé knihovní funkce).
A co když učitelka napíše jméno, které v poli není? Třeba Marek chodí do vedlejší třídy. najdi_zaka() vrátí NULL a zápis zak->body[pisemka] přes NULL by program zastavil s chybou RuntimeError: unreachable. Proto oprav_body() ukazatel nejdřív zkontroluje.
Jak psát:
Pokyny
Pod #include <stdio.h> přidejte #include <string.h>. Pak pod funkci pridej_body() napište funkci Zak *najdi_zaka(Zak zaci[], int pocet, const char jmeno[]), která vrátí ukazatel na žáka se jménem jmeno, nebo NULL, když v poli není.
Pod ni napište funkci void oprav_body(Zak zaci[], int pocet, const char jmeno[], int pisemka, int nove_body). Ta najde žáka pomocí najdi_zaka(). Když dostane NULL, vypíše jméno a za ním text ve třídě není. Pro Marka tedy vypíše Marek ve třídě není. Jinak nastaví žákovi body z písemky s indexem pisemka na nove_body.
V main() nad volání vypis_vysledky() opravte Lence první písemku (index 0): oprav_body(zaci, pocet, "Lenka", 0, 35);. Lenka má teď dvojku:
Lenka 35 40 41 38.7 2Pokud má Lenka 27 35 41, použili jste index 1. První písemka má index 0.
Vyzkoušejte jméno, které ve třídě není: pod opravu Lenky přidejte oprav_body(zaci, pocet, "Marek", 0, 40);. Nad výsledky se objeví:
Marek ve třídě není.Začněte programovat zdarma
6/7