Hlavní strana -> Programování v C -> 02. Datové typy a čtení dat z klávesnice -> Rozšíření

02. Datové typy a čtení dat z klávesnice - rozšíření

Tedy přidávám sem malé rozšíření k datovým typům a k jejich čtení z klávesnice. Je to jen díky aktivitě jednoho ze čtenářů těchto stránek - díky Alešovi - díky mu. Říkal jsem, že když něco někomu nepůjde proto, že si myslí, že jsem to málo rozepsal a nevysvětlil pořádně, tak přidám další díl k dané problematice.

Doporučuji každému, aby se trochu podíval na ostatní číselné soustavy a hlavně na binární (dvojkovou) a šestnáctkovou (hexadecimální). Počítač totiž pracuje výhradně s binární soustavou a je tedy dobré rozumět tomu, co se v danou chvíli té krabici na stole (pod stolem) prohání po obvodech. Tak se na to mrkněte nebo mi napište a já tady dám další přílohu právě o dvojkové soustavě. (Přidal jsem krátké vysvětlení k číselným soustavám)

Řekli jsme si, že jazyk C zná 4 datové typy. Jsou to CHAR, INT, FLOAT, DOUBLE a někdy se považuje za datový typ (nevím jak) také VOID. Ten je ale zvláštní - univerzální, ale není to datový typ v pravém slova smyslu. Tím se prostě nebudem zabývat.

Každý z těchto datových typů je určen pro jiný typ ukládaných hodnot, dat. CHAR je pro uchování jednoho znaku. INT se používá pro uložení celočíselných hodnot, tedy počtu lidí, jablek, piv... :-) FLOAT jak název napovídá, tam bude něco plavat. Je to pohyblivá řádová čárka. Typ FLOAT je tedy možno použít k ukládání necelých čísel např. hodnota funkce sinus, odmocnin... Prostě všeho co vás napadne a dá se uložit jako reálné číslo. Nakonec zbývá DOUBLE. Double je to samé jako float, ale zhruba s dvojnásobnou přesností. Tady už počítač dává opravdu přesné výsledky (v rámci možností vyjádření desítkového čísla v binárním tvaru).

Tady jsou šířky (velikosti) jednotlivých datových typů. Je to počet bytů (bajtů), které zaberou v paměti pro jeden prvek.

char     1
int      4 (na některých systémech 2)
float    4
double   8

U Int jsem napsal, že na některých systémech má šířku 2 bajty. Jak je to u vás poznáte, když přeložíte a spustíte tenhle krátký program, který všechno vypíše.

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

int main(void)
{
  printf("Char \t%d\nInt \t%d\n",sizeof(char),sizeof(int));
  printf("Float \t%d\nDouble \t%d\n",sizeof(float),sizeof(double));

  printf("Pokracujte libovolnou klavesou.");
  getche();

  return 0;
}

Tento program volá ve funkci pro výpis délky dat operátor %d, protože se budou vypisovat celočíselné hodnoty a tomuto operátoru řekne, jaké číslo se vypíše, funkce sizeof. Funkce sizeof(datový typ) vrátí šířku zadaného datového typu jako celočíselnou hodnotu, vrácí počet bytů potřebných k uložení tohoto datového typu. Jo tahle věta je dost kostrbatá.

Raději si něco řekneme o jejich naplňování uživatelem zadanými hodnotami. Vytvoříte si proměnnou (místo v paměti) kam je možno uložit celé číslo tak, že napíšete typ int a potom jméno vaši proměnné. Třeba takto:

int rohliky;

Tímto příkazem jste vyhradili v paměti místo, pro uložení jednoho celého čísla. Můžete tam zadat třeba počet chlebů, ale to by bylo nelogické. V takovém případě, bychom raději vytvořili proměnnou chleby.

Naše vytvořená proměnná je dosud neinicializovaná a obsahuje nějakou předem neurčitelnou hodnotu. To proto, že obsah paměti se nevymaže, jakmile už není programem používaná (program skončil), ale pouze se označí jako volné místo, které je možno v budoucnu použít k uložení nových hodnot tak, že se původní hodnota "přebije". Proměnné rohliky třeba dáme počáteční stav 8 takto:

rohliky = 8;

Slouží pouze pro zápis celých čísel a příkaz

rohliky = 7.5;

by byl špatný. Proměnné int nelze přiřadit reálné číslo!

Stejně tak lze přiřadit jiným typům dat jiná data.

float vyska = 1.82;
double prumer = 0.58;
char pismeno = 'A';

Float a double lze také přiřadit celé číslo, ale nesmí se zapomenout na desetinnou část. Tedy napsat desetinnou tečku a za ni nulu. Výška může být třeba 2 metry, ale budeme s ní někdy počítat, že ji budeme dělit apod. a potom budeme potřebovat, aby byla float. Pro zápis celočíselné hodnoty se použije příkaz takového tvaru:

vyska = 2.0;

Výše uvedeným způsobem bychom ale rohlíky zadávali programu "natvrdo", pokud bychom chtěli, aby jednou používal takovou hodnotu a podruhé zase jinou, museli bychom přidat čtení z klávesnice. Použijeme funkci scanf(). Funkce scanf může načíst prakticky cokoliv, jenom se musí použít správný operátor a odkazovat se na proměnnou existující a správného typu.

Tento program nejprve vytvoří proměnnou typu int, float, char. Zadá jim předem dané hodnoty a potom vyzve uživatele k zapsání vlastních hodnot. Nakonec je vypíše. Všimněte si, jak jsou podobné printf() a scanf(). Pozor na \n označuje nový řádek.

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

int main(void)
{
  int cele;
  float realne;
  char znak;

  cele = 5;
  znak = 'K'; /* pouze jednoduche uvozovky */
  realne = 3.141592;

  printf("Natvrdo zadane hodnoty jsou: \nCele: %d\nRealne: %f\nZnak: %c\n",
          cele, realne, znak);

  printf("Zadejte vlastni znak.\n");
  scanf("%c", &znak);

  printf("Zadejte vlastni hodnotu do Cele.\n");
  scanf("%d", &cele);
 
  printf("Zadejte vlastni hodnotu do Realne.\n");
  scanf("%f", &realne);

  printf("Zadali jste tyto nove hodnoty %d  %f  %c \n", cele, realne, znak);

  printf("Program je u konce. Pokracujte libovolnou klavesou.");
  getche();

  return 0;
}

Jak je vidět v příkladu, používají funkce scanf() i printf() stejné datové specifikátory.

char        %c
int         %d
float       %f
double      %f

U printf() se mezi dvojité uvozovky dává řetězec a na místě, kde chceme vypsat nějakou hodnotu použijeme správný specifikátor. Pro výpis hodnoty s pohyblivou řádovou čárkou se používá %f. Za řetězcem ukončeným dvojitou uvozovkou se dá čárka a pak v přesném pořadí proměnné, jejichž obsach potřebujem vypsat.

 printf("Zadali jste tyto nove hodnoty %d  %f  %c \n", cele, realne, znak);
/* správně */

printf("Zadali jste tyto nove hodnoty %d  %f  %c \n", realne, cele, znak);
/* špatně */

Místo těch tří výzev a tří funkcí pro načtení hodnoty byste mohli použít také tento způsob, kdy je vše zahrnuto do jednoho příkazu.

printf("Zadejte vsechny tri hodnoty najednou oddelene mezerami\n (znak,cele,realne).\n");
scanf("%c %d %f", &znak, &cele, &realne);

Pozor. Při použití scanf() je nutno dodat před proměnné, kterým chcem přiřadit naše zadané hodnoty ještě &. Toto se u printf() nepoužívá. & se do scanf dává z toho důvodu, že scanf očekává adresy, na které se bude zapisovat. Operátor & se nazývá referenční a veme místo hodnoty proměnné před kterou stojí její adresu. Více se dozvíte v díle o Pointerech - ukazatelích.

Přesměrování standardního vstupu a výstupu

Funkce printf() a scanf() zapisují / čtou takzvaný standardní výstup / vstup. Takovýto standardní vstup se dá s pomocí operačního systému přesměrovat na soubor. Mějme program:

#include <stdio.h>

int main(int argc, char *argv[])
{
    int a, b;

    printf("Zadavejte dvojce cisel, budu je scitat\n\
program ukoncite 2 nulami\n");

    scanf("%d%d", &a, &b);
    while(a!=0 || b!=0){
        printf("Soucet: %d\n", a+b);
        scanf("%d%d", &a, &b);
    }

    printf("Konec programu\n");
    return 0;
}

Když teď budete zadávat celá čísla, tak vždy po zadání druhého se vypíše jejich součet. Program bude ukončen zadáním dvou nul po sobě. Když si ale vytvoříte textový soubor v obyčejném notepadu a do něj si zadáte sudý počet celých čísel a poslední dvojice bude 0 0, tak tento soubor (třeba in.txt) můžete programu "předhodit" právě přesměrováním standardního vstupu. Program spustíte příkazem program.exe < in.txt

Stejným způsobem se dá přesměrovat i standardný výstup. Rozdíl je v použitém "většítku" místo "menšítka". Obě přesměrování se můžou zkombinovat. Pokud tedy spustíte program příkazem program.exe < in.txt > out.txt a obsah in.txt bude:

2 4
5 7
7 2
0 0

Pak vznikne nový textový soubor out.txt a jeho obsah bude:

Zadavejte dvojce cisel, budu je scitat
program ukoncite 2 nulami
Soucet: 6
Soucet: 12
Soucet: 9
Konec programu

Uvedená technika se dá velmi dobře použít. Určitě vás něco napadne. Nedostatkem mnou uvedeného programu je ale chybějící kontrola vstupních dat, takže pokud zadáte něco jiného než čísla nebo soubor nebude ukončen dvěma nulami, tak dojde k chybě.

Zpět

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