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.