Hlavní strana -> Programování v C -> Příklady

Příklady programů jazyka C

No pořád jenom říkám, že programování se musí zkoušet a že stálým čtením pravidel se to nikdo nenaučí. Proto sem musím dát nějaké příklady, ve kterých si můžete rozšířit své obzory a zdokonalit se v ovládání snad nejlepšího programovacího jazyka. Přece jenom je fajn, když se podaří tu hromadu obvodů a tranzistorů taky něčemu naučit. Teda co to plácám, komp se ničemu nenaučí, ale vy mu dáte perfektní návod, jak něco dělat. To jsem ale trochu odbočil a raději přejdu k věci.

Na úvod si třeba dáme primitivní, neprofesionální program, který bude počítat mocniny dvou a pokaždé se zeptá uživatele, jestli chce pokračovat. Co k tomu budeme potřebovat? Zaprvé inkludovat knihovnu standardních vstupně-výstupních funkcí. Dále budeme pokračovat funkcí main, vytvoříme si nějaké proměnné a využijeme cyklu do-while. Ještě přidáme jednu funkci pro čtení jednoho znaku, abychom mohli provést otázku ohledně pokračování. Funkce se jmenuje getche() a je definována v hlavičkovém souboru conio.h.

#include <stdio.h>
#include <conio.h>

void main(void)
{
    int i=1;  /* inicializace promenne */
  
    do{
        printf("Mocniny dvou %d \n", i);
        i = i*2; // nasobeni dvojkou, slo by i *= 2
        printf("Pokracovat? a = ano\n");
    }while(getche() == 'a');

    printf("Program konci, zmacknete cokoli.");
    getche(); /* tady program ceka */
}

To byl opravdu jednoduchý, prakticky ne moc využitelný program. Funkci getche() jsme na konci využili ke zdržení programu, aby hned neskončil, protože ještě čeká na zadaný znak, který se však nikam nepřiřazuje, a tak vlastně přijde nazmar. To teda byla věta. V řídící podmínce cyklu while je rovnou použito volání funkce a nepřiřazuje se nejdříve znak proměnné, která by se potom porovnávala se znakovou konstantou 'a'. Je to kratší a odbornější.


Zkusíme si nějaký jiný program. Opět využijeme toho, že není vždy zapotřebí nějakou hodnotu přiřadit proměnné, abychom s ní mohli pracovat. Následující program převádí zadanou rychlost v metrech za sekundu na kilometry za hodinu. Ve funkci printf použijeme volání funkce kmh() s parametrem typu int pro výpis zadané rychlosti v kilometrech za hodinu.

#include <stdio.h>
#include <conio.h>

float kmh(int rychlost); /* prototyp funkce */

void main(void)
{
    int metry;

    printf("Zadejte rychlost v m/s \n");
    scanf("%d", &metry);
    printf("Rychlost %d m/s je %f km/h \n", metry, kmh(metry));

    printf("Konec programu, zmacknete cokoli.");
    getche();
}

float kmh(int rychlost)
{ 
    return rychlost*3.6;
}

Použití funkce kmh() je v tomto případě naprosto zbytečné a úplně by stačilo napsat funkci printf takto:

printf("Rychlost %d m/s je %f km/h \n", metry, metry*3.6);

To bylo pouze na procvičení vytváření vlastních funkcí a psaní jejích prototypů.


Následující program se nejdříve uživatele zeptá, kolik bude zadávat čísel a potom je bude průběžně sčítat a vypisovat výsledky. Na konec ještě vypíše jejich průměr.

#include <stdio.h>
#include <conio.h>

void main(void)
{  
    int hodnot, cislo, soucet=0, i;

    printf("Kolik bude cisel?\n");
    scanf("%d", &hodnot);

    for(i=0; i<hodnot; i++){
        printf("Zadejte cele cislo.\n");
        scanf("%d" &cislo);
        soucet += cislo;
        printf("Prubezny soucet je %d\n",soucet);
    }
    printf(Prumer zadanych hodnot je %f",(float)soucet/hodnot);
    getche();
}

V posledním printf je použito přetypování na typ float. Obě proměnné jak soucet tak hodnot jsou celočíselné a výsledek tohoto dělení by byl také celočíselný právě kvůli konverze typu ve výrazech, kdy výsledek je vlastně stejného typu jako nejširší typ ve výrazu. Tohle je důvod k přetypování.
Ještě bych měl vysvětlit, proč je soucet na začátku nastaven na nulu. Je to proto, že v době spuštění programu se jednotlivým proměnným jen vyhradí místo v paměti, které již není žádným jiným programem využíváno. Paměť se ale nemaže, a tak by proměnná soucet na začátku obsahovala vpodstatě náhodné číslo.


Teď si dáme příklad, který využije zatím nejnovější poznatky o příkazu switch a řetězcích a polích. Vytvoříme si program, který nejdříve nechá uživatele zadat nějaký řetězec určité maximální délky a potom nám spočítá, kolik obsahuje samohlásek a kolik jiných vybraných znaků. Tedy necháme uživatele zadat řetězec a potom s ním budeme pracovat jako s polem, budeme jej tedy indexovat a využijeme také některé funkce pro práci s řetězci, konkrétně funkci strlen().

#include <stdio.h>
#include <string.h>
#include <conio.h> /* kvuli getche() nakonci */

void main(void)
{
    int samohl, jine, nerozl, i;
    char zprava[81]; /* znakove pole */

    printf("Zadejte retezec, ktery obsahuje maximalne 80 znaku.\n");
    gets(zprava);

    samohl = jine = nerozl = 0; /* vicenasobne prirazeni */
    for(i=0; i<strlen(zprava); i++){
        switch(zprava[i]){
            case 'a':
            case 'e':
            case 'i':
            case 'o':
            case 'u':
            case 'y': samohl++;
                break;
            case ' ': /* mezera */
            case '.':
            case ',':
            case ';': jine++;
                break;
            default: nerozl++;
        } /* konec switch */
    } /* konec for */

    printf("Retezec obsahuje %d samohlasek, %d jinych znaku a\
    %d nerozlisenych.\n",samohl,jine,nerozl);
    printf("Stisknete klavesu");

    getche();
    return;
}

Tohle je příklad na switch, kdy ne každá case má svou sadu příkazů. Pokud je tedy nalezena shoda, tak se provádějí příkazy až do příkazu break. Pokud tedy zprava[i] obsahuje a, e, i, o, u nebo y, tak se inkrementuje (zvětší o 1) proměnná samohl. Pokud obsahuje mezeru, tečku, čárku nebo středník, tak se inkrementuje proměnná jine. No a není-li nikde nalezena shoda, tak se provede část default, která inkrementuje nerozlišené znaky. Na samém konci budu vždy vkládat příkaz (spíše funkci) getche(), která nám zajistí, že program bude vyčkávat na stisk klávesy a neproblikne pouze na monitoru, takže uživatel bude mít spoustu času přečíst si výsledky počítání.


Další příkladek si dáme třeba na struktury. Nejedná se přímo o spustitelný program, ale jen o jeho část. Pokud programujete nějaký program pro převod trojrozměrného světa na obrazovku (3D Engine), pak budete určitě potřebovat mít tento svět nějak nadefinovaný a pravděpodobně to bude pomocí objektů, trojúhelníků (Face), jejich normálových vektorů a bodů (Vertex), které tyto trojúhelníky definují. Používá se proto vnořených struktur. Zatím použiju jejich pole. Později, až budeme umět pracovat s pointery (ukazateli), pak bych použil dynamická pole a paměť počítače by se využívala efektivně. Zatím tedy zadám přesný počet struktur. Následující úsek zdrojového kódu nám vytvoří podmínky pro uchování informací o 2 objektech, z nichž každý se skládá maximálně ze 700 trojúhelníků. Tedy:

struct Vertex{
    float x, y, z;  /* pozice bodu v prostoru */
};

struct Vector{
    float x, y, z;  /* smer vektoru v prostoru */
};

struct Face{
    struct Vertex vtx[3];
    struct Vector normal;
};

struct Object{
    struct Face obj_face[700];
};

struct Object obj[2];  /* vytvoreni dvou objektu jmena obj */

Potom bychom přiřadili hodnotu například k x-ové pozici 3. vertexu 65. facu od 2. objektu takto:

obj[1].obj_face[64].vtx[2].x = 51.47;

Zpět

Programování v C | CZ 175/477 | Mapa stránek
Bc. Petr Klimánek, student Ostravské univerzity v Ostravě