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 == jmeno neporovnává texty, ale jejich adresy, takže nenajde nikoho. Použijte strcmp.
  • strcmp vrátí 0, když jsou texty stejné, takže podmínka je strcmp(...) == 0. Bez == 0 platí 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.

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  2

Pokud 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

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

6/7