13. diel - Štruktúry v jazyku C
V predchádzajúcom cvičení, Riešené úlohy k 12. lekcii céčko, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V minulej lekcii, Riešené úlohy k 12. lekcii céčko , bola reč o deklarovanie funkcií. V dnešnom tutoriále sa naučíme používať nemenej dôležitú súčasť tohto jazyka, ktorú sú tzv. Štruktúry. Keďže bude vytvorený opäť len jednoduchý program, tak vo výklade funkcie použité nebudú. My už vieme, že keby bol program o chlp dlhší, tak by sme ich určite mali zaviesť.
Uloženie zložitých prvkov
Keď by sme chceli uložiť dáta jedného používateľa, ktorý sa nejako volá, má nejaký vek a býva v nejakej ulici, vytvorili by sme si s doterajšími znalosťami niekoľko premenných:
int main(int argc, char** argv) { char jmeno[] = "Tomáš Márny"; int vek = 33; char ulice[] = "Šikmá 5"; return (EXIT_SUCCESS); }
Len zriedka však ukladáme len jedného používateľa a tak ich budeme
chcieť mať uložených hneď niekoľko. Už vieme, že keď chceme uložiť
viac prvkov rovnakého typu, využijeme na to pole. Keďže užívateľ v sebe
však obsahuje hodnoty troch typov, museli by sme si vytvoriť 3 rôzne polia.
Jedno pre mená, druhé pre veky a tretí pre ulice. V ďalšom motivačným
príklade si teda vytvorme niekoľko polí s veľkosťou 10
(teda
max. Pre uchovanie 10 užívateľov). Do poľa si na skúšku uložme dáta 2
užívateľov a užívateľov v poli následne Vypíšme pomocou
for
cyklu.
{C_IMPORTS}
#include <string.h>
{C_MAIN_BLOCK}
char jmena[10][51];
int veky[10];
char ulice[10][51];
strcpy(jmena[0], "Tomáš Márny");
veky[0] = 33;
strcpy(ulice[0], "Šikmá 5");
strcpy(jmena[1], "Josef Nový");
veky[1] = 28;
strcpy(ulice[1], "Vo svahu 8");
int i;
for (i = 0; i < 2; i++)
{
printf("Užívateľ na indexe %d\n", i);
printf("Meno: %s\n", jmena[i]);
printf("Vek: %d\n", veky[i]);
printf("Ulice: %s\n\n", ulice[i]);
}
{/C_MAIN_BLOCK}
výsledok:
Konzolová aplikácia
Užívateľ na indexe 0
Meno: Tomáš Márny
Vek: 33
Ulice: Šikmá 5
Užívateľ na indexe 1
Meno: Josef Nový
Vek: 28
Ulice: Vo svahu 8
Program vyzerá na naše pomery celkom pôsobivo. Až sa naučíme ukladať dáta do súborov, mohli by sme podobne naprogramovať napr. Telefónny zoznam. Napriek tomu vyššie uvedený kód nie je ideálne. Najprv si však povšimnime niekoľkých vecí.
Zaujímavá je najmä definícia polí jmena
a
ulice
. Pretože chceme v každej priehradke poľa (jmena) ďalšie
pole znakov (meno), musíme vytvoriť premennú, ktorá je poľom polí. Preto
sú uvedené 2 hranaté zátvorky. V prvej zátvorke je uvedený počet
položiek vonkajšieho poľa, teda počet mien v poli. V druhej zátvorke je
uvedený počet položiek pole, ktoré je vložené v každej priehradke. V
našom prípade je to 50
znakov (+1 pre \0
).
Už vieme, že v céčku nemôžeme dosadiť reťazcovú konštantu inak,
než pri inicializácii premennej. Preto tu musíme využiť funkcie
strcpy()
, ktorá nám reťazec do už vytvorenej premennej
skopíruje. Výpis cyklom by mal byť jasný, prechádzame len indexy
< 2
, pretože viac osôb v poli zatiaľ nemáme.
Štruktúry
Aby sme nemuseli tvoriť toľko zložitých polí, umožňuje C jazyk
definovať tzv. Štruktúru. Jedná sa o nový dátový typ, ktorý môžeme
uložiť do jednej premennej, ale ktorý vnútri zároveň obsahuje niekoľko
prvkov (niekedy sa mu hovorí záznamový typ). Vzdialene sa môže podobať
poli, jeho prvky však nemusia byť rovnakého typu a miesto číselne sú
pomenované slovami. Pre evidenciu používateľov by bolo úplne
najjednoduchšie vytvoriť si štruktúru UZIVATEL
. Niekam do
globálneho priestoru, nad funkciu main()
, vložíme túto
definíciu:
typedef struct { char jmeno[51]; int vek; char ulice[51]; } UZIVATEL;
Hoci existuje, ako to už v céčku býva, niekoľko možností na
definovanie štruktúry, budeme sa držať výhradne tohto zápisu. Štruktúru
definujeme ako nový dátový typ pomocou kľúčového slova
typedef
, čím si ďalej uľahčíme vytváranie premenných typu
UZIVATEL
. Nasleduje kľúčové slovo struct
. Do
zložených zátvoriek deklarujeme prvky štruktúry ako obyčajné premenné.
Názov štruktúry uvádzame vždy veľkými písmenami a za ním nasleduje
bodkočiarka.
Telo funkcie main()
teraz prepíšeme do nasledujúcej
podoby:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char jmeno[51];
int vek;
char ulice[51];
} UZIVATEL;
int main(int argc, char** argv)
{
UZIVATEL uzivatele[10];
strcpy(uzivatele[0].jmeno, "Tomáš Márny");
uzivatele[0].vek = 33;
strcpy(uzivatele[0].ulice, "Šikmá 5");
strcpy(uzivatele[1].jmeno, "Josef Nový");
uzivatele[1].vek = 28;
strcpy(uzivatele[1].ulice, "Vo svahu 8");
int i;
for (i = 0; i < 2; i++)
{
printf("Užívateľ na indexe %d\n", i);
printf("Meno: %s\n", uzivatele[i].jmeno);
printf("Vek: %d\n", uzivatele[i].vek);
printf("Ulice: %s\n\n", uzivatele[i].ulice);
}
return (EXIT_SUCCESS);
}
Celá aplikácia je oveľa čitateľnejší. Obsahuje
jednoducho jedno pole typu UZIVATEL
miesto predchádzajúcich 3
polí. K jednotlivým prvkom štruktúr v poli pristupujeme pomocou operátora
bodky. Ak sú štruktúry používané dynamicky (čo ešte nevieme), používa
sa operátor šípky (->
). Všetko si ešte ukážeme ďalej v
kurze.
Ďalšie definícia štruktúr
Len pre úplnosť si uveďme ďalšie spôsoby, ktorými možno štruktúru
vytvoriť a to najmä preto, aby ste vedeli čítať cudzie programy. Keď
štruktúru vytvoríme bez kľúčového slova typedef
, pomenujeme
ju malými písmenami:
struct uzivatel { char jmeno[51]; int vek; char ulice[51]; };
U premenných typu tejto štruktúry musíme uvádzať kľúčové slovo
struct
:
struct uzivatel uzivatele[10];
Niekedy sa štruktúra definuje dokonca priamo s premennou:
struct { char jmeno[51]; int vek; char ulice[51]; } uzivatele[10];
Tento zápis berte skôr ako odstrašujúci príklad. To, že je niečo kratšia, vôbec neznamená, že je prehľadnejšie. Navyše štruktúru takto nemôžeme použiť na viacerých miestach programu.
Pozn .: Štruktúry samozrejme nemusíme používať len v poliach, je to
úplne normálne dátový typ ako napr. int
. Zvyšuje prehľadnosť
a určite ho používajte všade, kde potrebujete ukladať viac hodnôt, ktoré
spolu logicky súvisia.
Pozn .: Okrem štruktúr môžeme v céčku definovať aj tzv.
union
y. Tie sa tvári rovnako, ako štruktúry, avšak premenná
typu union
môže mať vyplnenú len jednu hodnotu. Každý
užívateľ by teda mohol mať vyplnené buď len meno, len vek alebo len ulici.
U užívateľov toto nedáva príliš veľký zmysel, v praxi sa nám teoreticky
môže stať, že potrebujeme ukladať prvky a každý prvok je trochu iný.
Rovnako sa union
y však príliš nepoužívajú, je problém
spoznať čo je kde vyplnené (preto sa často balia do štruktúr) a my sa tu s
nimi nebudeme zaoberať.
Ku štruktúram sa v kurze ešte raz vrátime. Dnešné aplikáciu máte nižšie k stiahnutiu so zdrojovým kódom.
Týmto ste dočítali úvodný sekcii seriálu do základov jazyka C. Gratulujem vám, ste zoznámenie s väčšinou jeho konštrukciou! Výučba samozrejme pokračuje ďalej, sú tu ďalšie cvičenia a potom nadväzuje kurz Programovanie v jazyku C - Dynamická správa pamäte, kde sa dozviete najmä ako v céčku dynamicky pracovať s pamäťou a ako prestať byť obmedzenia dĺžkou polí a reťazcov. Pretože je táto problematika pomerne komplikovaná a začiatočníkov často mate, bola od nej celá základnej sekcie odtienené a vy ste si mohli bez zádrheľov vyskúšať rôzne konštrukcie céčka. Teším sa na vás teda ďalej, kedy začneme vytvárať reálne použiteľné aplikácie.
V nasledujúcom cvičení, Riešené úlohy k 13. lekcii céčko, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 217x (32.65 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C