Posted in: Studijní materiály, Vývoj počítačů

Úvodní vhled do jazyka C

Zpracování programu

Editor Slouží pro zápis zdrojového kódu programu a ukládá ho s příponou .c. Preprocesor Předzpracuje zdrojový kód. Vkládá hlavičkové soubory s příponou .h, vynechává komentáře, rozvíjí makra atd. Compiler Převede zdrojový kód do relativního kódu počítače tak, že adresy proměnných a funkcí nejsou známy a jsou relativně zapsány do souboru *.obj. Soubor *.lis je protokol o překladu. Linker Přidělí relativním adresám adresy absolutní, najde adresy neznámých identifikátorů a připojí všechny potřebné knihovny *.lib. Debuger Hledá chyby nastávající při běhu programu a po nalezení chyby se celé zpracování programu opakuje. První program
Pro ilustraci toho jak vypadá program v C si uvedeme jednoduchý program který vypisuje text: „Hurá, můj první program v C!!!“

//Můj první program 
#include <stdio.h> 
int main()
{ 
   printf("Hura, muj prvni program v C!!!");
   getch(); 
   return(0);
}

V prvním řádku s vyskytuje komentář. V jazyce C se zapisuje jednořádkový komentář ve tvaru //jednořádkový komentář. Víceřádkový se zapisuje /* viceřádkový komentář */. Dále se v kódu vyskytuje direktiva (příkaz preprocesoru) #include , která zajišťuje připojení knihovny funkcí. V tomto případe stdio.h pro standardní formátovaný vsup a výstup. Hlavní program je zapsán do funkce main(), kterou musí obsahovat každý program. Začátek a konec programu zapisujeme pomocí tzv. bloku { … }. Definice funkcí (i hlavní funkce main()) většinou obsahují nepovinný příkaz return. V těle programu je funkce pro tisk na standardní výstup printf() a po ní funkce getch(), která je zde jen proto, aby se okno programu nezavřelo hned po spuštění. Místo této funkce lze použít elegentnější řešení s pomocí system(„pause“). V tomto programu se jednalo o pouhé nastínění toho, jak má program v C vypadat. V dalších lekcích se dozvíte vše podrobněji. Klíčová slova Je to množina slov, kterým překladač jazyka C rozumí a má je ve své slovní zásobě. Proto je nelze použít jako identifikátor či název funkce.

  • auto
  • break case char
  • const
  • double int else
  • long
  • extern return float
  • short
  • continue for default do
  • goto if
  • struct switch
  • enum register typedef union
  • unsigned signed void
  • sizeof volatile static while

Proměnné

Proměnné jsou paměťová místa přístupná prostřednictvím identifikátoru. Hodnotu proměnných můžeme během výpočtu měnit. Pro deklaraci proměnné používejte tento obecný formát: typ identifikátor; Pro deklaraci více proměnných stejného datového typu se používá tento zápis: typ identifikátor_1, identifikátor_2, identifikátor_3; V deklaraci může být proměnná současně inicializována, tj. můžeme jí přiřadit počáteční hodnotu: typ identifikátor=hodnota; Proměnné deklarované mimo všechny funkce jsou globální, můžeme je použít kdekoli v programu a jsou implicitně nulové. Proměnné deklarované ve funkcích či v bloku se nazývají lokální proměnné, můžeme je použít jen v dané funkci či bloku a jsou implicitně nenulové.

Datové typy

Datové typy určují rozsah hodnot, velikost alokované paměti a množinu přípustných operací. Dělíme je na: Jednoduché

bez hodnoty void
celočíselné: short (16b), int (16b|32b dle tzpu CPU), long (32b), char (8b)
výčtový typ: enum (8b|16b|32b)
reálné: float (32b), double long (64b), double (80b)

Strukturované

struktura: struct
unie: union
soubor: FILE
pole a řetězec nemají klíčové slovo, jsou složeny ze základních datových typů. Velikost proměnné a rozsah jejich hodnot závisí na implementaci překladače v operačním systému. Typy float, double a long double se používají pro reálná čísla. Typ int a z něj odvozené typy short int a long int pracují s celými čísly. Poněkud překvapivě patří k celočíselným typům i char. Je sice určen pro uložení jednoho znaku, ten je však v jazyce c reprezentován jako číslo. Všechny celočíselné typy mohou být prefixem unsigned deklarovány jen pro čísla bez znaménka. Implicitně jsou deklarovány jako signed. Pro zjištění velikosti daného datového typu se používá operátor sizeof. Operandem je buď datový objekt (např. proměnná nebo pole) sizeof identifikátor; nebo název typu uzavřený do závorek. sizeof (datový typ); Výsledek je v bajtech.

Konstanty

Konstanta je datový prvek jehož hodnota je neměnná. Překladač přiřadí konstantě typ odpovídající hodnotě. Uvozuje se klíčovým slovem const. Dělíme je na:
Celočíselné

druhzápis
desítkovédesítkové_číslo
osmičkové0osmičkové_číslo
šestnáctkové0xšestnáctkové_číslo

C umožňuje určit typ číselných konstant pomocí sufixu. Celá čísla můžeme zapsat jako long pomocí sufixu ‘l’ nebo ‘L’, nebo bez znaménka čili unsigned pomocí ‘u’ nebo ‘U’.

Reální

druhzápis
Desetinný zápiscelá_část.desetiná_část
semilogaritmický zápismantisaeexponent nebo mantisaEexponent

Implicitní typ racionální konstanty je double. Pro typ float uvedeme číslem ‘f‘ nebo ‘F‘. Pokud za číslo dáme ‘l’ nebo ‘L’ stane se z čísla long double.

Znakové

zápisvýznam
‚znak‘řetězec

Znakové konstanty jsou jeden znak obklopený apostrofy. Proto abychom mohli ve znakových a také řetězcových konstantách zapisovat speciální a negrafické znaky používají se tzv. escape sekvence. Začínají lomítkem a využívají se zejména ve výstupních funkcích jako např. printf. Jejich seznam je následující:

zápisvýznam
\0prázdný znak (je na konci každého řetězce)
\apípnutí
\bnávrat o jeden znak zpět
\fnová stránka nebo obrazovka
\npřesun na začátek nového řádku
\rpřesun na začátek aktuálního řádku
\tpřesun na následující tabelační pozici
\vpřesun dolů
\\obrácené lomítko
\‘apostrof
\“uvozovky
\?otazník

Řetězcové

Zapisují se jako posloupnost znaků obklopená uvozovkama.

Operátory

Operátory určují operaci, kterou hodláme provést s operandem. Např.: a + b, ‚a‘ a ‚b‘ jsou operandy a ‚+‘ je operátor Dělení:dle počtu operandů: unární (1), binární (2), ternární (3) dle funkce operátorů: aritmetické, relační, logické, bitové, přiřazovací, ternární, inkrementace a dekrementace a ostatní Aritmetické

zápisvýznam
+, -, *sčítání, odčítání, násobení
/celočíselné dělení (když jsou oba operandy celé číslo), reálné dělení (když je alespoň jede operand reální číslo)
%dělení modulo, neboli zbytek po celočíselném dělení

Relační

zápisvýznam
<, <=, >, >=menší než, menší nebo rovno, větší než, větší nebo rovno
==rovnost
!=nerovnost

Logické

zápisvýznam
&&logický součin (AND)
||logický součet (OR)
!negace

Bitové

zápisvýznam
>>, <<bitovém posunu vpravo a vlevo
&logický součin (AND)
|logický součet (OR)
~negace
^XOR

Přiřazovací

zápisvýznam
=přiřazení
+=, -=, *=, /=zkrácený výraz pro proměnná=proměnná+číslo atd.
!negace

Inkrementace a dekrementace

zápisvýznam
++inkrementace, zkrácený zápis pro proměnná=proměnná+1
dekrementace, zkrácený zápis pro proměnná=proměnná-1

Ostatní operátory

zápisvýznam
(datový_typ)operátor přetypování
sizeofoperátor pro zjištění velikosti datového typu či datového objektu
&operátor adresy
()operátor volání funkce
[]operátor prvku pole
.výběr prvku struktury
->výběr prvku struktury zadané ukazatelem

Vstupní/výstupní funkce

Aby uživatel mohl s programem aktivně pracovat používáme vstupní a výstupní funkce. Formátovaný vstup a výstup zajišťují tyto funkce: scanf(„formátovacířetězec“, adresy); printf(„formátovacířetězec“, proměnné_či_výrazy); Protože jazyk C má malé jádro, musí většinu funkcí připojovat. K tomu abychom je připojili musíme do zdrojového kódu zapsat názvy hlavičkových souborů obsahující potřebné funkce. Zapisujeme je do hlavičky programu. V případě formátovaného vstupu/výstupu to je stdio.h. Přidáme jí takto:

#include <stdio.h>

Formátovaný výsup printf()

printf(„formátovacířetězec“, proměnnéči_výrazy); Formátovací řetězec se skládá z úseků textu, které se beze změny objeví na výstupu, a formátové specifikace (konverze) určující, v jakém tvaru se hodnoty proměnných či výrazů zobrazí. Každá formátová specifikace začíná znakem % a končí písmenem, které musí odpovídat typu vypisované hodnoty Výrazy či proměnné jsou čteny z leva doprava. Vkládáme-li do formátovacího řetězce více výrazů či proměnných, oddělíme je čárkami. Forátovaný vstup scanf() scanf(„formátovací_řetězec“, adresa); Formátovacím řetězcem je určena formátová specifikace vstupní hodnoty (pomocí % a odpovídajícího písmene). Adresa určuje paměťovou oblast, do níž bude odpovídající vstupní hodnota uložena a zapisuje se ve tvaru &identifikátor_proměnné. V praxi jde nejčastěji o adresu proměnné, nebo o ukazatel na pole znaků. Čtení ze vstupu probíhá tak, že první formátová specifikace je použita pro vstup první hodnoty, která se uloží na první adresu po stisku klávesy Enter atd. Čteme-li více hodnot oddělujeme adresy proměnných čárkami. Formátová specifikace Formátová specifikace má obecně tento tvar: %[.přesnost][modifikátor]konverze Konverze je označena jedním znakem, mezi znakem % a označením konverze mohou být umístěné další (nepovinné) parametry jako modifikátor či přesnost. Konverze pro printf() a scanf() jsou stejné.

konverze

Modifikátory

Přesnost

Zapisuje se desetinou tečkou. Přesnost je dekadické číslo, které pro konverze d, i, o, u, x, X znamená minimální počet cifer na výstupu, pro konverze f, e, E, znamená počet cifer za desetinnou tečkou, pro konverze g, G znamená počet významových cifer a pro konverzi s maximální počet znaků. Formátovaný vstup a výstup může vypadat třeba takto:

#include <stdio.h> 
int x,y; 
int main(){ 
   printf("Zadejte dve cisla: \n"); 
   scanf("%d %d", &x, &y); 
   printf("Soucet %d a %d je roven: %d\n", x, y, x+y); 
   printf("Rozdil %d a %d je roven: %d\n", x, y, x-y); 
   printf("Soucin %d a %d je roven: %d\n", x, y, x*y); 
   printf("Podil %d a %d je roven: %.2f\n", x, y, (float)x/y); 
   getch(); 
   return(0);
}

Znak ‚\n‘ je zde interpretován jako přechod na novou řádku. Kombinace %d, %f jsou konverze určené pro výstup hodnot po řadě typu int a float. Vstup a výstup znaků Pro vstup znaků je určena funkce getchar() ze standardního vstupu. Pro výstup znaků na standardní výstup je určena funkce putchar(). Používá se pro ně následující zápis: getchar(znak); putchar(znak); Pro vstup znaku je taky možno použít funkci getch(), která se nachází v hlavičkovém souboru conio.h. Rozdíl mezi getch() a getchar() je takový, že getch čeká na stisknutí klávesy Enter, kdežto getch() okamžitě reaguje na vstup. Sekvence Sekvencí nebo blokem se rozumí posloupnost příkazů ohraničená znaky { }. Mezi těmito závorkami mohou být libovolné jiné příkazy včetně dalších bloků. Používá se ve větvení, cyklech a funkcích. Na začátku sekvence je vhodné definovat lokální proměnné. Blok se chová jako jeden příkaz.

Větvení

Alternativa neboli větvení nám zajišťuje provedení příkazu za určité podmínky. Rozlišujeme 3 typy: úplná, neúplné, vícenásobná

Úplné

Obecný zápis vypadá takto: if (podmínka) příkaz_1; else příkaz_2; Za klíčovým slovem if následuje podmínka povinně uzavřená do závorek. Je-li podmínka pravdivá (nenulová), potom se provede příkaz_1, je-li nepravdivá (nulová), pak se provede příkaz_2 Alternativy můžeme do sebe navzájem vnořovat. Vnořená alternativa vypadá takto: if (podmínka) příkaz_1; else if (podmínka) příkaz_2; else příkaz_3; V následujícím programu se pomocí úplné vnořené alternativy zjisti zda je číslo kladné, záporné nebo nula.

#include <stdio.h> 
int a; 
int main(){ 
   printf("Zadej cislo: "); 
   scanf("%d",&a); 
   if (a>0) 
   {
      printf("Cislo je kladne"); 
   }else if (a<0) 
       {
         printf("Cislo je zaporne"); 
       }else 
       {
         printf("Cislo je nula");
       }
   getch(); 
   return(0);
}

Neúplné

Obecný zápis vypadá takto: if (podmínka) příkaz_1; Je shodná s úplnou alternativou s tím rozdílem, že v ní chybí příkaz else. Je-li podmínka nepravdivá (nulová) pokračuje se v programu dále. V tomto programu se pomocí neúplné alternativy zjisti zda je číslo kladné, záporné nebo nula.

#include <stdio.h> 
int a; 
int main()
{ 
   printf("Zadej cislo: "); 
   scanf("%d",&a); 
   if (a>0) 
   {
      printf("Cislo je kladne"); 
   }if (a<0) 
   {
     printf("Cislo je zaporne");
   }if (a==0) 
   {
      printf("Cislo je nula"); 
   }
   getch();
   return(0);
}

Vícenásobné

Zápis vícenásobné alternativy vypadá následovně: switch(selektor) { case hodnota_1: příkaz_1; break; case hodnota_2: příkaz_2; break; … case hodnota_n: příkaz_n; break; default: příkaz; } Vícenásobná alternativa switch neboli přepínač se vyhodnocuje tak, že se porovná selektor s celočíselnými nebo znakovými hodnotami ze seznamu a dojde-li ke shodě provede se příslušný příkaz. Příkaz break způsobí ukončení provádění příkazu switche. Za jeho absence by se provedly příkazy následujících case. Příkaz default není povinný a provede se v případě že podmínce nevyhovuje žádná hodnota za nabízených case. Pomocí vícenásobné alternativy můžeme zpracovat program takovéhoto zadání: Uživatel zadá počet mobilů, které chce zakoupit. Cena za jeden mobil je 6999Kč, při odběru dvou nebo tří mobilů je cena 5999Kč,při odběru 4,5, nebo 6 kusů je cena 4999Kč a při odběru nad 7 kusu je cena jednoho 3999Kč. Určete celkovou částku, kterou kupující zaplatí.

#include <stdio.h> 
int pocet,cena; 
int main(){ 
   printf("Zadej pocet mobilu: "); 
   scanf("%d",&pocet); 
   switch(pocet) {}{
      case 1:cena=6999; 
             break; 
      case 2:
      case 3:cena=5999; 
             break; 
      case 4:
      case 5: 
      case 6:cena=4999; 
             break; 
     default:cena=3999;
   } 
   printf("Cena za kus: %dKc\n",cena); 
   printf("Celkova cena: %dKc\n",pocet*cena); 
   getch(); 
   return(0);
}

Cykly

Cykly používáme v případě, že potřebujeme nějakou činnost provádět opakovaně. U cyklů používáme nějakou podmínku, která říká, kolikrát se daná činnost provede. Rozlišujeme dva typy cyklů: s podmínkou na začátku a s podmínkou na konci.

Cyklus s podmínkou na konci

Cyklus s podmínku na konci se zapisuje pomocí klíčových slov do a while. Jeho obecný zápis vypadá následovně: do příkaz; while(podmínka); Pracuje tak, že se provede tělo cyklu a poté se vyhodnotí podmínka, je-li pravdivá (nenulová) opakuje se tělo cyklu. Je-li podmínka nepravdivá (nulová) cyklu se ukončí. Tento cyklus se používá v případech, kdy potřebujeme tělo cyklu vykonat alespoň jednou. Příkladem cyklu s podmínkou na konci může být zjištění ciferného součtu zadaného čísla:

#include <stdio.h> 
int n, cislo; 
int main(){ 
   printf("Zadej cislo pro vyocet ciferneho souctu \n"); 
   scanf("%d",&n); 
   do {}
   {
      cislo=n%10+cislo; 
      n=n/10;
   }
   while((n%10)!=0); 
   printf("Ciferny soucet je %d",cislo); 
   getch(); 
   return(0);
}

Cyklus s podmínkou na začátku

Cyklus s podmínku na začátku se zapisuje pomocí klíčového slova while. Jeho obecný zápis vypadá následovně: while(podmínka) příkaz; Nejprve se vyhodnotí podmínka. Když je pravdivá (nenulová) je provedeno tělo cyklu. Když je nepravdivá (nulová) cyklus se ukončí Cyklus while se dá například použít pro výpočet faktoriálu zadaného čísla.

#include <stdio.h> 
int n, faktorial=1; 
int main()
{ 
   printf("Zadej cislo pro vyocet faktorialu \n"); 
   scanf("%d",&n); 
   if(n<0) 
   {
      printf("Faktorial zaporneho cisla neni mozny!"); 
   }else{
      while(n>0){
         faktorial=faktorial*n; 
         n--;
      }
   printf("Faktorial je %d",faktorial); 
   }
   getch(); 
   return(0);
}

Cyklus s pevným počtem opakováním

Cyklus s podmínku na začátku se může zapsat také pomocí klíčového slova for. Jeho obecný zápis vypadá takto: for(inicializace; podmínka; iterace) příkaz; Cyklus for pracuje tak, že se nejprve inicializuje proměnná, poté se vyhodnotí podmínka (je většinou tvořena relačními operátory) a při její pravdivosti se provede tělo cyklu. Při nepravdivosti se cyklus ukončí. Pak se provede iterace (nejčastěji inkrementace či dekrementace). Použijeme jej tehdy, známe-li předem počet opakování průchodů. V cyklu for můžeme inicializaci, podmínku a iteraci vynechat. Pak vytvoříme nekonečný cyklus ve tvaru: for(;;) příkaz; Cyklus for může mít třeba použití v programu ve kterém máme načíst celé kladné číslo a zjistit kterými čísly je celočíselně dělitelné.

#include <stdio.h> 
int i, cislo; 
int main()
{
   printf("Zadej cislo pro zjisteni delitelu \n"); 
   scanf("%d",&cislo); 
   for(i=1;i<cislo;i++) 
   {
      if(cislo%i==0) 
      {
        printf("%d ",i); 
      }
   }
   getch();
   return(0);
}

Break a continue

Tyto příkazy lze použít ve všech cyklech. Mění provádění cyklu. break Způsobí ukončení cyklu. Díky příkazu break dochází k větší efektivitě a pružnosti cyklů. Můžeme například upravit příklad uváděný u cyku for a vyjmout všechny jeho atributy.

#include <stdio.h> 
int i=1, cislo;
int main()
{
   printf("Zadej cislo pro zjisteni delitelu \n"); 
   scanf("%d",&cislo); 
   for(;;){
    if(i>cislo) break; 
    if(cislo%i==0) 
    {
       printf("%d ",i); i++;
    }
   } 
   getch(); 
   return(0);
}

continue

Ukončí aktuální průchod cyklem. Cyklus není ukončen a pokračuje se dalším průchodem cyklu. goto Způsobí nepodmíněný skok na návěští. Není příliš používaný, jelikož porušuje zásadu strukturovaného programování. Dal by se použít třeba takto: goto návěští; příkazy_které_se neprovedou návěští: příkaz;

Funkce

unkce je základní programovou jednotkou v jazyce C. Každý program obsahuje alespoň jednu funkci – main(). Obecně by se definice funkce dala zapsat takto: návratový_typ identifikátor_fce(formální parametry) { . . . return návratová_hodnota; } Definice funkce se skládá z hlavičky a těla. Pokud není určen návratový typ je implicitně int. Formální parametry jsou lokální proměnné platné jen v dané funkci. Čtou se zprava do leva a proto je nutné u každého uvést datový typ. Formální parametry se proto zapisují takto: dat_typ identifikátor_1, dat_typ identifikátor_2, … Jsou volány hodnotou, tedy neovlivňují hodnotu načtených skutečných parametrů. Pro volání adresou (odkazem), tedy pro předání hodnoty skutečným parametrům ve funkci užíváme pointery. Příkaz return ukončí funkci a předá nepovinnou návratovou hodnotu programové jednotce, která funkci vyvolala. Funkce může obsahovat libovolné množství příkazů return nebo ani jeden. Funkci můžeme definovat před funkcí main() nebo za main(). Definujeme-li funkci za main() musíme uvést deklaraci funkce v hlavičce programu, aby kompilátor při průchodu programem věděl o použití funkce. Deklarace vypadá stejně jako hlavička definice funkce se středníkem: návratový_typ identifikátor_fce(formální parametry); V programu pak funkci zavoláme takto: identifikátor_fce(skutečné parametry); Následujíc příklad ukazuje jak vytvořit funkci definovanou před main(). Funkce vrací absolutní hodnotu zadaného čísla.

#include <stdio.h>
float abs_hodnota(float x){
   if(x>0) return(x); 
   else return(-x);
} 
float cislo; 
int main()
{ 
   printf("Zadej cislo pro absolutni hodnotu\n"); 
   scanf("%f", &cislo); 
   printf("Absolutni hodnota cisla %.4f je %.4f", cislo, abs_hodnota(cislo)); 
   getch(); 
   return;
}

V dalším programu je funkce definována za main(), tudíž je v programu deklarace funkce.

#include <stdio.h> 
int nsd(int a, int b); 
int cislo1, cislo2; 
int main(){ 
   printf("Zadej dve cela kladna cisla\n"); 
   scanf("%d %d", &cislo1, &cislo2); 
   if(cislo1>0 && cislo2>0) 
   {
     printf("Nejvetsi spolecny delitel cisla %d a %d je %d", cislo1,
     cislo2, nsd(cislo1, cislo2)); 
   }else printf("Bylo zadano zaporne cislo!"); 
   getch(); 
   return;
} 
int nsd(int a, int b)
{ 
   int i, max; 
   for(i=1;i<=((a<b)?a:b);i++) 
   {
      if ((a%i==0)&&(b%i==0)) max=i; 
   }
   return(max);
}

Pokud chcete aby funkce nevracela žádnou hodnotu, čili vytvořit proceduru, stačí uvést jako návratovou hodnotu funkce datový typ void jako v následujícím příkladu

#include <stdio.h>
void oddelovac();
int main()
{
   oddelovac(); 
   printf("Cecko je fajn\n");
   oddelovac(); 
   printf("A mam ho strasne rad\n"); 
   oddelovac(); 
   getch(); 
   return;
} 
void oddelovac(){
   int i; 
   for(i=1;i<=20;i++) printf("*"); 
   printf("\n");
   return;
}

Rekurzivní funkce

Je funkce která při svém běhu volá sama sebe. Musí obsahovat podmínku která určí kdy se má vnoření zastavit.

#include <stdio.h> 
int faktorial(int n); 
int cislo; 
int main(){ 
   printf("Zadej ciso pro faktorial\n"); 
   scanf("%d", &cislo); 
   if(cislo<0) printf("Faktorial zaporneho cisla neni mozny!"); 
   else printf("Faktorial je %d", faktorial(cislo)); 
   getch(); 
   return;
} int faktorial(int n){
   if(n>1) return(n*faktorial(n-1)); 
   else return(1);
}

Preprocesor

Preprocesor jazyka C slouží k předpřipravení zdrojového kódu pro kompilátor. Jeho úkolem je odstraňování komentářů, vkládání hlavičkových souborů, rozvoj maker a provádění podmíněného překladu. Činnost preprocesoru řídíme pomocí tzv. direktiv preprocesoru. Direktiva preprocesoru není příkaz jazyka C, proto za ní neuvádíme středník. Každá direktiva je uvozena znakem ‚#‘ , který musí být uveden hned jako první znak na řádku. Tak určíme, že zbytek řádku je určen preprocesoru. Chceme li ovšem ať preprocesor zpracuje i text na druhém řádku musíme přidat na konec řádku znak ‚\‘.

Makra

Makro je text, který je v podstatě zdrojovým kódem. Jako se zdrojovým kódem se s ním však
pracuje až po zpracování preprocesoru, kdy se výskyt identifikátoru makra ve zdrojovém kódu nahradí textem makra. Pro definici makra používáme direktivu #define Máme dva typy maker: bez parametrů a s parametry

Makra bez parametrů

Používají se pro definování symbolických konstant, kdy místo konstanty používáme nějaké symbolické jméno. Ustáleným pravidlem je psát identifikátor makra bez parametru velkými písmeny. Zápis vypadá takto: #define identifikátor_makra text_makra Volání makra bez parametrů se provádí takto: identifikátor_makra

Makra s parametry

Obsahují formální parametry se kterými se v textu makra dále pracuje. Používají se mnohdy místo funkcí. Narozdíl od funkcí jsou rychlejší a za formální parametry mohou být načteny hodnoty libovolných datových typů. Ustáleným pravidlem je psát identifikátor malými písmeny. Obecný zápis je takovýto: #define identifikátor_makra(seznam formálních parametrů) text_makra Volají se následovně: identifikátor_makra(seznam skutečných parametrů) V tomto programu je shrnuta práce s makry na jednoduchém výpočtu objemu válce. Obsahuje makra s a bez parametru, vnořování maker a zápis makra na více řádků

#include <stdio.h> 
#define PI 3.141592653 
#define na_2(x) (x)*(x) 
#define obem_valce(r,v) PI*na_2(r)*v 
#define oddelovac for(i=1;i<=40;i++) printf("*");\ 
    printf("\n");
float polomer,vyska; 
int i; 
int main(){
  oddelovac printf("Zadej polomer a vysku valce\n"); 
  oddelovac scanf(" %f %f",&polomer,&vyska); 
  oddelovac printf("Obem valce je %.2f * %.2f * %.2f =
  %.2f\n",PI,na_2(polomer),vyska,obem_valce(polomer,vyska)); 
  oddelovac getch(); 
  return;
}

Vkládání souborů

Proto abychom mohli do našeho souboru se zdrojovým kódem připojit další soubory, ať už knihovny funkcí či další části našeho programu používáme tyto dva zápisy příkazu #include: #include #include „název_souboru“ První zápis znamená že soubor název_souboru je hledán ve standardním adresáři pro include. Takto se zpravidla začleňují standardní hlavičkové soubory. Není-li soubor nalezen, je ohlášena chyba. Druhý zápis znamená že soubor název_souboru je hledán v pracovním adresáři. Není-li tam nalezen, postupuje se podle první možnosti. Takto se zpravidla začleňují uživatelské hlavičkové soubory.

Alokace paměti

Alokace paměti je vymezení místa v paměti pro proměnnou. Každé proměnné musí být během své existence přidělen paměťový prostor, který je dán datovým typem. Jméno proměnné je vlastně symbolická adresa tohoto prostoru. Data dělíme na: statické a dynamické

Statické

sou to data u nichž známe v době překladu jejich velikost a identifikátor. Jsou to globální proměnné, které mají tu vlastnost, že se automaticky nulují, vznikají spuštěním programu a zanikají na jeho konci. Ke statickým proměnným se řadí také lokální proměnné, které mají tu vlastnost, že nejsou automaticky nulované a jejich platnost končí koncem funkce či bloku.

Dynamické

Dynamické data jsou data které nemají předem stanovenou velikost. Alokaci provádíme speciálním příkazem za běhu programu. Dynamické proměnné nemají svůj identifikátor. Přistupujeme k nim pomocí pointerů.

Paměťové třídy

Kromě identifikátoru a datového typu jsou proměnné určeny ještě paměťovou třídou, které náleží. Paměťová třída určuje kde bude proměnná v paměti uložena, jakou bude mít viditelnost a jakouživotnost. Paměťové třídy se zapisují v následujícím formátu: název_pam_třídy datový_typ identifikátor_proměnné; Existují tyto paměťové třídy: auto, extern, statis, register auto Paměťová třída je implicitně používána pro všechny lokální proměnné. Paměť se pro ně alokuje automaticky až při vstupu do bloku, ve kterém jsou definovány. Po opuštění bloku je tato paměť zase uvolněna. Tato proměnná je viditelná jen v rámci bloku, ve kterém je definována. Existuje– li vedle této automatické proměnné i nějaká globální proměnná se stejným identifikátorem, je zastíněna automatickou proměnnou.

extern

Implicitní paměťová třída pro globální proměnné. Má využití při odděleném překladu. Je-li třeba, aby dva či více modulů sdílelo tutéž proměnnou v jednom souboru bude definována proměnná bez slova extern a ve všech ostatních zapíšeme klíčové slovo extern. Proměnné s paměťovou třídou extern nelze inicializovat! static Tato paměťová třída je použitelná jak pro lokální tak pro globální proměnné. Statické lokální proměnna je viditelná jen ve funkci, kde je definována. Paměť pro takovou proměnnou je alokována při spuštění dané funkce a uvolněna je až po skončení programu. Z toho vyplývá, že, máme-li statickou proměnnou a opustíme blok, ve kterém byla definována, tato proměnná nezaniká, pouze již není viditelná (ponechává si svou hodnotu mezi jednotlivými voláními funkce) Pro globální proměnné má paměťová třída static poněkud odlišný význam. Používá se při odděleném překladu. Při jejím použití by jsme nadefinovali globální neexportovatelnou proměnnou. To znamená že globální proměnné paměťové třídy static jsou viditelné pouze v modulu ve kterém jsou definovány. register Používá se pro lokální proměnné. Proměnná je viditelná pouze v bloku ve kterém je definována. Je alokována do registru, není-li v něm místo alokuje se do zásobníku. Pro nejasnost alokace nelze použít operátor adresy &. Jelikož třída register zvyšuje rychlost přístupu, používá se pro často používané proměnné (např. řídící proměnné cyklu). Program ukazuje použití modifikátoru register a static pro lokální proměnné.

#include <stdio.h> 
void fce(void); 
int main()
{ 
   register int i; 
   for(i=0;i<5;i++) fce(); 
   getch(); 
   return;
} 
void fce(void)
{ 
   static int x=0; 
   x++; 
   printf("Funkce byla volana %dx \n",x);
}

Pointery

Ukazatel (pointer) je v Céčku statická celočíselná proměnná obsahující adresu jiné statické či dynamické proměnné. Nese sebou současně informaci o datovém typu, který se na této adrese nachází. Pointer na proměnnou určitého datového typu se deklaruje pomocí operátoru dereference ‚*‘: datový_typ *identifikátor_pointeru; Uložení adresy do pointeru se liší dle toho zda pointer ukazuje na statickou či dynamickou proměnnou. Díky operátoru reference ‚&‘ uložíme do pointeru adresu statické proměnné: identifikátor_pointeru=&identifikátor_proměnné;

A takto do pointeru uložíme adresu a vyalokujeme prostor pro dynamickou proměnnou: identifikátor_pointeru=(datový_typ *)malloc(sizeof(datový_typ)); Výše uvedený zápis se dá přeložit následovně. Funkce malloc() je funkce, která alokuje paměťový prostor v haldě. Jejím parametrem je počet bytů potřebný pro alokaci. Ten jsme zjistili operátorem pro zjištění velikosti datového typu sizeof(). Jelikož funkce malloc() vrací ukazatel na datový typ void (generický pointer na libovolný datový typ) je nutné tento pointer přetypovat pomocí operátoru přetypování (datový_typ *). V případě, že se nepodaří požadovanou paměť alokovat, vrací funkce hodnotu NULL. Proto lze do programu zapsat následující test zda alokace proběhla: if(identifikátor_pointeru==NULL) printf(„Chybna alokace pameti\n“);
Pro samotné uložení hodnoty na místo kde ukazuje pointer se používá tento zápis: *identifikátor_pointeru=hodnota; Při použití pointeru na dynamickou proměnnou se musíme po ukončení práce s pointerem postarat o uvolnění paměti: free(identifikátor_pointeru); A proto aby pointer neodkazoval na místo, které již neexistuje měli bychom ho ukotvit: identifikátor_pointeru=NULL; Následující příklad ukazuje jak pracovat s dynamickými pointery.

#include <stdio.h> 
int main(){ 
   float *a,*b; 
   a=(float *)malloc(sizeof(float)); 
   b=(float *)malloc(sizeof(float)); 
   printf("Zadej dve cisla\n"); 
   scanf("%f %f",a,b); 
   (*a > *b)?printf("%f je vetsi nez %f \n", *a, *b):printf("%f je mensi nez %f \n",   *a, *b); 
   printf("Soucet: %.2f\n",*a+*b); 
   printf("Rozdil: %.2f\n",*a-*b); 
   printf("Soucin: %.2f\n",*a**b); 
   printf("Podil: %.2f\n",(*a)/(*b)); 
   getch(); 
   return;
}

Pointery a funkce

Pomocí pointerů realizujeme funkce které vracejí více hodnot. Realizuje se to pomocí
proměnných, které jsou vně funkce a my s nimi ve funkci můžeme pomocí pointerů pracovat neboli přidat jim určitou hodnotu. Hovoříme o formálních parametrech volaných adresou. V kapitole Funkce jsme vždy používali tzv. formální parametry volané hodnotou, které nemají vliv na skutečný parametr. Definice funkce, která vrací více hodnot by mohla vypadat takto: návratový_typ identifikátor_fce(formální parametry, dat_typ *pointer) { .. .
*pointer=výstupní_hodnota; return návratová_hodnota; }
A v programu by jsme takovouto funkci volali následovně: identifikátor_fce(skutečné parametry, &identifikátor_proměnné); Následující program demonstruje použiti pointerů realizujících návrat více hodnot z funkce.

#include <stdio.h> 
void vypocty(int a, int b, int *sou, int *roz, int *souc, float *pod); 
int main()
{ 
   int x,y,soucet,rozdil,soucin; 
   float podil; 
   printf("Zadejte prosim dve cela cisla\n"); 
   scanf("%d %d",&x,&y); 
   vypocty(x,y,&soucet,&rozdil,&soucin,&podil); 
   printf("%d + %d = %d\n",x,y,soucet); 
   printf("%d - %d = %d\n",x,y,rozdil); 
   printf("%d * %d = %d\n",x,y,soucin); 
   printf("%d / %d = %.2f\n",x,y,podil); 
   getch(); 
   return;
} 
void vypocty(int a, int b, int *sou, int *roz, int *souc, float *pod)
{ 
   *sou=a+b; 
   *roz=a-b; 
   *souc=a*b; 
   *pod=(float)a/b; 
   return;
}

Pole

Je strukturovaný homogenní datový typ. To znamená že, obsahuje několik prvků stejného datového typu se kterými můžeme pracovat. Pole je v podstatě pointer obsahující adresu nultého prvku pole. Může být statické či dynamické. Statické pole U statického pole je nutné znát počet prvků během překladu. Deklarujeme ho následovně dat_typ identifikátor[počet_prvků]; Pole může nabývat hodnot kteréhokoli základního datového typu. K hodnotám pole přistupujeme pomocí indexů. Jelikož C indexuje od nuly můžeme přistupovat k prvkům od indexu 0 až počet_prvků-1. Takový přístup by vpadal takto: identifikátor[index]

Hodnoty pole pod jednotlivými indexy jsou v paměti ukládány za sebou. Je třeba si uvědomit, že překladač jazyka C neprovádí kontrolu mezí. Proto je možné pracovat indexy pole, které jsou větší než námi nadefinovaný nejvyšší index. To ovšem může způsobit katastrofální následky, jelikož pracujeme s části paměti, která nebyla alokována. Pole je možno hned při deklaraci inicializovat: dat_typ identifikátor[počet_prvků]={hodnota_1, hodnota_2, …}; Chceme-li pole setřídit použijeme nějakou třídící metodu. Nejjednodušší, ale zároveň docela pomalou je Bubble Sort:

for(i=0; i<pocet_prvku-1;i++)
for(j=0; j<pocet_prvku-1;j++)
if(pole[j]<pole[j+1]){ pom=pole[j];
pole[j]=pole[j+1];
pole[j+1]=pom;
}

Dynamické pole

Není nutné znát během překladu počet prvků, můžeme je vyalokovat až při samotném běhu programu. Při překladu je ovšem nutné znát bázový typ pole. Deklaruje se stejně jako pointer, tedy takto: dat_typ *identifikátor; Alokace pole se obecně zapisuje následně: identifikátor=(datový_typ *)malloc(sizeof(datový_typ)*počet_prvků); Samotná práce s dynamickým polem je shodná s prací se statickým polem. Dynamické pole ovšem musíme jakožto dynamickou proměnnou uvolnit: free(identifikátor); a také zakotvit: identifikátor=NULL; Příklad pro práci s dynamickým polem je obdoba příkladu pro statické pole:

#include <stdio.h> 
int main()
{ 
   int i,j,*pole,pocet,max,min,sum=0,pom; 
   printf("Zadej pocet prvku pole: "); 
   scanf("%d",&pocet); 
   pole=(int *)malloc(sizeof(int)*pocet); 
   printf("Zadavej prvky pole: \n"); 
   for(i=0;i!=pocet;i++) scanf("%d",&pole[i]); 
   max=pole[0]; 
   min=pole[0]; 
   for(i=0;i!=pocet;i++) 
   { 
      if(pole[i]>max) max=pole[i]; 
      if(pole[i]<min) min=pole[i]; 
      sum+=pole[i]; 
   }
   printf("\nMaximum je %d\n",max); 
   printf("Minimum je %d\n",min); 
   printf("Stredni hodnota je %.2f\n",(max+min)/2.0); 
   printf("Aritmetricky prumer je %.2f\n",(float)sum/i);
   for(i=0;i!=pocet-1;i++) 
   for(j=0;j!=pocet-1;j++) if(pole[j]>pole[j+1]) { 
      pom=pole[j+1]; 
      pole[j+1]=pole[j]; 
      pole[j]=pom; 
   }
   printf("\nSetrizene pole: "); 
   for(i=0;i!=pocet;i++) printf("%d ",pole[i]); 
   free(pole); 
   pole=NULL; 
   getch(); 
   return;
}

Pole a funkce

Je-li proměnná typu pole (tzn. ukazatel na první prvek) parametrem funkce užíváme adresu pole
(volání odkazem). To proto aby se změna pole zachovala i po návratu z funkce. Obecný zápis hlavičky funkce jejíž parametr je statické pole je takovýto: dat_typ id_fce(dat_typ pole[], int pocet, …) Hlavička funkce jejíž parametr je dynamické pole s e zapisuje obdobně: dat_typ id_fce(dat_typ *pole, int pocet, …) Z těchto zápisů je zřejmé, že je nutné zavést jako parametr funkce taky celočíselnou proměnnou pocet, která uchovává informaci o počtu prvků pole a slouží tak pro kontrolu mezí. Volání funkce v hlavní části programu se provádí takto: id_fce(pole,pocet, …); Pro ilustraci pole jakožto parametru funkce je užit příklad pro statické pole s tím, že načítání, výpis, setřízení a zjišťování maxima a minima je zajištěno funkcemi.

#include <stdio.h> 
#define POCET 8 const nil=0; 
void nacti(int pole[], int poc); 
void vypis(int pole[], int poc); 
void zjisti(int pole[], int poc, int *max, int *min, int *sum); 
void setrid(int pole[], int poc); 
int main()
{ 
	int pole[POCET],max,min,soucet=0; 
	printf("Zadej prvky pole:\n"); 
	nacti(pole,POCET); max=pole[nil];
	min=pole[nil]; 
	zjisti(pole,POCET,&max,&min,&soucet); 
	printf("\nMaximum je %d\n",max); 
	printf("Minimum je %d\n",min); 
	printf("Stredni hodnota je %.2f\n",(max+min)/2.0); 
	printf("Aritmetricky prumer je %.2f\n",(float)soucet/POCET); 
	printf("\nSetrizene pole:\n"); 
	setrid(pole,POCET); 
	vypis(pole,POCET); 
	getch(); 
	return;
} 
void nacti(int pole[], int poc)
{
	int i; 
	for(i=nil;i<poc;i++) scanf("%d",&pole[i]); 
	return;
} 
void vypis(int pole[], int poc)
{
	int i; 
	for(i=nil;i<poc;i++) printf("%d ",pole[i]); 
	return;
} 
void zjisti(int pole[], int poc, int *max, int *min, int *sum)
{
	int i; 
	for(i=nil;i!=poc;i++) { 
		if(pole[i]>*max) *max=pole[i];
	if(pole[i]<*min) *min=pole[i]; 
	*sum+=pole[i]; 
	}
	return;
} 
void setrid(int pole[], int poc) 
{
	int i,j,pom; 
	poc--; 
	for(i=nil;i!=poc;i++) 
	for(j=nil;j!=poc;j++) 
	if(pole[j]>pole[j+1]) { 
		pom=pole[j+1]; 
		pole[j+1]=pole[j]; 
		pole[j]=pom; 
	}
	return; 
}

Matice

Je to pole polí, přičemž prvky jsou uloženy v paměti za sebou. Indexuje se od nuly. Deklaruje se takto: dat_typ id_matice[řádky][sloupce]; Inicializuje se tímto způsobem: id_matice[][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12},…}Z tohoto zápisu vyplývá že uvedení počtu sloupců je povinné, uvedení počtu řádků je nepovinné.

Dynamická matice se realizuje třemi způsoby: jako pole pointerů, pointer na pole nebo pointer na pointer.

Pointer na pole

Je realizováno pomocí ukazatele který ukazuje na souvislý blok v haldě. Při deklaraci je nutné znát počet sloupců na řádek. Deklarace je takováto: dat_typ (id_pole)[počet_sloupců]; Alokace v dynamické paměti se zapisuje takto: id_pole=(typ ()[])malloc(sizeof(typ)počet_sloupcůpočet_řádků); Po ukončení práce je nutné místo v paměti odalokovat a pointer ukotvit: free(id_pole); id_pole=NULL;

#include <stdio.h> 
#define S 3
int main()
{ 
	int i,j; 
	int (*matice)[S]; /* pocet sloupcu je znam pri prekladu */
	srand((long)time(NULL)); 
	printf("\nMatice - pointer na pole:"); 
	printf("\n");
	matice=(int(*)[])malloc(2*S*sizeof(int));
	for (i=0;i<2;i++)
	{
		for (j=0;j<S;j++)
		{
			matice[i][j]=rand()%100; printf("%4d",matice[i][j]);
		} 
		printf("\n");
	}
	getch(); 
	return 0;
}

Pointer na pointer

Je to pointer který ukazuje na dynamické pole pointerů v haldě (symbolizuje řádků), jednotlivé prvky pole obsahují pointery ukazující na další dynamické pole (symbolizuje sloupce). Jednotlivé řádky nemusí být v paměti uloženy za sebou. Deklaruje se takto: dat_typ **id_pole; Pro alokaci dynamického pole symbolizující počet řádků se užije tento zápis: id_pole=(typ **)malloc(sizeof(typ *)*počet_řádků); Alokace jednotlivých řádků se zapíše následně: id_pole[index]=(typ *)malloc(sizeof(typ)*počet_sloupců); Ukončení-li práci odalokujeme oblast v dynamické paměti, která zabírá jednotlivé řádky: free(id_pole[index]); Poté musíme odalokovat pole obsahující pointery: free(id_pole); A pak už jen ukotvit pointer id_pole=NULL;

#include <stdio.h> 
int main()
{ 
	int i,j; int **matice; /* pocet radku, sloupcu neni znam pri prekladu */
	srand((long)time(NULL)); 
	printf("\nMatice - pointer na pointer:"); 
	printf("\n");
	matice=(int**)malloc(2*sizeof(int*)); /* radky */
	matice[0]=(int*)malloc(3*sizeof(int)); /* pocet prvku na radce */ 
	matice[1]=(int*)malloc(3*sizeof(int));
	for (i=0;i<2;i++)
	{ 
		for (j=0;j<3;j++)
		{
			matice[i][j]=rand()%100; 
			printf("%4d",matice[i][j]);
		} 
		printf("\n");
	}
	getch(); 
	return 0;
}

Řetězce

V jazyku C není definován datový typ řetězce, místo toho je využíváno pole znaků ukončené nulovým znakem, čili znakem s ASCII hodnotou nula (Zapisujeme ho takto: ‚\0‘). Skutečnost ukončení nulovým znakem znamená, že musíme nadefinovat pole o jeden byte delší, aby zbylo místo pro nulový znak. Řetězec deklarujeme takto: char id_řetězce[velkost]; Inicializovat lze dvěma způsoby, buď takto: char id_řetězce[]={‚a‘,’h‘,’o‘,’j‘,’\0′}; nebo takto: char id_řetězce[]=“ahoj“; Tento zápis je zcela ekvivalentní s předchozím. Pro pole je vyhrazeno 5 bytů, do kterých je uložen řetězec „ahoj“ včetně nulového znaku. Načítání a výpis řetězce můžeme provádět pomocí scanf() a printf(), ale taky pomocí funkcí přímo určených pro čtení a výpis řetězců gets() a puts(). Funkce gets() při načítání čte narozdíl od scanf(), která načítá pouze po první výskyt bílého znaku, vše co zapíšeme. Práce s řetězcem je shodná jako práce s polem, lze tedy například užít pointerovou aritmetiku.

Funkce pro řetězce

Pro řetězec jsou v C předdefinovány funkce strcpy(),strcat(),strcmp(),strlen(). Pro jejich použití je nutno připojit hlavičkový soubor string.h.

strcpy() Slouží pro překopírování obsahu zdroje do cíle, přičemž zdroj zůstane nezměněn. Musíme zajistit to aby byl cíl dostatečně velký. Má obecný tvar: strcpy(zdroj,cíl);

strcat() Slouží pro přidávání obsahu zdroje k obsahu cíle (zřetězení). Musíme zajistit to, že je cílové pole dostatečně velké. Obecný zápis: strcat(zdroj,cíl);

strcmp() Funkce porovnává dva řetězce. Řetězce jsou porovnávány lexikograficky, tj. ve slovníkovém pořadí. Jsou-li řetězce shodné, vrací funkce nulu. Je-li první větší než druhý, vrací 1 a je-li první menší než druhý vrátí funkce -1. Obecný zápis: strcmp(řetězec_1,řetězec_2);

strlen() Tato funkce vrací délku řetězce ve znacích. Do délky řetězce se nezapočítává koncový nulový znak. Zapisuje se následně: strlen(řetězec); Příklad uvedený níže ukazuje varianty načítání řetězce, zjišťování délky a porovnání.

#include <stdio.h> 
#include <string.h> 
int main()
{ 
	int indikace; 
	char retezec_1[20],retezec_2[20],vysledek; 
	gets(retezec_1); 
	scanf("%s",retezec_2); 
	printf("retezec_1 (%s) ma delku %d\n",retezec_1,strlen(retezec_1)); 
	printf("retezec_2 (%s) ma delku %d\n",retezec_2,strlen(retezec_2)); 
	indikace=strcmp(retezec_1,retezec_2); 
	if(indikace==0) puts("Retezce jsou shodne"); 
	else if (indikace==1) puts("retezec_1 je lexikograficky vetsi nez retezec_2"); 
	else if (indikace==-1) puts("retezec_2 je lexikograficky vetsi nez retezec_1");
	getch(); 
	return;
}

Soubory

V programovacím jazyku C se provádí diskové I/O pomocí logického rozhraní nazývaného datový proud. Datové proudy mají podobné vlastnosti a jsou zpracovávány stejnými I/O funkcemi. Soubor je skutečný fyzický výskyt, který přijímá nebo poskytuje data. V C existují dva typy souborů. Textový a Binární, liší se použitím I/O funkcí. Základní rozdíl mezi těmito dvěma typy souborů je v tom, že v binárním souboru jsou data ukládána stejným způsobem jako v paměti. Kdežto do textového souboru se musí data převést na posloupnost znaků. V hlavičkovém souboru stdio.h je pro práci s nimi zaveden datový typ FILE, který je strukturou obsahující různé informace o souboru, například velikost, aktuální pozici a jeho přístupové režimy, které určují jak k souboru přistupovat. Proměnnou soubor si nadeklatujeme jako ukazatel na typ FILE. FILE *id_souboru Před tím než budeme se souborem pracovat musíme ho nejdřív otevřít. To provedeme pomocí funkce fopen(), která vrací ukazatel na daný soubor. Je-li tato funkce neúspěšná, vrací NULL. id_souboru=fopen(„jméno.přípona“,“režim“); Pro textové souory existují následující režimy:

režimvýznamrežim pro binární soubory
rotevře textový soubor pro čtenírb
wvytvoří textový soubor pro zápis (přepíše existující)wb
aotevře textový soubor pro připisováníab
R+otevře textový soubor pro čtení/zápisrb+
W+vytvoří textový soubor pro čtení/zápiswb+
A+otevře textový soubor pro čtení/připisováníab+

Pokud soubor neexistuje, při většině režimech se vytvoří. Pouze při r,r+,rb,rb+ se soubor nevytvoří a fopen() selže. Jelikož operace otevření nemusí proběhnout je vhodné ji ošetřit testem a raději používat tento zápis: if(id_souboru=fopen(„jméno.přípona“,“režim“)==NULL){printf(„Chyba pri otevreni souboru“); return;} Pro ukončení práce se souborem použijeme funkci fclose(), která zavře soubor a odpojí datový proud. Je nutné soubor zavřít jestliže chceme ať se v něm projeví změny. fclose(id_souboru); Při úspěchu vrací nulu, při chybě vrací symbolickou konstantu EOF. Pro kontrolu úspěšnosti je vhodnější používat tento zápis: if(fclose(soubor)==EOF){printf(„\nChyba pri uzavreni souboru“); return;} Další funkce souborového systému Patří mezi ně funkce rename(), remove(), rewind(), feof() a fflush().

rename() Slouží pro přejmenování souboru. Obecně se zapisuje: rename(„staré_jméno“,“nové_jméno“); Při úspěchu vrací funkce nulu, při neúspěchu nenulovou hodnotu.

remove() Smaže daný soubor. Zápis je: remove(„jméno_souboru“); Při úspěchu vrací funkce nulu, při neúspěchu nenulovou hodnotu.

rewind() funkce přesune aktuální pozici v souboru na jeho začátek.

rewind(id_souboru); Je bez návratové hodnoty jelikož každý úspěšně otevřený soubor lze nastavit na začátek.

feof() Tato funkce se používá k zjišťování konce souboru. Je-li aktuální pozice na konci vrací nenulovou hodnotu. Jestliže ne vrací nulu. feof(id_souboru);

fflush() Funkce slouží k vyprázdnění diskového bufferu. fflush(datový_proud) Využívá se pro vyprázdnění standardního datového proudu pro čtení z klávesnice stdin (standardní vstup).

Pro souborový vstup/výstup znaku se užívají funkce getc(), putc(). Tento postup se užívá jak pro textové, tak pro binární soubory getc() nebo fgetc() Tato funkce je určena pro vstup znaků ze souboru. Zapisuje se takto: fgetc(id_souboru); Má jediný parametr typu ukazatel na FILE, návratovou hodnotou této funkce je kód znaku, přečtený z určeného souboru. Při konci souboru či chybě vrací symbolickou konstantu EOF. putc() nebo fputc() Funkce je určena pro výstup znaků do souboru. fputc(znak,id_souboru); Má jako první argument kód znaku, který má být zapsán do souboru, který je identifikován druhým parametrem. Návratová hodnota funkce je kód zapsaného znaku, nebo EOF pokud při výstupu došlo k chybě. V následující ukázce nejprve zapíšeme do souboru text a poté se vytvoří kopie tohoto souboru.

#include <stdio.h> 
#include <conio.h>
int main(void)
{ 
	FILE *fr,*fw; char c;
	fw=fopen("original.txt","w"); 
	printf("Zapiste text ukonceny '.'\n"); 
	do 
	{ 
		scanf("%c",&c); 
		putc(c,fw);
	} while (c!='.'); 
	fclose(fw);
	fr=fopen("original.txt","r"); 
	fw=fopen("kopie.txt","w"); 
	while (feof(fr)==0) putc(getc(fr),fw); 
	fclose(fr); 
	fclose(fw);
	printf("\nSoubor byl zkopirovan!"); 
	fflush(stdin); 
	getch(); 
	return(0);
}
Posted in: Vývoj počítačů

Historie OS, od počátků k Windows 7

Tato prezentace je určena jako rychlý přehled hitorie operačních systémů nejen Microsoftu. Novějším operačním systémům (Windows 8 novějším) se na tomto webu věnuji podrobněji a proto původní prezentaci z roku 2010 o tyto systémy neaktualizuji.

Poznámky k prezentaci

V úvodu si musíme uvědomit, co je to ten operační systém. Pro naše potřeby bude stačit stručná charakteristika uvedená zde a na dalších snímcích. Hodně zjednodušeně by se také dalo říci, že hardware je tělem a OS duší počítače.
Ke struktuře, kterou vidíte, musíme ještě připočítat zavaděč systému, který ovšem většinou není součástí systému. Tato struktura je velmi stručná, podrobnější naleznete na webu, kde jsou vysvětleny i pojmy vztahující se k tématice OS.
Vznikly tak první operační systémy, nejprve firmy IBM, která v té době měla téměř monopol na sálové počítače (a jiné v té době nebyly). Roku 1960 však firma Digital Equipment Corporation (DEC) vytvořila první komerční počítač vybavený obrazovkou a klávesnicí (tzv. obrazovkovým terminálem). Se vznikem minipočítačů v polovině 60. let, což byly menší stroje, které nevyžadovaly tak specializovanou obsluhu jako mainframe a byly rovněž vybaveny obrazovkovým terminálem, vyvstala potřeba operačních systémů tak, jak je známe dnes. Všechny systémy uvedené v přehledu jsou určeny pro sálové počítače. Do roku 1981 jsme neznali standartní OS, ale vše fungovalo na bázi Basic.Do dnešních dnů se nám skrytě dochoval UNIX.
CP/M Tento systém zavedl některé podstatné věci, bez kterých by nebyl možný rozvoj Windows, Linux ani Mac OS. Lze jej zařadit do rodiny systémů, které stály u zrodu Linux, protože užívají podobné jádro, ale díky povaze MS DOS i Windows.
MS-DOS nebyl skutečným produktem Microsoftu. V zásadě se jednalo o mírně upravený CP/M, jehož původní verze dokonce na prvních PC fungovala. Proti MS-DOSU zkrýval Unix výhodu v tom, že dokázal obsluhovat více uživatelů a programů v reálném čase. MS-DOS komunikuje prostřednictvím příkazového řádku. Firma IBM nebyla spokojena se systémem MS-DOS a proto začala vyvíjet vlastní PC-DOS, který se lišil jen v maličkostech. Ona i spousta dalších firem vyvíjela Dosy z niž nejvýznamnější byl DR-DOS. Ve stejné době firma Apple vyvinula systém s grafickým uživatelským rozhraním (podobná platforma jako Windows 1.0) a byl celý 32 bitový, narozdíl od 16 bitového PC.
Ještě před nástupem Windows zaznamenalo úspěch rozhraní firmy hp, které bylo graficky dost podobné, ale bylo převálcováno Windows na plné čáře.
Nové ovladače byly především grafické, na myši, klávesnice, tiskárny atd. Okna jsou řazeny do formy. Ukončením správce oken se mohl člověk vrátit do MS DOS.
Požadavky systému: MS-DOS 3.0 nebo vyšší, 512K paměti nebo více, grafická karta, disketová mechanika a pevný disk. Propracovanější klávesové zkratky (potržené písmeno v nabídkách). Vývojářská podpora se podstatně zvýšila s touto verzí. Windows 2.03 byly vydány v lednu 1988.
3.1 Systém podporoval české jazykové nástroje. 1. verze windows 3.0 byla vydána roku 1990.¨Správce programů umožňoval vytvářet ikony programů, seskupovat je, vyvářet textová menu atd., jeho ukončení znamenalo návrat do dosu. Chyba jediné aplikace v kooperativním multitaskingu mohla zblokovat chod celého systému, tato bolest provázela všechny 16 bitové Windows. Programové vybavení: Správce souborů (winfile.exe) umožňoval správu souborů a adresářů (podobal se dnešnímu Průzkumníku – každé okno obsahovalo dvě části – strom složek a obsah aktuální složky). Kopírování probíhalo přes přez schránku, bylo podporováno filtrování.

Windows 3.1x obsahovaly různé základní aplikace: Poznámkový blok (notepad.exe), Write (write.exe, dnešní WordPad), Malování (Paintbrush, pbrush.exe) atp. Obsahovaly také Windows Media Player (uměl přehrát WAV, MIDI a AVI), Přehrávač CD a Záznam zvuku (ten je stejný dodnes, dříve sndrec.exe, v např. WinXP sndrec32.exe). Nástroj Ovládací panel (control.exe) sloužil ke konfiguraci Windows. Mohlo to být např. barevné schéma, nastavení myši a klávesnice, instalace ovladačů, ale také celkem dost podrobné nastavení portů a podobně.

3.1 NT Jde o systém, který vyšel těsně po 3.11 a je jakousi spojnicí 3.11 a 95, která na rozdíl od obou jmenovaných systémů pracuje na zcela novém, bezdosovém jádře. Toto jádro je určeno do firem a na servery a až po Windows XP to platilo na 95%. (pro XP již ne, protože ty na stejné technologii jádra byly určeny již i do domácností).
4 NT Vydáno bylo 16 servisních balíčků ten poslední s označením 16a byl vydán v roce 1999. Jde o systém, který spojuje 95 a 2000. Některé technologie a aplikace přebírají 98, které vychází na dosovém jádře o 2 roky později. Celkově se systémy NT vyvíjejí samostatně, nezávisle na systémech s dosovým jádrem. 98 Systémové požadavky Procesor 486 DX 66Mhz nebo vyšší minimálně 16 MB operační paměti, 24MB doporučeno Místo na disku: Ze systému Windows 3.1 nebo 95: 120-295 MB(obvykle 195 MB) Nová instalace – FAT16: 165-300 MB(obvykle 225) Nová instalace – FAT32: 140-220 MB(obvykle 175) Windows 98 neumí obsloužit paměť nad 512 MB. Nejvýkonnější sestava pro Windows 98SE Základní deska s chipsetem nForce 3 Ultra se Socketem 939 (na žádné variantě nForce 4 už Windows 98 nefungují!) Procesor AMD FX-57 (2,8 GHz) 1 GB operační paměti (jen s použitím Himemx.exe) jediné grafická karta do slotu AGP 8x – ATI Radeon 9800 (neoficiálně až ATI Radeon X850) nebo nVidia GeForce 6800 137 GB pevný disk 95 Pracovním názvem těchto windows je Chicago. Bylo již upuštěno od podpory starších 16bitových x86 procesorů. Windows 95 používá ke spuštění MS-DOS 7.0, který je v něm obsažen, ale většinou je před uživateli ukrytý. Windows 95 se stal prvním produktem Windows pevně svázaným s určitou verzí operačního systému DOS. přestává být starší 32bitový přístup k disku přes BIOS používán. To mimo jiné redukuje roli MS-DOS na pouhý zavaděč pro chráněný mód jádra Windows. Tímto systémem systém předbíhá Microsoft Apple a IBM, která se snaží držet při životě BeOS 5. verzí, o celé kolo díky podpoře 32 bitů a definitivně si dělá ,,Monopol“ na OS. (většinové postavení na trhu, nikoliv plně monopol, protože konkurence existuje ještě dnes). Systémové požadavky Procesor Intel 80386 kompatibilní (jakákoli rychlost) 4 MB operační paměti 50 MB místa na disku Disketová mechanika nebo jednotka CD-ROM (pouze pro instalaci) NT5 Počet bitů: 32

funkce spánku = uložení veškerého obsahu paměti na pevný disk a vypnutí počítače s možností opětovné reaktivace systému a pokračování ze stavu, ve kterém byl počítač uspán. Digitální podpis laboratoří Microsoft, bohužel přinesl i zápornou stránku a tou je zdražení hardware. Chystaná odlehčená verze s pracovním názvem Windows Neptune nikdy oficiálně nevyšla. Celkem byly vydány 4 servisní balíčky. Systémové požadavky Windows 2000 Professional: 133 MHz nebo vyšší Pentium-kompatibilní Procesor 32 MB RAM 650 MB místa na HDD Windows 2000 Server: 133 MHz procesor 256 MB RAM 1 GB na HDD Windows 2000 Advanced Server: 133 MHz Procesor 256 MB RAM 2 GB HDD

Me Mimo jiné také standardně obsahují ovladače pro USB Mass storage zařízení. System Restore = obnovení předchozího nastavení v případě havárie systému. Systémové požadavky Minimální: Procesor: 150 MHz – Intel Pentium kompatibilní Místo na HDD: 320 MB Operační paměť: 32 MB Doporučené: Procesor: 300 MHz – Intel Pentium II kompatibilní Místo na HDD: 2 GB Operační paměť: 96 MB Pozn.: Pokud se instalační program spustí s parametrem /nm, nebude se testovat, zda má počítač dostatečný výkon.
XP Číslo verze znamená pořadí v řadě jader s technologií NT, předchůdcem byl Windows 2000 s označením NT5. V české verzi byly vydány 1. prosince 2001. Představeny byly v Marriott Marquis Theatre v New Yorku. Windows XP jako první umožnil budoucím technikům IT simulovat pomocí aplikace celou síť v jednom PC. Ještě trocha teorie. Aktualizační balíček integruje rozsáhlejší sadu oprav (bezpečnostních aktualizací) a nových verzí integrovaných programů, které byly k danému datu vydány. SP2: Zaměřen byl na bezpečnost NX bitu, která zamezuje zneužití přetečení zásobníku a tím i běžný postup pro šíření virů. Aktualizován byl Windows Firewall, který je od SP2 implicitně aktivní. Podpora SP2 již byla ukončena.

Systémy Windows označené písmenem N jsou výsledkem antimonopolního řízení Evropské komise, po kterém kromě zaplacení pokuty 497 miliónu euro musela firma Microsoft vydat verzi Windows XP bez integrovaného přehrávače Windows Media Player. Provedení a cenová politika verzí N je však taková, že se nesetkaly se zájmem uživatelů.
Windows Server 2003, Web EditionWindows Server 2003, Web Edition, představující novou verzi v řadě produktů Windows Server, je webový server. Poskytuje organizacím platformu pro provoz webových serverů a hostitelských služeb, kterou lze snadno zavádět a spravovat. Díky technologii Microsoft ASP.NET, která je součástí platformy .NET Framework, poskytuje Windows Server 2003, Web Edition vývojářům platformu pro rychlé vytváření a zavádění webových služeb a aplikací XML.Windows Server 2003, Standard EditionWindows Server 2003, Standard Edition je síťový operační systém. Windows Server 2003, Standard Edition nabízí řešení pro sdílení souborů a tiskáren, připojení k Internetu, centralizované zavádění osobních aplikací a spolupráci mezi zaměstnanci, partnery a zákazníky. Windows Server 2003, Standard Edition podporuje symetrické zpracování dvěma procesory a až 4 GB paměti.Windows Server 2003, Enterprise EditionWindows Server 2003, Enterprise Edition je server pro střední a velké organizace. Poskytuje funkce potřebné k zajištění provozu podnikové infrastruktury, použití komerčních aplikací a transakcí elektronického obchodování. Windows Server 2003, Enterprise Edition je multifunkční operační systém, který podporuje využití až osmi procesorů a poskytuje funkce pro podniková prostředí, jako je například vytváření clusterů se čtyřmi uzly, a až 32 GB paměti. K dispozici je také pro 64bitové počítačové platformy.Windows Server 2003, Datacenter EditionWindows Server 2003, Datacenter Edition je určen pro velké organizace. Poskytuje základ pro vytváření důležitých řešení pro databáze, software pro plánování podnikových zdrojů (ERP), zpracování velkého množství transakcí v reálném čase a slučování serverů. Jde o nejvýkonnější serverový operační systém, jaký kdy společnost Microsoft představila. Podporuje symetrické zpracování až 32 procesory a poskytuje možnost vytváření clusterů s osmi uzly a vyrovnávání zatížení jako standardní funkce. Windows .NET Datacenter Server je k dispozici také pro 64bitové počítačové platformy.

Vista Oficiální název Windows Vista byl představen 22. července 2005. Dne 27. července 2005 byla uvedena první betaverze, Windows Vista Beta 1 (build 5112), která byla k dispozici předplatitelům MSDN, vybrané části betatesterů a na některých konferencích pořádaných Microsoftem, jako např. Professional Developers Conference (PDC) a WinHEC. V květnu 2006 byla uvolněna Beta 2. V září 2006 společnost Microsoft uvolnila verzi Release Candidate 1 (RC1), od 14. září 2006 volně ke stažení na firemních webových stránkách. Finální produkt (RTM) byl v anglické verzi do výroby uvolněn 9. listopadu 2006. Prodej byl v Česku zahájen v listopadu 2006 (pro firemní zákazníky prostřednictvím multilicenčních smluv) a 30. ledna 2007 pro všechny ostatní. Česká verze byla k dispozici od 1. března 2007. Ve Windows Vista se objevuje zcela přepracované grafické rozhraní, označované názvem Aero, které využívá počítačovou 3D grafiku. Podporuje průhlednost oken a nabídek, trojrozměrné animace, ikonky přizpůsobené vyšším rozlišením apod . Pro funkčnost rozhraní Aero je nutné mít v počítači grafickou kartu, ke které musí existovat WDDM ovladač. (GUI) bylo přepracováno a obsahuje mnoho nových funkcí. Na mnoha místech je využíváno výše zmíněné vyhledávání (kromě adresářů a souborů i na různé seznamy). Ve vyšších verzích obsahuje funkci stínová kopie (anglicky shadow copy), která zajišťuje ukládání omezené historie obsahu měněných souborů.

7 Jde o systém, který má za úkol nahradit xp a nt5 s miléniji. Jde o kombinaci technologií Visty a upraveného jádra xp. Celý systém se zkoušel převážnou část testovací doby pod křídly xp. Rozpoznávání rukopisu podporuje češtinu, ale řeč ne. gadget pro Windows Media Center, schopnost vizuálního PINu, možnost spouštění položek jak z nabídky Start, tak z hlavního panelu a lepší mediální funkce. Kalkulačka umožňuje více řádkové vkládání dat, programovatelné statistické režimy a převodník jednotek.
Liny Díky povaze Linuxu jsou veškeré síťové aktivity s Linuxem jednoduché a přirozené. Jediné v čem je Linux ještě lepší i mimo síť, je tzv. live CD, což není nic jiného, nežli systém, který vám umožní po totálním kolapsu OS zachránit vaše data, protože je spouštěn přímo z mechaniky CD/DVD+-R/RW, či nahrán do paměti RAM. Díky hekrům v této podobě existují i Windows XP, nebo vista, ale nikdy takovéto disky nevyšli oficiálně, na rozdíl od Linuxu. Jednotlivé verze nejsou vždy mezi sebou kompatibilní. Je dobrou volbou pro mladé hravé lidi, kteří nechtějí hekovat, a nemají peníze na drahé OS. Dobrý je též jako záložní OS.
Mac OS systém 6 Cena se při uvedení pohybovala kolem 49 US dolarů. Tento nástroj byl vytvořen, protože DAS nebyly nainstalovány jako aplikace, ale místo toho byly integrovány do systému softwarových souborů, podobně jako pro drivery. To znamenalo, že DAS nemohly být řízeny pomocí finderu. Font/DA Mover byl použit také pro instalaci písem do systému 6 pro použití v softwaru, například MacWrite, Apple Word na zpracování softwaru. Font/DA Mover byl poprvé vyvinut Bertem Sloanem v roce 1985 a krátce poté byl zahrnut do systému Macintosh software jako standardní. Switcher nebyl zařazen do operačního systému, ale bylo možné ho zakoupit od Apple samostatně.

Systém 7 Je stále ještě používán malým počtem uživatelů, kteří vlastní dnes již spíše archaický hardware té doby. Sdílení souborů. Zároveň s uživatelským rozhraním zlepšení pro instalaci AppleTalk, System 7 také obsahoval server pro jednoduché sdílení souborů dovolující kterémukoli počítači sdílet soubory do sítě AppleTalk.
Typický alias je malý soubor, mezi 1 a 5 KB. Funguje jako přesměrování na objekt v systému, jako je. Ačkoli byl pro programátory aplikací pomocí AppleScript na implementaci složitý, pro uživatele to byl silný nástroj, který je dostupný dodnes jako součást Mac OS X. System 7 byl první verzí Mac OS, která se musela instalovat z více disket, neboť instalátor byl větší než jedna 1,44 MB disketa. Byl to také první operační systém od Apple, který byl distribuován na CD. CD neobsahovalo žádný další software. K počítačům Macintosh byly často přibalovány aplikace jako textový editor, šachy atd. System 7 také obsahoval aplikace využívající síťový protokol AppleTalk.

Systém 8 během prvních dvou týdnů se ho prodalo přes 1,2 milionu kopií. Mac OS 8.1 představil nový a mnohem účinnější systém souborů, známý jako HFS+. Mac OS 8.5 byl první verze Mac OS, která vyžadovala procesor PowerPC. Používal původní verzi QuickDraw a AppleScript, spolu s vyhledávacím nástrojem Sherlock. Mac OS 8.1 Vypuštěn 19. ledna 1998. Mac OS 8.1 představil nový systém souborů známý jako HFS+, Mac OS 8.1 také používal vylepšenou verzi PC Exchange, dovolující uživatelům vidět dlouhé názvy souborů (do 255 znaků), vytvořené na počítačích s operačním systémem Windows a podporujících FAT32.
Mac OS X Současná verze systému Mac OS, pod názvem x pomalu uzavírá naše putování dějinami OS. Grafické rozhraní je přejímáno nebo napodobováno v iPodech, iPhonech, iPadech atd. Program zvaný RakDok umožňuje užití nástrojové lišty z Mac OS X ve Windows (NT5 a vyšší) jako pomocné nástrojové lišty. Jde o konkurenci Windows, ale díky podílu Microsoftu ve společnosti Apple se spíše postupně přibližuje a snaží se podporovat produkty určené pro windows a vydané Microsoftem. Projděme si spíše grafiku a hledejme v zápiscích kompatibilitu systému Mac OS X a Windows. Hned na stránce se všeobecnými informacemi jsme mohli vidět tuto verzi užitou jako záložní systém k Windows XP. Jaguár Quartz Extreme pro vytváření grafiky přímo v grafické kartě, Systémová schránka pro ukládání kontaktních informací v novém Apple Address Book, Zvýšení rychlosti celého systému Ars Technica: Mac OS X 10.2 GUIdebook: Galerie uživatelského rozhraní. Alternativní OS Jde o systémy, které vyvíjely původně velké firmy, nebo university, čí parta popřípadě jeden programátor. Většinou jsou dobré jako záložní systémy, nebo druhé systémy pro mladé lidi, kteří rádi experimentují a také se tak trochu u svých PC nudí.

Obecnější prezentace o historii a fungování operačních systémů od počátků po XP

Posted in: Windows server

MyPro Biolinux pro Hyper-V, VMWare a Virtual Box

Biolinux disponuje předpřipraveným virtuálním strojem MyPro určeným pouze pro Virtual Box na uživatelské stanici. V této podobě je z důvodu HW náročnosti problematické jeho užití, proto publikuji jeho verzi, která jde spouštět na uživatelské stanici i serveru. Podmínkou je instalace virtualizačního nástroje Microsoft Hyper-V, VMWare player nebo work station, či původní Virtual Box.

Pro rozbalení virtuálního disku je potřeba program 7-zip

Minimální konfigurace virtuálního PC

RAM: 2 GB dynamicky se zvětšující do 256 GB, pro pevnou minimálně paměť 12 GB

Virtuální procesory: 8 a více

Siťový adaptér – Pro Hyper-V starý kompatibilní

Grafická paměť: 128 MB a více
Disk: Použít již existující, který si vyextrahujete z archivu

Stažení

Stažení part 1

Stažení part 2

Stažení part 3

Stažení part 4

Stažení part 5 – poslední

Originální dokumentace

Back to Top