Parametr funkce

Z Wikipedie, otevřené encyklopedie
Skočit na: Navigace, Hledání

Parametr funkce je označení pro vstupní data funkce v programování.

Formální a skutečný parametr[editovat | editovat zdroj]

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 | editovat zdroj]

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 | editovat zdroj]

Předávání jménem[editovat | editovat zdroj]

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 | editovat zdroj]

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 | editovat zdroj]

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);
 }