#7 Rozdělení zdrojového kódu

V sedmé lekci kurzu programování v jazyce C si ukážeme, jak a k čemu je dobré rozdělovat zdrojový kód do více části, než právě do jedné velké funkce.

Již v druhé lekci jsme si popsali základní prvky, které funkce může nebo musí obsahovat. Klasická funkce by měla obsahovat návratový typ a také vstupní argumenty, na základě kterých se ve funkci vyhodnotí kód a funkce nám vrací nějaký výstup.

Rozdělení kódu do více funkcí je užitečné zejména proto, že celý kód se stává o mnoho přehlednější a je také snadnější na editaci. Je vhodné pro odstraňování duplicity kódu. Pokud potřebujete použít vícekrát stejný výpočet akorát s jinými parametry, jednoduše tuto část vyjměte jako novou funkci a poté ji spusťte kolikrát bude potřeba.

Deklarace funkce

Jsou dvě možnosti jak funkci deklarovat:

  1. samotná deklarace funkce a její definice se nachází později v kódu
  2. deklarace společně s definicí

Jak tomuto rozumět? Znázorníme si vše na příkladu.

void func1(int, char, double); //deklarace, nemusi obsahovat nazvy parametru
void func2(int number) //deklarace s definici
{
    //prikazy
}

int main(void)
{
    func1(0,'f',5.0);
    func2(0);

    return 0;
}

void func1(int number, char c, double pi) //definice funkce
{
    //prikazy
}

Pokud máte program, který má pouze jednu vlastní funkci, tak použijte deklaraci společně s definicí. Pro více funkcí a komplexnější programy je pro přehlednost vhodnější použít strukturu:

  • deklarace vlastních funkcí
  • funkce main
  • definice vlastních funkcí

Argumenty a proměnné ve funkci

Proměnné deklarované ve funkci jsou lokální, tzn. že po skončení funkce zanikají. Argumenty jsou také lokální proměnné. Při zavolání funkce se tyto proměnné vytvoří a zkopíruje se do nich hodnota, která jim při zavolání byla předána. Existují 2 možnosti předání argumentů:

  1. Předání hodnotou
  2. Předání hodnotou ukazatele

Rozdíly mezi těmito způsoby si ukážeme na příkladu, použijeme oddělené proměnné pro každý způsob.

void Afunc(int a) {a = 50;} //nastavime a na 50
void Bfunc(int* b) {*b = 80;} //nastavime b na 80

int main(void)
{
    int a = 10;
    int b = 20;

    Afunc(a); //predani hodnotou
    Bfunc(&b); //predani hodnotou ukazatele

    printf("%d\n", a); //a je opet 10
    printf("%d\n", b); //b se zmenilo na 80

    return 0;
}

Ještě si ukážeme jak předat funkci celé pole proměnných, aby jej bylo možno upravovat ve funkci.

#define MAX_ARRAY 10

void write(int* array)
{
    for (int i = 0; i < MAX_ARRAY; i++)
        array[i] = i;
}

void print(const int* array)
{
    for (int i = 0; i < MAX_ARRAY; i++)
        printf("%d ", array[i]);
    printf("\n");
}

int main(void)
{
    int array[MAX_ARRAY] = {0};
    print(array);
    write(array);
    print(array);
    return 0;
}

Poznámka

Na příkladu vidíme, jakým způsobem jsou vyhodnocovány výrazy v jazyce C. Jedná se o zkrácené vyhodnocování neboli také líné. Tento způsob využívají i jiné programovací jazyky jako C# nebo Java.

int func()
{
    printf("func\n");
    return 0;
}

int main(void)
{
    if ((6 == 5) && (func() == 0)) {}
    return 0;
}

Volání funkce func se nachází v podmínce. Vidíme, že první část podmínky se vyhodnotí na false, zde líné vyhodnocování způsobí, že se druha část podmínky ani nemusí vyhodnocovat, jelikož bude celý výraz false.

K dnešní lekci o rozdělení zdrojového kódu to bude vše. V následující lekci se podíváme na využití rekurze a také na různé použití datových struktur.