Prázdný ukazatel
Někdy ukazatel nemá na co ukazovat. Představte si funkci, která v poli teplot hledá první mráz, tedy teplotu pod nulou, a vrátí adresu prvku, ve kterém ho našla. Co má vrátit, když celý týden nemrzlo? K tomu má jazyk C hodnotu NULL, prázdný ukazatel: ukazatel, který nikam neukazuje.
Tato funkce vrací adresu, a proto má návratový typ int *. &cisla[i] je adresa prvku s indexem i:
int *najdi_zaporne(int *cisla, int pocet) {
for (int i = 0; i < pocet; i++) {
if (cisla[i] < 0) {
return &cisla[i];
}
}
return NULL;
}Proč funkce vrací adresu, a ne rovnou teplotu? Číslem nejde říct „žádný není“: jakékoli číslo, které by funkce vrátila, by mohlo být skutečnou teplotou. Ukazatel to umí, protože NULL není adresa žádné proměnné.
Ukazatel, který může být NULL, před použitím zkontrolujte podmínkou:
#include <stdio.h>
int *najdi_zaporne(int *cisla, int pocet) {
for (int i = 0; i < pocet; i++) {
if (cisla[i] < 0) {
return &cisla[i];
}
}
return NULL;
}
int main(void) {
int tyden[] = {3, 1, -2, 0, -4};
int *mraz = najdi_zaporne(tyden, 5);
if (mraz != NULL) {
printf("První mráz: %d\n", *mraz);
} else {
printf("Žádný mráz\n");
}
return 0;
}Tento kód vypíše:
První mráz: -2Proč kontrolovat? Číst nebo zapisovat přes NULL je chyba, protože tam žádná proměnná není. Na počítači takový program obvykle spadne, často s hláškou Segmentation fault. Tady v prohlížeči čtení přes NULL zastaví program chybou RuntimeError: unreachable, stejnou jako u indexu za koncem pole. Ta neříká, co se pokazilo, a tak když ji uvidíte v programu s ukazateli, hledejte ukazatel, který může být NULL.
NULL je také dobrá počáteční hodnota pro ukazatel, který zatím nemá na co ukazovat: int *nalezeno = NULL;. Ukazatel bez hodnoty, int *p;, tady způsobí chybu při překladu, jakmile ho použijete (variable 'p' is uninitialized when used here), stejně jako každá jiná proměnná bez hodnoty.
Ještě jedno pravidlo pro funkce, které vracejí ukazatel: vracejte jen adresy věcí, které existují i po skončení funkce, třeba prvků pole, které funkce dostala. Lokální proměnné funkce po jejím skončení zaniknou, a proto jejich adresy nikdy nevracejte.
Jak psát:
Pokyny
V poli sedadla je 1 obsazené sedadlo a 0 volné. Program se nepřeloží: když není volné žádné sedadlo, funkce najdi_volne_misto skončí bez return. Doplňte na její konec, za cyklus, return NULL;. Program pak dvakrát vypíše Rezervováno.
Do kina přichází třetí divák. V main zavolejte rezervuj(sedadla, 4); potřetí. Program dvakrát vypíše Rezervováno a pak skončí chybou RuntimeError: unreachable: řada je plná, funkce najdi_volne_misto vrátila NULL a funkce rezervuj se přes něj pokusila zapisovat. Opravte funkci rezervuj: když je misto rovno NULL, vypíše Vyprodáno a nic nezmění, jinak sedadlo rezervuje jako dosud. Program vypíše Rezervováno, Rezervováno a Vyprodáno.
Začněte programovat zdarma
9/11