6. Ukazovatele a funkcie

6.2 Parametre volané odkazom (referenciou)

Ak chceme vo funkcii zmeniť hodnotu skutočného parametra, musíme použiť volanie odkazom. Ale ako, veď sme ešte pred chvíľou tvrdili, že v C volanie odkazom ako také neexistuje? To je pravda. Tento problém vyriešime pomocou pointerov.

 Volanie odkazom v jazyku C nie je v skutočnosti volanie odkazom, tak ako to poznáme z Pascalu, keď sa formálny parameter označí kľúčovým slovom var. V tomto prípade kompilátor zaistí, že sa pri volaní podprogramu do zásobníku odovzdá adresa premennej (adresa skutočného parametra), ktorá má byť zmenená. Vo funkcii (procedúre) sa potom s formálnym parametrom pracuje bežným spôsobom – teda bez akýchkoľvek trikov s pointermi. Kompilátor sám zaistí, že sa napr. priraďovacím príkazom, nebude meniť hodnota v zásobníku, ale hodnota skutočného parametra. Aj keď si v C musíme na dosiahnutie rovnakého výsledku pomôcť pointermi, pre zjednodušenie budeme aj tu používať termín volanie odkazom.

Vráťme sa k nášmu príkladu, tento raz však hodnotu skutočného parametra vo funkcii nastav zmeníme:

void nastav(int *x)
{
	*x = 0;
	printf("x ma hodnotu %d\n", *x);
}

int main(void)
{
	int x = 1;
	printf("x ma hodnotu %d\n", x);
	nastav(&x);
	printf("x ma hodnotu %d\n", x);
	return (0);
}

Na výstupe teraz máme:
 
x má hodnotu 1
x má hodnotu 0
x má hodnotu 0
 

Ako parameter sa vo volaní nastav(&x) odovzdáva adresa premennej x.
 
Vo vnútri funkcii nastav pracujeme s pointerom!

Práve sme pomocou pointera zrealizovali „volanie odkazom.“ Všimnite si ale, že v C je toto „volanie odkazom“ opäť len volanie hodnotou, keď sa v zásobníku vytvorí lokálna kópia pre uloženie parametra – adresy skutočného parametra. Táto lokálna premenná síce zaniká s ukončením príslušnej funkcie, ale má tú vlastnosť, že je v nej uložený pointer, pomocou ktorého sa nepriamo zmenia údaje, ktoré nemajú s touto funkciou nič spoločného – boli definované mimo tejto funkcie a nezanikajú s jej koncom. Teda výsledok je rovnaký ako pri skutočnom volaní odkazom v Pascale, ale postup spracovania iný. To čo v Pascale uskutočňoval automaticky kompilátor vďaka kľúčovému slovu var, to musíme v C urobiť sami – teda nepracovať s formálnym parametrom ako s normálnou premennou, ale ako s pointerom.