Parametr funkce
Parametr funkce je označení pro vstupní data funkce v programování.
Obsah |
Formální a skutečný parametr [editovat]
Tento pojem ve skutečnosti zahrnuje dvě odlišné věci:
- Formální parametr je parametr použitý při psaní funkce, její vnitřní proměnná. Ta je vždy před zpracováním nahrazována hodnotou skutečného parametru.
- Skutečný parametr je proměnná nebo výraz dosazený při volání funkce. Při volání funkce je jeho hodnota přiřazena formálnímu parametru.
Způsoby předávání parametru [editovat]
Navázání skutečného parametru na formální lze dosáhnout několika odlišnými způsoby. Ve většině dnešních programovacích jazyků se používají hlavně předávání parametrů hodnotou a odkazem:
- Při předávání hodnotou (call-by-value) se těsně před zpracováním těla funkce skutečný parametr vyčíslí a výsledek se zkopíruje do lokální proměnné uvnitř volané funkce. Jakékoli změny parametru uvnitř volané funkce nemají vliv na volající funkci, neboť se pracuje s lokální kopií, předávání hodnotou tedy lze používat pouze pro vstupní parametry. Tento způsob je typický např. při vytváření aritmetických funkcí.
- Při předávání odkazem (call-by-reference) se formální parametr uvnitř volané funkce bere jen jako jiné označení (alias) pro proměnnou předanou jako skutečný parametr, tzn. ve volané funkci se pracuje přímo s předávanou proměnnou, nevytváří se tedy kopie (což zvláště u strukturovaných proměnných znamená zpravidla úsporu času i paměti). Volaná funkce změnou parametru ovlivňuje i volající funkci (takže předávání odkazem lze používat pro výstupní či vstupně-výstupní parametry), nevýhodou však je, že parametrem může být jen proměnná a nikoli výsledek obecného výrazu. Předávání odkazem se obvykle implementuje pomocí ukazatele na předávanou proměnnou.
Někdy se používají také o něco netradičnější způsoby předávání jako např. předání hodnotou s kopií při návratu (call-by-copy-restore) nebo předání jménem (call-by-name).
Příklady [editovat]
Předávání jménem [editovat]
Bylo použito např. v Algolu 60. Předávání je podobné jako při předávání referencí, ovšem hodnota proměnné se vyhodnocuje v těle funkce pokaždé.
Příklad:
procedure P(X);
integer X;
begin
write(X);
I:=I+1;
write(X);
end
Při zavolání funkce:
P(A[i]);
se pak vypíší prvky v poli A na místě I a I+1.
Příklad v jazyce C [editovat]
Předávání hodnotou
void Zamen(int a, int b) //zameni hodnoty v promennych { int pom; pom = a; a = b; b = pom; }
Tuto metodu budeme volat v programu následně:
int main(void) { int promennaA = 10, promennaB = 20; Zamen(promennaA, promennaB); return 0; }
Po tomto zavolání metody Zamen budou hodnoty v proměnných promennaA 10 a v proměnné promennaB bude hodnota 20. Tedy k žádné změně nedojde. Je to tím, že pokud předáváme parametry funkci hodnotou, tak pracujeme vlastně s kopiemi proměnných a tím je průběh funkce izolovaný.
Pokud chceme, aby volání funkce ovlivnilo parametry, které předáváme, musíme předávat parametry funkci ukazatelem (referencí) na danou proměnnou.
Předávání ukazatelem
void Zamen(int* a, int* b) //zameni hodnoty v promennych { int pom = *a; *a = *b; *b = pom; }
Tuto metodu budeme volat v programu následně:
int main(void) { int promennaA = 10, promennaB = 20; Zamen(&promennaA, &promennaB); return 0; }
Po zavolání funkce tímto způsobem se již odkazuje na místo v paměti, kde jsou uložené proměnné promennaA a promennaB a tím dosáhneme toho, že po zpracování funkce bude v proměnné promennaA hodnota 20 a v proměnné promennaB bude 10.
Příklad v jazyce C# [editovat]
Předávání parametrů v jazyce C# je velice podobné jazyku C, jen zde dochází k malé změně definice a volání takové funkce.
Předávání hodnotou
void Zamen(int a, int b) //zameni hodnoty v promennych { int pom; pom = a; a = b; b = pom; }
Tuto metodu budeme volat v programu následně:
static void Main(string[] args) { int promennaA = 10, promennaB = 20; Zamen(promennaA, promennaB); return 0; }
Jak můžeme vidět, tak předávání parametrů funkci hodnotou v jazyce C# je totožné s jazykem C a dočkáme se i stejného výsledku, tj. promennaA a promennaB budou po zavolání funkce beze změny.
Předávání odkazem
void Zamen(ref int a, ref int b) //zameni hodnoty v promennych { int pom = a; a = b; b = pom; }
Tuto metodu budeme volat v programu následně:
static void Main(string[] args) { int promennaA = 10, promennaB = 20; Zamen(ref promennaA, ref promennaB); return 0; }
Po předání parametrů funkci tímto způsobem dosahujeme stejného výsledku jako v jazyce C a ve výsledku máme tedy po zavolání funkce v našich proměnných promennaA a promennaB hodnotu 20 resp. 10.
Jazyk C# umí navíc další možnosti jak předávat parametry funkci. Je zde možnost proměnného počtu parametrů funkce a také možnost použití modifikátoru out, který je blízký modifikátoru ref. Na následujících příkladech si ukážeme funkčnost těchto možností.
Proměnný počet parametrů
int Suma(params int[] cisla) // secte vsechna cisla zadana jako parametry { int _suma = 0; for(int i = 0; i < cisla.Length; i++) { _suma += cisla[i]; } return _suma; }
Tuto metodu budeme volat v programu následně:
static void Main(string[] args) { int suma = 0; suma = Suma(1,2,3,4,5); //libovolny pocet parametru typu int return 0; }
Předání odkazem (modifikátor out)
Tato možnost předání parametru funkci je podobná jako u předávání odkazem (ref). Tento zápis používáme, pokud potřebujeme z funkce například více výstup. Například potřebujeme zjistit, jestli se výpočet funkce provedl v pořádku a tak funkce vrací hodnotu bool a výsledek je tedy potřeba získat přes modifikátor out. Bylo by možné použít i možnost ref, ale při použití modifikátoru out je nucen programátor parametr funkce s tímto modifikátorem ve funkci naplnit.
bool Soucet(int a, int b, out int soucet) //secte hodnoty a, b a ulozi do prommene, ktera je jako parametr soucet a vraci typ bool, zdali se soucet povedl { try{ soucet = a + b; // pokud je nejaky parametr out, je nutne ho v tele funkce pouzit (zmena oproti ref) return true; catch(Exceprion) { soucet = 0; // pokud se neco pokazi, tak tim ze je soucet s modifikatorem out, tak musime promennou naplnit (v tomto pripade 0) return false; // soucet se nepovedl } }
Tuto metodu budeme volat v programu následně:
static void Main(string[] args) { int a = 10, b = 20, soucet; bool vypocetOK = Soucet(a , b, Out soucet); }