Scrigroup - Documente si articole

Username / Parola inexistente      

Home Documente Upload Resurse Alte limbi doc  

 
CATEGORII DOCUMENTE




BulgaraCeha slovacaCroataEnglezaEstonaFinlandezaFranceza
GermanaItalianaLetonaLituanianaMaghiaraOlandezaPoloneza
SarbaSlovenaSpaniolaSuedezaTurcaUcraineana

BiologieBudovaChemieEkologieEkonomieElektřinaFinanceFyzikální
GramatikaHistorieHudbaJídloKnihyKomunikaceKosmetikaLékařství
LiteraturaManagementMarketingMatematikaObchodPočítačůPolitikaPrávo
PsychologieRůznéReceptySociologieSportSprávaTechnikaúčetní
VzděláníZemědělstvíZeměpisžurnalistika

Softwareová laboratoř - zdrojovÝ text programu

počítačů

+ Font mai mare | - Font mai mic






DOCUMENTE SIMILARE

Trimite pe Messenger
TFTP, anonymní FTP servery
Testování tří programů na vytvoření animovaného GIFu
JavaScript - začátečníci (3)
Datová komprese – definice prefixového kódu, Kraftova nerovnost, kompresní poměr, průměrná délka slova, Huffmanova konstrukce kódu
Třída, objekt, zapouzdření s vlastnostmi
Kryptografie – princip moderní bezpečnosti, symetrická a asymetrická kryptografie, digitální podpis, certifikační autorita, hashovaní funkce, základní popis: DES, RSA, AES
Základní principy periferních zařízení počítače (klávesnice, harddisk, jednotky CD, DVD, tiskárny, monitory, modemy, USB, zvukové karty atd.)
POLYMORFIZMUS A VIRTUÁLNE FUNKCIE - c++
Charakteristika systému LP
Když disk něco bolí

1.   Zdrojový text programu

Překlad programu probíhá podle schématu:

Přeložený program

 


Zdrojový text programu se skládá:

a)      vlastní příkazy jazyka,

b)      direktivy preprocesoru.

1.1.        Direktivy preprocesoru

Direktivy slouží k:

  • nahrazování částí zdrojového programu jiným zdrojovým textem,
  • definování maker,
  • vkládání textů do překládaného zdrojového programu z jiných zdrojových souborů,
  • vynechání při kompilaci stanovené části zdrojového programu,
  • nastavit specifické parametry při překladu související s danou implementací.

Zápis direktivy:

#jméno direktivy parametry

Direktiva #include

Tato direktiva se používá k začlenění knihoven s procedurami do programu.

Zápis:

#include <název souboru>

Standardní knihovna má příponu .h. Kromě toho můžeme vytvářet vlastní knihovny. Potom se zápis změní:

#include “název souboru“

Příklad:

#include <string.h>

#include “deklar.h”

Direktiva #define

Direktiva se používá k definování makra. Platí od místa, kde je zapsána. Platnost lze ukončit pomocí direktivy #undef. Zápis makra:

#define ident tělo_makra

Příklad:

#define Pocet 20

Potom preprocesor změní výpočet:

a= Pocet *10

na

a=20*10

Lze také definovat makro s parametry:

#define ident(ident1,ident2,…identk) tělo_makra

Příklad:

#define Obsah(x,y) x*y

Potom preprocessor změní výpočet:

a= Obsah(b+c,d)

na

a=(b+c)*d

1.2.        Základní datové typy

Datové typy dělíme do tři kategorií:

1.      Základní

2.      Odvozené

3.      Nové

Celočíselné typy

Typ                        Délka dat     Min                           Max                       Rozsah

char                       1 byte           SCHAR_MIN         SCHAR_MAX     -128127

unsigned char        1 byte           0                               UCHAR_MAX    0…255

short                      2 byte           SHRT_MIN             SHRT_MAX        -32768…32767

unsigned short       2 byte           0                               UINT_MAX         0…65536

int                          2 nebo 4       INT_MIN                INT_MAX            jako short nebo long

unsigned int           2 nebo 4       0                               UINT_MAX         jako unsigned short(long)

long                       4 byte           LONG_MIN            LONG_MAX       -2147483648…2147483647

unsigned long        4 byte           0                               ULONG_MAX    0…4294967295

Celočíselné typy lze zapisovat ve třech číselných soustavách:

  • desítkové,
  • oktálové,
  • hexadecimální.

Znaky

Používá se char nebo unsigned char. Znaky se zapisují s apostrofy. Např. ‘c’, ‘+’.

Logické hodnoty

Logická hodnota         číselná hodnota           bool

Není pravda                0                                  false

Je pradva                     1, libovolná jiná           true

Řetězce

Řetězce se zapisují uzavřené v uvozovkách.

Za poslední znak se ukládá binární 0.

Délka řetězce není omezena.

 

Příklad:

Řetězec “Jazyk C++” s délkou 9 je v paměti uložen na 10 bytech.

Řídící a některé další znaky s v řetězci zapisují ve formě dvojice znaků:

Znak          Význam

a               zvukové znamení

b               posun kurzoru o jednu pozici vlevo

f                nová stránka

n               nový řádek

r                návrat kurzoru na začátek řádku

t                horizontální tabulátor

v               vertikální tabulátor

                obrácené lomítko

                apostrof

               uvozovka

?               Otazník

Čísla v pohyblivé řádové čárce

Typ               Délka     Přesnost          Rozsah exponentu

Float             4 byte    7 míst              -37…+38

Double         8 byte    15 míst            -307…+308

long double  10 byte  17 míst            -4931…+4932

1.3.        Identifikátory a deklarace

Identifikátor začíná písmenem nebo znakem _.

Na dalších místech písmena, číslice, _.

Délka není omezená, ale bere se jen prvních 31 znaků.

Dva účely identifikátorů:

  • Pro jména proměnných, konstant, funkcí, …
  • Pro označení cílového návěští příkazu skoku goto.

Schematický tvar deklarace proměnných:

spec typ dekl1 ident1=výraz1, dekl2 ident2=výraz2,…;

Vynecháme-li volitelné specifikace a volitelné deklarační údaje:

typ ident1=výraz1, ident2=výraz2,…;

Příklad:

char ZnakA=‘A‘, ZnakB=ZnakA+1, zn

Pro definování konstanty používáme klíčové slovo const a zápis:

const typ ident1=výraz1, ident2=výraz2,…;

Příklad:

const char ZnakA=‘A‘, ZnakB=ZnakA+1, zn

1.4.         Operátory

Základní vlastnosti:

-          priorita,

-          asociativita.

 ()                slouží k definici, deklaraci a volání funkce.

 []               je použit pro deklaraci a zápis prvku pole.

. a ->          zajišťují přístup ke členům strukturovaných typů a tříd.

.* a ->*      zajišťují přístup ke členům třídy s použitím pointeru na členy třídy.

::                pro vymezení rozsahu platnosti.

Unární operátory

!                 negace.

~                negace celočíselného operandu ve všech bitech.

-                 unární operátor pro výpočet opačné hodnoty.

+                unární operátor, který nechává hodnotu výrazu beze změny.

+ +             inkrementace, zvyšuje hodnotu operandu o 1.

- -               dekrementace, snižuje hodnotu operandu o 1.

*                dereference, zajišťuje přístup k hodnotě přes pointer.

&               operátor adresy.

sizeof         délka datového objektu.

delete        uvolní alokovanou paměť.

Binární operátory

-          aritmetické: + , - , * , / , % (zbytek celočíselného dělení)

-          bitového posuvu: << , >>

-          srovnání: < , <= , > , >= , = = , !=

-          logické: && (součin), || (součet), & (bitový součin), | (bitový součet), ^ (b. nonekvivalence)

-          podmíněný výraz:    ?: (podmínkový_výraz ? výraz_true : výraz_false)

-          přiřazení: = , *= , /= , %= , += , -= , <<= , >>= , &= , ^= , |= (zkrácení zápisu levá_strana = levá_strana op výraz)

Konverze hodnot

Konverze v operaci přiřazení lvalue=rvalue

1.Celočíselné typy mezi sebou.

2.Celočíselné typy a typy s pohyblivou řádkou.

3.Typy s pohyblivou řádkou a celočíselné typy.

4.Typy v pohyblivé řádce mezi sebou.

2.   Pointery

Pointery jsou proměnné, do kterých se ukládají adresy.

spec typ *dekl ident=výraz, … ;

Lze deklarovat pointer, který není vztažen k žádnému datovému typu:

void *ident;

Příklad:

int *p1, **p2, ***p3;

2.1. Operace s pointery

Pointery reprezentují adresy. Lze s nimi sestavovat různé výrazy:

            pointer +- celočíselný výraz

            pointer2 – pointer1

Příklad:

long L=3, *pl=&L;

03

00

00

00

                                                            pL                                   pL+1                                                        

Příklad:

short *pI=adresa; //short (délka 2 byte)

?

?

?

?

?

?

?

?

                                          pI

*pI=1000;

E8

03

?

?

?

?

?

?

                                          pI

*(pI+2)=10;

E8

03

?

?

0A

00

?

?

                                          pI

*++pI=5;

E8

03

05

00

0A

00

?

?

                                                            pI

++*pI;

E8

03

06

00

0A

00

?

?

                                                            pI

*pI++=2;

E8

03

02

00

0A

00

?

?

                                                                              pI

 (*pI)--;

E8

03

02

00

09

00

?

?

                                                                              pI

2.2. Konstantní pointery, pointery s konstantní hodnotou

Pointer na konstantní hodnotu – pointery, kterým lze přiřadit novou hodnotu, ale nelze měnit hodnoty, na které pointery ukazují.

const typ *ident1, *ident2,…;

Příklad:

int i;

const int *pi;

pi=&I;

pi++;

*pi=1 // nelze měnit hodnotu

Konstantní pointery – lze měnit hodnoty, na které pointer ukazuje, ale nelze změnit jeho hodnotu.

typ *const ident1=výraz1, *const ident2=výraz2,…;

Příklad:

int i;

int *const pi=&i;

*pi=2;

pi++; // nelze měnit hodnotu pointeru

Konstantní pointer na konstantní hodnotu – nelze měnit ani hodnotu pointeru ani hodnotu, na níž pointer ukazuje.

const typ *const ident1=výraz1, *const ident2=výraz2,…;

Příklad:

const i=1;

const *const pi=&i;

*pi=2; //nelze měnit hodnotu, na níž pointer ukazuje

pi++; // nelze měnit hodnotu pointeru

3.   Příkazy jazyka

3.1.        Příkaz, složený příkaz

Obdobné příkazy jako v ostatních procedurálních jazycích.

  • Zápis příkazu je vždy ukončen středníkem.
  • Středník je součástí příkazu.

Příklad:

short q;

A=1;

Složený příkaz (Blok)

Je uzavřen složenými závorkami a může obsahovat:

  • příkazy,
  • složené příkazy,
  • deklarace (platnost je pouze ve složeném příkazu).

Příklad:

int j;

j=1;

}

3.2.        Podmíněný příkaz

Dva formáty podmíněného příkazu.

if (podmínkový_výraz) příkaz1

if (podmínkový_výraz) příkaz1 else příkaz2

Příklad:

if (k>0) j=k; else j=-k;

Lze také použít operátor podmíněného výrazu:

j= (k>0) ? k : -k;

Jeli vnořeno více příkazů if, pak část else se vztahuje k nejbližšímu if.

3.3.        Příkazy cyklu

Jsou celkem tři formáty příkazů cyklu:

1. while

while (podmínkový_výraz) příkaz

Je-li hodnota podmínkového výrazu false (0), je cyklus ukončen.

2. do – while

do příkaz while (podmínkový_výraz)

Je-li hodnota podmínkového výrazu false (0), je cyklus ukončen. Cyklus vždy proběhne alespoň 1.

2. for

do (výraz1; podmínkový_výraz; výraz3) příkaz

výraz1 – je vypočítán je jednou před zahájením cyklu.

podmínkový_výraz – podmínka cyklu.

výraz3 – je vypočítán vždy na konci každého průchodu cyklem.

3.4.         Prázdný příkaz

Prázdný příkaz obsahuje  jen středník.

3.5.        Příkazy continue, break

Continue

Je-li v těle cyklu proveden příkaz

continue;

je daný průchod cyklu ukončen, zbývající příkazy těla cyklu jsou vynechány. U cyklu for je přitom výraz3 vypočítán. Cyklu po continue pokračuje dalším průchodem.

Break

Je-li v těle cyklu proveden příkaz

break;

je cyklus ukončen. Program pokračuje příkazem, který následuje za cyklem.

3.6.        Přepínač switch

Slouží ke větvení programu. Zápis:

switch (celočíselný_výraz)

Na začátku je vypočítán celočíselný_výraz a jeho hodnota je postupně srovnávána s konst_výraz1 konst_výrazm. Jestliže je hodnota shodná, jsou provedeny všechny příkazy až do konce přepínače (tedy i ty, které jsou uvedeny za dalšími hodontami case, včetně default). Proto je obvyklé použít na konci každé části příkaz break. Jestliže nejsou hodnoty shodné, jsou vykonány příkazy v části default .

3.7.        Návěští

Pravidla pro návěští:

  • návěští je identifikátor ukončený dvojtečkou,
  • je v programu uvedeno v cílovém místě skoku,
  • návěští se nikde nedeklaruje,
  • platí pro celou funkci, ve které je uvedeno.

Zápis:

goto návěští;

Příklad:

int i, m, n, licha, suda;

n=1;

m=100;

for (i=m, licha=suda=0; i<=n; i++)

4.   Pole, struktutovaný a výčtový typ

4.1.        Odvozený datový typ

typedef zápis_ve_tvaru_deklarace;

Příklad

Deklarujeme odvozený datový typ pointeru na int:

typedef int *pInt;

Deklarace pointerů

pInt pi,pi1=0;

je ekvivalentní s deklarací

int *pi,*pi1=0;

4.2.        Pole

Pole s jedním rozměrem

Deklarace:

dekl ident[počet_prvků],…;

Zápis prvku pole:

ident[index]

Příklad

int Pole[10];

Prvky pole jsou

Pole[0], Pole[1],… Pole[9]

Deklarace s iniciací:

dekl ident[počet_prvků]=;

Příklad

char Pole[10]=;

Řetězce

Pro uložení řetězců se používají znaková pole (typu char).

Pointery a jednorozměrná pole

Máme-li pole:

dekl ident[počet_prvků];

pak jsou ekvivaletní zápisy:

     *ident            ident[0]

*(ident+index)    ident[index]

Vícerozměrná pole

Deklarace:

dekl ident[počet_prvků1] [počet_prvků2]… [počet_prvkům];

Zápis prvku pole:

ident[index1][index2]… [indexm]

Příklad

int Pole[2][2];

Prvky pole jsou

Pole[0][0], Pole[0][1], Pole[1][0], Pole[1][1]

Pole lze v deklaraci inicializovat. Platí, že lze vynechat počet prvků pouze u prvního indexu.

Pointery a vícerozměrná pole

Máme-li pole:

dekl ident[počet_prvků1] [počet_prvků2];;

pak jsou ekvivaletní zápisy:

     *(ident+ix1)      ident[ix1]

a jsou to pointery na řádek pole – jednorozměrné pole.

Všechny tyto čtyři zápisy jsou ekvivalentní:

            ident[ix1][ix2]         *(ident[ix1]+)

            (*(ident+))[ix2]       *(*(ident+ix1)+ix2)

4.3.        Strukturované datové typy

Datový typ struct

struct ident dekl1 ident1=inic1,…,dekln identn=inicn;

Příklad

struct Dat1, Dat2, *pDat

Příklad

struct Datum

Datum Dat1, Dat2, *pDat

Přístup ke členům:

proměnná.člen

Operátor -> je pro přístup ke členům při zadaném pointeru:

pointer->člen

Přes pointer lze přistupovat dvěma způsoby:

  • (*pointer).člen
  • pointer->člen

Nedefinovaná deklarace strukturovaného typu

struct ident;

Použijeme ji pro deklaraci pointeru tehdy, kdy není k dispozici úplná deklarace strukturovaného typu (je uvedena v jiné části programu nebo následuje až a deklarací pointeru).

Příklad

struct S2;

struct S1 ;

struct S2 ;

Datový typ union

Všechny členy strukturovaného typu union jsou uloženy na stejné adrese – překrývají se. Délka je rovna délce největšího členu.

union ident dekl1 ident1=inic1,…,dekln identn=inicn;

Příklad

union   U

i

c[0]

c[1]

c[2]

c[3]

c[4]

l

4.4.        Bitová pole

U strukturovaných typů lze definovat přesnou velikost členů v bitech. Ty jsou pak uloženy těsně za sebou.

typ ident: počet_bitu;

Příklad

struct Tepl  

4.5.        Výčtový typ enum

Používá se pro deklaraci většího počtu celočíselných konstant.

enum ident dekl1 ident1=výraz1,…,dekln identn=výrazn;

Příklad

enum Tyden   

Potom jednotlivé konstanty mají hodnoty:

Pondeli=0, Utery=1, Streda=2, Ctvrtek=3, Patek=4, Sobota=10, Nedele=11

5.   Funkce a reference

5.1.        Reference

spec typ &dekl ident=výraz, … ;

Základní vlastnosti:

  • deklarace reference musí obsahovat inicializaci,
  • jiným způsobem než deklarací nelze stanovit referenci na datový objekt,
  • v zápisu reference se na rozdíl od pointerů neuvádí operátor *.

Příklad:

int prom;

int &rprom=I;

rprom = 10;

Princip přístupu je stejný jako u pointeru, ale pointer má širší použití. Hodnotu pointeru lze měnit, s pointery lze provádět aritmetické operace.

Reference na konstantní hodnotu:

const typ &dekl ident=výraz, … ;

5.2.        Funkce

Deklarace:

dekl ident(dekl1 par1, dekl2 par2,… , deklk park)

Jestliže nemá parametry, nechají se závorky prázdné nebo se napíše klíčové slovo void:

dekl ident(void)

Volání:

            S parametry:

dekl ident(parv1, parv2,… , parvk)

Bez parametrů:

dekl ident()

Každý program musí obsahovat funkci main. Tuto funkci nelze samostatně volat.

Příklad:

int i=1;

void F()

       

Uvažujme příkazy:

F( );     // zvýší hodnotu i o 1

F          // formálně správně, ale nemá žádný efekt

Funkční hodnota

Návrat z funkce typu void (funkce nevracející hodnotu) je:

  • automaticky na konci těla funkce,
  • kdekoliv uvnitř těla funkce příkazem:

return;

U funkce, která vrací hodnotu, je návrat příkazem:

return výraz;

Formální parametry funkce

Jsou tři druhy formálních parametrů:

  • volané hodnotou,
  • volané odkazem,
  • volané referencí.

Parametry dělíme na:

  • vstupní, které jen předávají hodnotu,
  • vstupní i výstupní.

Parametry funkce volané hodnotou

  • jsou jen vstupní.

Příklad:

int F(int p1, int p2)

       

Parametry funkce volané odkazem

Používají se pro:

  • pole, strukturované typy a objekty tříd,
  • jakékoliv typy, jde-li o výstupní parametr.

Příklad:

void Rotace(int *p1, int *p2, int *p3)

       

Volání:

int i=3, j=-2, k=7;

Rotace (&i, &j, &k);

Jednorozměrná pole lze zapsat jako formální parametr několika způsoby:

  • pointer,
  • nekompletní deklarace pole,
  • kompletní deklarace pole.

Příklad:

#include <limits.h>

long Maxim(long *Cisla, unsigned Pocet)

       

U vícerozměrných polí můžeme také použít tři způsoby zápisu:

  • pointer na pole: dekl (*ident) [počet_prvků2]… [počet_prvkům];
  • nekompletní deklarace pole: dekl ident[][počet_prvků2]… [počet_prvkům];
  • kompletní deklarace pole: dekl ident[počet_prvků1] [počet_prvků2]… [počet_prvkům];

Parametry funkce volané referencí

  • vstupní i výstupní,
  • mechanismu stejný jako u volání odkazem, jen se používá reference.

Příklad:

void Rotace(int &p1, int &p2, int &p3)

       

Volání:

int i=3, j=-2, k=7;

Rotace (i, j, k);

Typ výsledku funkce

Pro předání výsledku funkce lze použít jeden ze tří způsobů:

  • hodnotou,
  • odkazem,
  • referencí.

Funkce vracející hodnotu

Výsledek funkce vracíme hodnotou pro stejné datové typy, pro jaké používáme volání hodnotou ve formálních parametrech.

Funkce vracející pointer

Prototyp funkce vracející pointer:

spec typ *dekl ident(.. parametry ..)

Příklad:

struct Obdelnik ;

Obdelnik *Vetsi(Obdelnik *o1, Obdelnik *o2)

       

Volání:

Obdelnik obd1={2.5,4), obd2={3,2), *pobd;

pobd = Vetsi(&obd1, &obd2);

Funkce vracející referenci

Prototyp funkce vracející pointer:

spec typ &dekl ident(.. parametry ..)

Příklad:

struct Obdelnik ;

Obdelnik &Vetsi(Obdelnik &o1, Obdelnik &o2)

       

Volání:

Obdelnik obd1={2.5,4), obd2={3,2), pobd;

pobd = Vetsi(obd1, obd2);

Implicitní hodnoty parametrů funkce

dekl ident(dekl1 par1, dekl2 par2,… deklk-1 park-1, deklk park= výrazk ,…, dekln parn= výrazn )

Příklad:

int Soucet(int a, int b=2, int c=4)

       

Funkci lze volat s 1, 2, nebo 3 parametry:

Soucet(1)

Soucet(1,3)

Soucet(1,3,8)

Polymorfní funkce

V programu lze uvést více funkcí se stejným jménem. Musí se však lišit buď počtem nebo typem parametrů.

Příklad:

#include <math.h>

float Obsah(float r)

float Obsah(float a, float b)

Funkci voláme:

Obsah(5)

Obsah(6,2)

Prototyp funkce, deklarace funkce

Prototyp je deklarace funkce s jejími parametry, zatímco funkce samotná je definována v jiném místě programu.

spec typ dekl ident(.. parametry ..);

V deklaraci funkce lze vynechat konkrétní jména formálních parametrů nebo je změnit..

Příklad:

Následující deklarace funkce jsou ekvivalentní:

void Kop(const int *Cis1, int Cis2[], int Počet);

void Kop(const int *C1, int C2[], int P);

void Kop(const int *, int [], int);

Funkce jako datový typ

Deklarace funkce:

typedef dekl ident(dekl1, dekl2,… , deklk);

Příklad:

Následující deklarace funkce jsou ekvivalentní:

typedef double Fun(double);

typedef Fun *pFun;

#include <math.h>

pFun F[3]=;

F[0](.5)

F[1](.5)

F[2](.5)

Deklarace typu pointer na funkci: typedef dekl (*ident)(dekl1,dekl2,…,deklk);

Deklarace typu reference na funkci: typedef dekl (&ident)(dekl1,dekl2,…,deklk);

Funkce jako formální parametr

Lze využít datový typ funkce. Parametr je volán odkazem.

Příklad:

typedef float Fun(float);

float Koren (float x1, float x2, funkce F)

float X2(float x) {return x*x-3;)

float x= Koren (1,2,X2);

Funkce s proměnným počtem parametrů

V definici funkce se nejprve uvede pavná část parametrů (alespoň 1) a za ně se udělají 3 tečky:

dekl ident(dekl1 par1, dekl2 par2,… , deklk park . . . )

Funkce inline

Slouží pro velice krátké funkce.

Vkládá se do programu jako makro.

inline dekl ident(.. parametry ..)

6.   Vstupy a výstupy

6.1.        Vstupy a výstupy na standardní zařízení

stdout – označení pro standardní výstup - monitor,

stdin – označení pro standardní vstup - klávesnice,

stderr – označení pro standardní zařízení, na které vystupují informační a chybové zprávy – monitor.

Výstup na standardní zařízení

Základní funkce:

int printf(const char *format, …);

parametr format je řetězec, ve kterém jsou obsaženy:

  • vypisované texty,
  • řídící znaky (přechod na nový řádek, atd.),
  • formáty pro výstup hodnot výrazů.

Příklad:

printf(“Jazyk C++“);

Výstup:

Jazyk C++

printf(“nnJazyk C++nje rozšířením jazyka Cna“);

Výstup:

Jazyk C++

je rozšířením jazyka C

Výstup pro hodnoty výrazů:

% příznaky  počet_znak;  .deset_míst  F|N|h|I|L  typ

povinný je jen % a typ.

Typ stanovíme, v jakém tvaru je výstup hodnoty:

  • d – celé číslo se znaménkem,
  • i – stejné jako u d,
  • u – celé číslo bez znaménka,
  • o - celé číslo bez znaménka v oktalové soustavě,
  • x - celé číslo bez znaménka v hexadecimálně soustavě, hex. číslice se tisknou malými písmeny a,b,c,d,e,f,
  • X - celé číslo bez znaménka v hexadecimálně soustavě, hex. číslice se tisknou velkými písmeny A,B,C,D,E,F,
  • f – číslo v pohyblivé řádové čárce, tisk ve tvaru desetinného čísla,
  • e – číslo v pohyblivé řádové čárce, tisk ve semilogaritmickém zápisu, oddělovačem exponentu je e,
  • E – číslo v pohyblivé řádové čárce, tisk ve semilogaritmickém zápisu, oddělovačem exponentu je E,
  • g – číslo v pohyblivé řádové čárce, v závislosti na hodnotě čísla je vybrán nejvhodnější tvar výstupu – celé číslo, desetinné číslo nebo semilogaritmický zápis,
  • G – stejné jako g, jen v semilogaritmickém zápisu je místo e E.
  • c – výpis znaku,
  • s – výpis řetězce,
  • p – výpis hodnoty pointeru, výstup v hexadecimální soustavě.

Příklad

char Zn=’+’;

printf(“Hodnota znaku ‘%c’ je dekadicky %i a hexadecimálně %X“,Zn,Zn,Zn);

Výstup:

Hodnota znaku ‘+’ je dekadicky 43 a hexadecimálně 2B

Příklad

printf(“n%.3f“,10.12345);

Výstup:

10.123

Příklad

printf(“%05u“,10);

Výstup:

00010

V části příznaky lze uvést znaky:

  • - pro zarovnání zleva místo zprava,
  • + pro výstup znaménka + u nezáporných čísel,
  • mezeru, která zajistí, že při výstupu nezáporných čísel je na místě znaménka vynechána mezera.

Příklad

printf(“%+-4i|% i|% i“,1,2,-3);

Výstup:

+1  | 2|-3

Další parametry:

  • N – je výpis blízkého pointeru,
  • F – je pro výpis vzdáleného pointeru,
  • h – pro celá čísla typu short, tj. 2 byte,
  • L – pro čísla v pohyblivé řádové čárce typu long double.

Příklad

cislo=123456;

printf(“%li %i“,cislo,cislo);

Výstup:

123456 -7616


Vstup ze standartního zařízení

Základní funkce:

int scanf(const char *format, adresa1,adresa2…);

-          format stejný jako u printf jen neobsahuje texty a řídící znaky,

-          adresa1,adresa2 udávají adresy, na které se uloží přečtené hodnoty.

Příklad

int i,j,k;

scanf(“%i%i%i“,&i,&j,&k);

Příklad

unsigned i,j,k;

scanf(“%2u%5u%3u“,&i,&j,&k);

printf(“%u  %u  %u”,i,j,k);

Vstup:

1234567890

Výstup:

12  34567  890

Další funkce a makra výstupu na stand. zař.

int putchar(int ch);

-          tiskne jeden znak na standardní výstup,

-          parametr je typu int, ale vystupuje jako char. To odpovídá volání funkce: printf(“%c”,ch);

int puts(const char *s);

-          vypíše obsah řetězce a přejde na nový řádek,

-          zápis odpovídá volání funkce: printf(“%sn”,s);

Další funkce a makra vstupu ze stand. zař.

int getchar(void);

-          přečte jeden znak ze stand. vstupního zařízení,

-          makro vrací přečtenou hodnotu.

Příklad

char ch;

scanf(“%c“,&ch);

ch=getchar();


int *gets(char *s);

-          přečte obsah celého řádku a uloží do řetězce.

6.2.        Vstupy a výstupy pro soubory

Označení stand. zař. stdout, stdin a stderr jsou rovněž pointery typu FILE, jejich deklaraci bychom mohli zapsat:

FILE *stdout,*stdin,*stderr

Otevření souboru

FILE *fopen(const char *filename, const char * mode);

-          filename – řetězec se jménem nebo cestou k souboru,

-          mode – řetězec, ve kterém je uveden jeden z následujících způsobů otevření souboru:

·         r – otevřeno pro čtení,

·         w – otevřeno pro vytvoření souboru, jestliže již existuje, je přepsán,

·         a – otevřen pro pokračování v zápisu, pokud neexistuje, je vytvořen,

·         r+ – otevřeno pro čtení i zápis,

·         w+ – otevřeno pro vytvoření souboru a zároveň i aktualizaci, jestliže již existuje, je přepsán,

·         a+ – otevřen pro pokračování v zápisu a současně i čtení,

-          v řetězci mode se uvádí jeden parametrický znak. Je nepovinný a má dvě hodnoty:

·         t – je označení textového souboru (implicitní),

·         b- binární soubor.

Funkce vrací:

  • pointer typu FILE, jestliže soubor je otevřen,
  • nulu, jestliže otevření nebylo úspěšné.

Příklad

FILE *Soubor;

Soubor=fopen(“Test.txt”,”wt”);

If (!Soubor) printf(“Soubor nelze vytvořit”);

Formátový a neformátový vstup/výstup

1.Formátový výstup/vstup – data jsou při ukládání i čtení převedena z a do znakové podoby. Vhodné pro práci s textovými soubory.

2.Neformátový výstup/vstup – data jsou ukládána i čtena bez úprav. Vhodné pro pro uložení většího množství číselných dat.

Formátový výstup

int fprint(FILE *stream, const char *format, …);

Příklad

FILE *Soubor;

Soubor=fopen(“Test”,”w”);

char S[]=”Jazyk C++”,C=’$’;

fprint(Soubor,“%s%c”,S,C);

Neformátový výstup

unsigned fwrite(const void *ptr,size_t size, size_t count,FILE *stream);

-          ptr – adresa, pointer na data, která mají být zapsána,

-          size – délka jednoho bloku dat v bytech,

-          count – počet za sebou následujících zapisovaných bloků dat délky size.

Příklad

FILE *Soubor;

struct Jm=;

Soubor=fopen(“Test”,”w”);

if (fwrite(&Jm,sizeof Jm,1,Soubor)!=1) printf (“Chyba pri zapisu zaznamu Jm”);

Další funkce a makra pro výstup

int fputc(int c,FILE *stream);

int putc(int c,FILE *stream);

-          makro pro zápis znaku.

int fputs(const char *c,FILE *stream);

-          makro pro zápis řetězce.

int putw(int w,FILE *stream);

-          makro pro zápis slova.

Formátový vstup

int fprint(FILE *stream, const char *format, adresa1,adresa2…);

Příklad

FILE *Soubor;

int i,j;

char Str[100];

Soubor=fopen(“Test”,”r”);

fscan(Soubor,“%i%i%s”,&I,&j,Str);

Neformátový vstup

unsigned fread(void *ptr,size_t size, size_t count,FILE *stream);

Další funkce a makra pro vstup

int fgetc(FILE *stream);

int getc(FILE *stream);

-          makro pro přečtení jednoho znaku.

int *fgets(char *s, int n, FILE *stream);

-          makro pro přečtení řetězce. Je ukončení koncem řádku nebo přečtením n-1 znaků nebo koncem souboru.

int getw(FILE *stream);

-          makro pro čtení slova.

Test konce souboru

int feof(FILE *stream);

-          funkce vrací nenulovou hodnotu, jestliže při posledním čtení byl dosažen konec souboru.

Mohou nastat případy

-          při čtení makry fgetc, getc, getw, nebyla přečtena žádná hodnota a funkce vrací EOF(číslo -1),

-          funkce fgets vrací pointer na řetězec, pokud před dosažením konce souboru přečetla alespoň 1 znak. Jinak vrací 0.

-          funkce fscanf nepřečte žádnou hodnotu nebo jen část. Počet přečtených hodnot je návratová hodnota.

-          funkce fread nepřečte žádný blok, nebo jen menší počet bloků. Funkce vrátí skutečně přečtený počet celých bloků.

Uzavření souboru

int fclose(FILE *stream);

-          funkce vrátí hodnotu 0, jestliže uzavření bylo úspěšné.

Ošetření chyb

int ferror(FILE *stream);

-          funkce vrací hodnotu 0, jestliže nenastala chyba.

Příklad

FILE *Soubor;

Soubor=fopen(“Test”,”w”);

… // příkazy zápisu do souboru

if (ferror(Soubor)) printf(“Při zápisu došlo k chybě”);

void clearerr (FILE *stream);

-          vynuluje příznak chyby.

Výpisy zpráv o chybě

void perror (const char *s);

-          funkce vypíše řádek ve formě s: popis chyby.

Přímý přístup k souboru

long ftell (FILE *stream);

-          funkce vrací pozici místa, na kterém právě probíhá zpracování souboru, jestliže bylo volání úspěšné. Nebo –1L v případě chyby.

int fseek (FILE *stream,long offset, int whence);

-          funkce pro nastavení souboru na zvolenou pozici,

-          parametrem offset se zadává nová pozice,

-          parametre whence může mít tyto hodnoty:

o       0 – hodnota offset je zadána vzhledem k počátku souboru,

o       1 – nová hodnota offset je zadána vzhledem k aktuálnímu nastavení souboru,

o       2 – hodnota offset je počítána od konce souboru.

Příklad

FILE *Soubor;

Soubor=fopen(“Test”,”w+”);

fputs(“Jazyk ”,Soubor);

long Pozice=ftell(Soubor);

fputs(“C++”,Soubor);

fseek(Soubor,Pozice,0);

printf(“%c”,getc(Soubor));

fseek(Soubor,-5,2);

printf(“%c”,getc(Soubor));

fseek(Soubor,-2,1);

printf(“%c”,getc(Soubor));

pis:

Cky

Přejmenování (přesun) a zrušení souboru

int rename (const char *oldname,const char *newname);

-          funkce pro změnu jména souboru,

-          vrací 0, bylo-li přejmenování úspěšné.

int remove (const char *filename);

-          funkce pro zrušení souboru,

-          vrací 0, bylo-li zrušení úspěšné.

Funkce vstupu/výstupu v paměti

int sprintf (char *buffer,const char *format);

-          pro formátový výstup řetězce,

-          buffer adresa, kam bude uložen výsledný řetězec.

int sscanf (const char *buffer,const char *format, adresa1,adresa2…);

-          pro formátový vstup řetězce,

-          buffer adresa vstupního pole.

7.   Základní struktura programu

Typické uspořádání programu:

direktivy preprocesoru

deklarace

definice funkcí

definice hlavní funkce - main

Jiné uspořádání programu:

direktivy preprocesoru

deklarace datových typů

prototypy funkcí

deklarace konstant a proměnných

definice hlavní funkce - main

definice ostatních funkcí

7.1.        Specifikace uložení v paměti

V deklaraci lze použít jedno z klíčových slov auto, extern, static a register. Specifikuje se jimi, kde hodnota bude uložena.

Specifikace auto

        používá se jen v lokálních deklaracích,

        pro lokálně deklarovanou proměnnou je při každém vstupu do složeného příkazu přiděleno místo v paměti a proměnná je inicializována,

        při opuštění složeného příkazu je paměť uvolněna.

Specifikace static

        používá se rovněž v lokálních deklaracích,

        paměť je přidělena trvale.

Specifikace register

        lze použít pro jednoduché datové typy (char, int),

        proměnná je uložena v registrech.

Specifikace extern

        používá se pouze v případě, je-li program rozdělen do více částí a více částí sdílí jeden datový objekt, pak ho deklarujeme jen v jedné z nich. V ostatních uvedeme deklaraci s klíčovým slovem extern.

7.2.        Blízké a vzdálené pointery, paměťové moduly

Pointery

1.Blízká adresa

        rozsah 64 KB,

        označení near.

2.Vzdálená adresa

        dvojice segment + offset,

        označení far.

Modely paměti

tiny

-          instrukce near, data near,

-          maximální rozsah programu je 64 KB,

-          lze sestavit program typu *.com.

small

-          instrukce near, data near,

-          maximální rozsah programu je 64 KB kódu a 64 KB dat.

medium

-          instrukce far, data near,

-          rozsah programu je nad 64 KB a maximálně 64 KB dat.

compact

-          instrukce near, data far,

-          maximální rozsah programu je 64 KB kódu a rozsah dat nad 64 KB.

large a huge

-          instrukce far, data far,

-          instrukce i data mohou přesáhnout 64 KB,

-          u modelu huge může být datový objekt větší než 64 KB.

Typ datového modelu se zadává v parametrch pro překlad programu.

7.3.        Změna typu – (cast)

Vedle implicitní změny typu je zavedena i explicitní změna typu výrazu. Její zápis:

(typ)výraz

-          typ – nový typ výrazu.

Příklad:

char *p;

(char *)výraz

V konstruktoru lze použít I zápis:

typ(výraz)

Příklad:

Místo zápisu:

l=(long)i+(long)j;

můžeme použít:

l=long(i)+long(j);

8.   Standardní funkce, pole pointerů

8.1.        Alokace a uvolnění paměti

Operátory new a delete

Zápis alokace paměti:

pointer = new name

Operace new vrací:

  • pointer na alokovanou oblast paměti,
  • nulu, jestliže alokace nebyla provedena.

Zápis uvolnění alokované paměti:

delete pointer

Zápis alokace pole:

pointer = new dekl[počet_prvků1] [počet_prvků2]… [počet_prvkům];

Uvolnění alokované paměti pro pole:

delete [] pointer

Alokace a uvolnění paměti

Funkce jsou v souborech <ALLOC.H> a <MALLOC.H>.

void *malloc(size_t size);

-          size je rozsah alokované paměti v bytech,

-          funkce vrací:

o       pointer na oblast paměti,

o       nulu, jestliže alokace nebyla provedena.

Příklad:

char Pole=(char *)malloc(100);

Další funkce:

void *calloc(size_t nitems,size_t size);

-          nitems – kolik bloků paměti velitosti size se má alokovat.

Příklad:

Cas *pC

pC=(Cas *)calloc(10,sizeof(Cas));

Ekvivalentní zápis:

pC=(Cas *)malloc(10*sizeof(Cas));

Uvolnění paměti:

free(pointer)

Realokace paměti

Pro změnu rozsahu alokovaného bloku paměti použijeme funkci:

void *realloc(void *oldblock,size_t size);

-          oldblock je pointer na původní alokovaný blok v paměti.

Zjištění velikosti volné paměti

Pro malé datové modely:

unsigned coreleft();

Pro velké datové modely:

unsigned long coreleft();

Test paměti

Funkce pro test správného přidělování paměti.

int heapcheck();

-          funkce vrací hodnotu:

o       větší než nula, jestliže přidělování paměti je v pořádku,

o       menší než nula, pokud systém přidělování paměti je narušen.

8.2.        Funkce pro práci s řetězci

Funkce pro práci s řetězci jsou v souboru <string.h>.

Kopírování řetězce

char *strcpy(char *dest, const char * src);

Příklad:

char Jaz[]=“Jazyk C++“, Ret[20];

strcpy(Ret,Jaz);

char *strncpy(char *dest, const char * src, size_t maxlen);

-          maxlen – maximální délka, která se při kopírování přenese.

Spojování řetězců

char *strcat(char *dest, const char * src);


Příklad:

char Ret=“Jazyk“;

strcat(Ret,“ C++“);

char *strncat(char *dest, const char * src, size_t maxlen);

-          maxlen – maximální délka řetězce src, který se připojí k řetězci v poli dest.

Délka řetězce

size_t strlen(const char * s);

Kopírování řetězce

char *stcpy(char *dest, const char * src);

-          tato funkce se od strcpy liší návratovou hodnotou:

o       stcpy vrací pointer na konec řetězce ve výstupním poli,

o       strcpy vrací pointer na začátek řetězce ve výstupním poli.

Alokace paměti a uložení řetězce

char *strdup(const char * src);

-          nejdříve alokuje blok paměti o délce strlen(src)+1. Je-li alokace úspěšná, uloží do alokované oblasti řetězec.

Srovnání dvou řetězců

int *strcmp(const char *s1, const char * s2);

-          funkce vrací hodnotu:

o       <0, jestliže řetězec s1 je menší než s2,

o       0, jsou-li oba řetězce shodné,

o       >0, jestliže je s1 větší než s2.

int *strncmp(const char *s1, const char * s2, size_t maxlen);

-          funkce srovnává řetězce nejvýše v délce maxlen.

int *stricmp(const char *s1, const char * s2);

int *strnicmp(const char *s1, const char * s2, size_t maxlen);

-          srovnávají řetězce bez ohledu na velikost písmen.


Vyhledávání zanku v řetězci

const char *strchr(const char *s, int c);

-          funkce vrací:

o       pointer na první výskyt znaku, který je zadán v parametru c,

o       hodnotu 0, jestliže znak není v řetězci obsažen.

const char *strrchr(const char *s, int c);

const char *strrchr(char *s, int c);

-          funkce vrací:

o       pointer na poslední výskyt znaku, který je zadán v parametru c,

o       hodnotu 0, jestliže znak není v řetězci obsažen.

const char *strpbrk(const char *s1, const char *s2);

char *strpbrk(char *s1, const char *s2);

-          funkce hledá, zda se v řetězci s1 nevyskytuje některý ze znaků, které jsou uvedeny v řetězci s2,

-          funkce vrací:

o       pointer na první výskyt znaku, který je obsažen v řetězci s2,

o       hodnotu 0, jestliže žádný znak není uvedený v řetězci s2 není v řetězci s1.

Vyhledávání podřetězce v řetězci

const char *strstr(const char *s1, const char *s2);

char *strstr(char *s1, const char *s2);

-          funkce hledá první výskyt řetězce s2 v řetězci s1,

-          funkce vrací:

o       pointer na místo, kde v s1 je podřetězec s2,

o       hodnotu 0, jestliže řetězec s2 není v řetězci s1 obsažen.

Změna velikosti písmen v řetězci

char *strupr(char *s);

char *strlwr(char *s);

-          funkce strupr změní všechna písmena v řetězci s na velká,

-          funkce strlwr změní všechna písmena v řetězci s na malá.

Nastavení obsahu řetězce

char *strset(char *s, int c);

-          všechny znaky v řetězci s jsou nahrazeny hodnotou uvedenou v parametru c.

char *strnset(char *s, int c, size_t n);

-          je nahrazeno jen prvních n znaků.

8.3.        Funkce pro práci s bloky paměti

Funkce pro operace s pamětí jsou v souborech mem.h a memory.h.

Přenos (kopie) bloku paměti

void *memcpy(void *dest, const void *src, size_t n);

-          funkce z adresy zadané pointerem src přenese obsah bloku paměti v délce n bytů na adresu zadanou pointerem dest,

-          funkční hodnota je cílový pointer dest.

Příklad:

#include <memory.h>

int A[10], B[10];

memcpy(B,A,sizeof A);

void *memmove(void *dest, const void *src, size_t n);

-          jestliže se obě oblasti paměti překrývají,

-          v závislosti na vzájemné poloze obou oblastí se zvolí směr přenosu od nižších adres k vyšším adresám nebo od vyšších adres směrem k nižším. Tím je zajištěno, že vstupní oblast se přenese do výstupní oblasti bez narušení jejího obsahu při přenosu.

Srovnání bloků paměti

int memcmp(const void *s1, const void * s2, , size_t n);

-          bloky paměti se srovnávají byt po bytu v délce n bytů,

-          funkce vrací hodnotu:

o       <0, jestliže první rozdílní byte v s1 je menší než s2,

o       0, jsou-li oba bloky paměti shodné,

o       >0, jestliže první rozdílný byte v s1 je větší než s2.

int memicmp(const void *s1, const void * s2, size_t n);

-          srovnávají paměti bez ohledu na velikost písmen.

Vyhledávání znaku v paměti

void *memchr(const void *s, int c, size_t n);

-          funkce hledá výskyt znaku c v oblasti, jejíž adresa je uvedená v prvním parametru funkce a která má délku n bytů,,

-          funkce vrací:

o       pointer na první výskyt znaku c,

o       hodnotu 0, jestliže znak není obsažen v bloku paměti.

Nastavení bloku paměti

char *memset(char *s, int c, size_t n);

-          funkce zapíše hodnotu c do všech bytů bloku paměti zadaného pointerem s a dlouhého n bytů.

8.4.        Funkce a makra pro práci se znaky

Funkce a makra pro operace jsou deklarovány v souboru ctype.h.

Makra pro test znaků

Makra testují, zda znak patří do určité skupiny.

Prototyp makra:                                              Makro testuje, zda parametr c je

int isalnum(int c);                         písmeno nebo číslice

int isalpha(int c);                         písmeno

int isdigit(int c);                         číslice

int islower(int c);                         malé písmeno

int isupper(int c);                         velké písmeno

int isxdigit(int c);                      hexadecimální číslice

int isprint(int c);                         tisknutelný znak

int isgraph(int c);                         tisknutelný znak mimo mezeru

int isascii(int c);                         znak v základní části ASCII tabulky

int iscntrl(int c);                         řídíci znak

int isspace(int c);                         mezera nebo znaky 9-0xD

-          makro vrací:

o       nenulovou hodnotu, jestliže je test splněn,

o       hodnotu 0, jestliže znak nemá testovanou vlastnost.

Úpravy znaků

int tolower(int c);

int _tolower(int c);

-          makro tolower a funkce _tolower mění velká písmena na malá, ostatní znaky vrací beze změny.

int tolupper(int c);

int _toupper(int c);

-          makro toupper a funkce _toupper mění malá písmena na velká, ostatní znaky vrací beze změny.


8.5.        Pole pointerů

spec typ *dekl ident[počet prvk;]=seznam;

Příklad:

#include <stdio.h>

const char *Mesice[]=;

void main()

9.   Třídy, objekty

-          v jazyku C++ se pro definici objektů používá klíčové slovo class,

-          jeho český překlad třída se používá pro označení objektu jako deklarovaného datového typu,

-          termín objekt se pro odlišení používá pro označení konkrétního deklarovaného objektu dané třídy,

-          vzájemný vztah objektu a třídy vyjadřujeme pojmem instance – objekt je instancí třídy.

9.1.        Deklarace třídy

-          třídu deklarujeme jako typ struct, ve kterém vedle deklarací datových členů jsou i definice funkcí,

-          pro třídy je ještě určen další typ deklarace s klíčovým slovem class,

-          deklarace:

struct identt deklx1,…, deklxm;

class identt deklx1,…, deklxm;

-          rozdíl mezi oběmi typy je pouze v implicitním nastavení přístupu k datovým členům a funkcím tříd.

9.2.        Přístup k datovým členům a funkcím třídy

-          pro datové členy i funkce při sestavování třídy stanovíme, jak lze k nim přistupovat. K tomu slouží klíčová slova:

o       public – přístup k datovým členům a funkcím třídy není omezen, jsou přístupné ve třídě i mimo třídu.

o       protected – datové členy a funkce jsou přístupné ve třídě, která je obsahuje. Dále ve třídách, které tuto třídu dědí a ve spřátelených třídách a funkcích.

o       private – datové členy a funkce jsou přístupné jen uvnitř třídy. Pro jiné třídy a pro globální funkce jsou přístupné jen tehdy, jsou-li ve třídě deklarovány jako friend.

-          implicitní nastavení:

o       public – pro třídy deklarované s klíčovým slovem struct,

o       private – pro třídy deklarované class.

9.3.        Konstruktor a destruktor

-          konstruktor je funkce volaná při vzniku objektu, platí pro ni tyto zásady:

o       jméno konstruktoru je shodné se jménem třídy,

o       konstruktor nevrací hodnotu, typ funkční hodnoty se u něj neuvádí,

o       lze definovat více konstruktorů – musí se lišit typem nebo počtem parametrů,

o       definice konstruktoru není povinná,

o       konstruktor nelze explicitně volat.

-          destruktor je funkce, která se volá při zániku objektu, platí pro ni tyto zásady:

o       jeho název je sestaven ze znaku ~ a jména třídy,

o       destruktor nevrací hodnotu, typ funkční hodnoty u něj neuvádíme,

o       destruktor je vždy funkce bez parametrů,

o       destruktor nemusí být ve třídě definován,

o       destruktor lze explicitně volat.

-          vznik objektu a tím i volání konstruktoru je:

o       u deklarace na globální úrovni, při spuštění programu,

o       u lokální deklarace v místě, kde je deklarace objektu,

o       u dynamicky vytvořeného objektu v okamžiku volání operátoru new.

-          zánik objektu a tím i volání destruktoru:

o       u deklarace na globální úrovni, při ukončení programu,

o       u lokální deklarace mimo typ static při opuštění složeného příkazu,

o       u lokální deklarace typu static při ukončení programu,

o       u dynamicky vytvořeného objektu při jeho zrušení operátorem delete.

-          v případě, kdy pro vytvoření objektu použijeme konstruktor s parametry, je nutné v deklaraci objektu nebo při dynamickém vytvoření objektu uvést hodnoty parametrů pro konstruktor objektu,

-          deklarace objektu má zápis:

identt ident(..parametry..);

-          dynamické vytvoření objektu:

identt *identp = new identt(..parametry..);

-          bez parametrů zápis vypadá takto:

identt ident;

identt *identp = new identt;

-          konstruktor i destruktor musí být přístupný i mimo objekt, musí tedy být typu public,

-          v konstruktoru i destruktoru mohou být volány členské funkce,

-          konstruktor, který je volán s jedním parametrem, se nazývá konvertující konstruktor, můžeme u něj použít i zápis:

identt ident = parametr;

Příklad:

Retez r2(50);

Retez r2=50;

-          při volání destruktoru ve třídě musí obsahovat operátor rozlišení :: , zápis příkazu:

identt::~ident();

-          základní datové typy mají definovaný konstruktor, který lze použít k inicializaci proměnných v konstruktoru třídy:

identt(..parametry..):i1(výraz1), i2(výraz2),…, ik(výrazk) ;

9.4.        Definice členských funkcí

-          členské funkce lze ve třídě definovat dvojím způsobem:

o       napíšeme kompletní definici funkce uvnitř třídy, takové funkce nazýváme inline,

o       ve třídě je jen deklarace (prototyp) funkce a definice funkce je uvedena mimo třídu. Syntaktický zápis takto definované funkce:

dekl identt::ident(..parametry..) ;

-          inline funkce lze definovat dvěmi způsoby:

o       uvedeme zápis definice funkce uvnitř deklarace třídy,

o       u funkcí, jejichž definice je mimo třídu, na začátku definice uvedeme klíčové slovo inline.

9.5.        Statické datové členy

-          ve třídě lze deklarovat datové členy s klíčovým slovem static, které mají odlišné vlastnosti:

o       jsou uloženy mimo objekty dané třídy,

o       existují nezávisle na objektech, tedy i v případě, kdy neexistuje žádný objekt dané třídy,

o       vedle jejich uvedení v deklaraci třídy je nutné je deklarovat mimo třídu zápisem:

dekl identt::ident;

dekl identt::ident=výraz;

o        jejich hodnota je společná pro všechny objekty třídy,

o       pro přístup k takovýmto datovým členům můžeme použít standardní přístup přes objekty nebo tvar zápisu, který není vztažen k žádnému objektu:

identt::ident

9.6.        Statické funkce

-          členské funkce, které používají pouze statické datové členy jsou nezávislé na existenci objektů třídy, lze je tedy definovat jako funkce typu static,

-          zápisy volání funkce jsou obdobné jako zápisy datových členů.

9.7.        Spřátelené třídy

-          všechny datové členy a funkce třídy A (tedy i typu private a protected) se stanou přístupná ve třídě B, jestliže v deklaraci třídy A uvedeme na libovolném místě deklaraci:

friend B;

friend class B;

9.8.        Spřátelené funkce

-          zpřístupnit lze datové členy a funkce třídy také pouze pro některé funkce,

-          všechny datové členy a funkce třídy A se stanou přístupné funkci F třídy B, jestliže ve třídě A uvedeme deklaraci funkce s klíčovým slovem friend na začátku:

friend dekl B::F(..parametry..);

-          v případě, že chceme zpřístupnit třídu A pro globální funkci F, do třídy zařadíme deklaraci:

friend dekl ::F(..parametry..);

9.9.        Konstantní funkce

-          konstantní funkce třídy může být jen členská funkce, která při volání nemění hodnoty datových členů třídy:

dekl identt::ident(..parametry..) const;

9.10.   Konstantní objekt

-          se specifikací const lze deklarovat konstantní objekty,

-          pro jejich použití platí omezující podmínky:

o       datovým členům lze přiřadit hodnotu jen v konstruktoru,

o       lze volat jen konstantní členské funkce.

9.11.   Dočasné (temporary) objekty

-          při volání funkce lze použít i objekty, které nejdou deklarované,

-          v tomto případě do parametru funkcí (nebo do výrazů) zapíšeme inicializační konstruktory objektu,

-          před voláním funkce se automaticky vytvoří dočasný objekt, který po návratu z funkce zanikne.

9.12.   Pole objektů

-          pole pointerů se deklaruje obdobných způsobem jako pole jiných datových typů,

-          je-li konstruktor implicitní, lze pole objektů alokovat běžným postupem operátorem new:

identt *pointer;

pointer=new identt [počet_objektů];

delete [] pointer;

-          v deklaraci pole objektů, které jsou tvořeny konstruktorem s parametry, je nutné uvést seznam volání konstruktorů pro jednotlivé objekty pole, nelze takovéto pole vytvářet operátorem new.

9.13.   Objekty jako datové členy tříd

-          objekty mohou být datovými členy jiných tříd,

-          deklarace objektů s implicitním konstruktorem se píše běžným způsobem,

-          deklarace objektů, kde konstruktor má parametry, se objekt deklaruje jako objekt bez parametrů a konstruktor objektu se uvede v konstruktoru třídy:

identt (..parametry..): ident1 (..parametry..)… identj (..parametry..);

9.14.   Skrytí datových členů (encapsulation)

-          v objektově orientovaném programování se preferuje skrytí všech datových členů třídy , tj. žádný datový člen není přístupný mimo třídu (není public),

-          veškeré operace a manipulace s datovými členy jsou zajištěny prostřednictvím členských funkcí.

10.         Dědění tříd

10.1.   Dědění jedné třídy

-          dědičnost nám umožňuje deklarovat novou třídu, která přejímá (dědí) datové členy a funkce jiné nebo jiných tříd,

-          nejčastější je případ, kdy nová třída B dědí datové členy a funkce z jedné třídy A:


Přístupové vlastnosti členů při dědění třídy

 class B : public A ;

-          specifikace public u výchozí třídy A stanoví toto:

o       Člen z třídy A:           public              protected        private

o       je ve  třídě B jako:     public              protected        není přístupný

class B : protected A ;

-          specifikace protected u výchozí třídy A stanoví toto:

o       Člen z třídy A:           public              protected        private

o       je ve  třídě B jako:     protected        protected        není přístupný

class B : private A ;

-          specifikace private u výchozí třídy A stanoví toto:

o       Člen z třídy A:           public              protected        private

o       je ve  třídě B jako:     private             private             není přístupný

-          toto je implicitní specifikace a je shodná s tím, když klíčové slovo private neuvedeme.

Konstruktory a destruktory

-          při vzniku a zániku objektu třídy, která vznikla děděním, se vedle konstruktoru a destruktoru volá automaticky i konstruktor a destruktor děděné třídy,

-          při vzniku objektu je nejdříve volán konstruktor děděné třídy a po něm vlastní konstruktor třídy,

-          při zániku objektu je naopak nejdříve volán vlastní destruktor třídy a po něm destruktor děděné třídy,

-          v případě, kdy konstruktor děděné třídy A má parametry, je nutné v definici konstruktoru třídy B uvést volání konstruktoru třídy A. Zápis konstruktoru třídy B, který dědí třídu A:

B(..parametryB..): A (..parametryA..);

Operátor rozlišení

-          jestliže je v dědící třídě B uveden člen se stejným jménem jako má člen děděné třídy A, dochází v dědící třídě ke skrytí členu děděného ze třídy A, stejné je to i u funkce, kde ani nevzniká polymorfismus,

-          přístup k takto skrytým datovým členům a funkcím máme přes operátor ::

::ident

identt::ident

Virtuální funkce

-          vezměme nyní tento případ:

Příklad:


#include <stdio.h>

#include <math.h>

class Valec

                    float Obsah()

                    float Objem() };

class Kvadr: public Valec

             float Obsah() };

Valec Val(2,5);

Kvadr Kv(2,3,5);

void main()

Výstup: 125.664 125.664

-          pro tyto případy se zavádí virtuální funkce:

#include <stdio.h>

#include <math.h>

class Valec

                    virtual float Obsah()

                    float Objem() };

class Kvadr: public Valec

             float Obsah() };

Valec Val(2,5);

Kvadr Kv(2,3,5);

void main()

Výstup: 125.664 30

-          funkce, která je zapsána v tomto tvaru:

virtual dekl identt (..parametry..)=NULL;

virtual dekl identt (..parametry..)=0;

-          se nazývá čistě virtuální a není v dané třídě definována, ale pouze deklarována,

-          třída, která obsahuje pouze čistě virtuální funkce se nazývá abstraktní, nelze vytvořit její objekt, lze ji jen dědit jinými třídami, v procesu dědění musí být každá vituální funkce definována.

Pointery na třídu, virtuální destruktor

-          pointer na třídu lze použít:

o       pro uložení adres objektů třídy,

o       pro adresy objektů tříd, které ji dědí.

-          máme-li třídu A, pak platí:

A *p;

p -> člen_třídy_A

-          operace je korektní, jestliže pointer obsahuje adresu objektu třídy A nebo adresu objektu, která třídu A dědí.

Příklad:

class A;

class B: public A ;

A a, *pa;

B b, *pb;

a=b;

b=a; //chyba

pa=&a;

pa=&b;

pb=&a; //chyba

-          ve třídě lze definovat virtuální destruktor (konstruktor virtuální být nemůže).

10.2.   Dědění více tříd

-          dědičnost více tříd využíváme pro sestavení třídy, ve které používáme (dědíme), datové členy a funkce z více různých tříd:

Třída A1

 

Třída An

 


                                       


-          deklarace třídy B, která dědí třídy A1, A2, …, An:

class B : public A1, public A2,…, public An;

Konstruktory a destruktory

-          při vzniku a zániku objektu třídy, která vznikla vícenásobnou dědičností, se vedle konstruktoru a destruktoru třídy volají automaticky konstruktory a destruktory všech děděných tříd,

-          konstruktory děděných tříd jsou volány v pořadí, v jakém jsou třídy uvedeny v deklaraci, destruktory v opačném pořadí,

-          jestliže konstruktory děděných tříd mají parametry, je nutné uvést volání jejich konstruktorů v konstruktoru děděné třídy:

B(..parametry..) : A1(..parametry..), A2(..parametry..),…, An (..parametry..);

Vícenásobný přístup, virtuální dědění třídy

-          vezměme si tento případ:


-          v třídách B1 a B2 jsou stejné proměnné a funkce, které obě třídy podědily z třídy A. Třída C touto cestou dědí dvakrát,

-          pro tyto případy se používá virtuální dědění tříd. Třída, která je při dědění označená klíčovým slovem virtual, je děděná vždy jen jedenkrát bez ohledu na to, kolika cestami je děděná,

-          předchozí příklad by vypadal takto:

class A ;

class B1: public virtual A ;

class B2: public virtual A ;

class C: public B1, public B2;

-          konstruktory virtuálně děděných tříd jsou volány před konstruktory nevirtuálně děděných tříd,

-          destruktory virtuálně děděných tříd jsou volány až po destruktorech nevirtuálně děděných tříd,

-          lze dědit stejné datové členy a funkce i bez virtuálních tříd, pak při jejich použití je operátorem :: nutné stanovit, z které třídy jsou zděděné.

11.         Streamy

-          stream je termín pro datový tok,

-          používají se pro vstup a výstup,


11.1.   Streamy pro standardní zařízení

-          všechny třídy se nacházejí v knihovně iostream.h

Výstup na standardní zařízení

-          výstup přes stream cout je obdobou funkce printf,

-          pro výstup se používá překrytý operátor <<:

cout << výstup

-          hodnoty výstupu  v pořadí, v jakém jsou v příkazu výstupu zapsány zleva doprava,

-          do příkazu výstupu lze uvést výrazy datových typů:

o       char, int, long,

o       char *  (výstup řetězce),

o       float, double, long double,

o       void * (výstup pointeru).

Příklad:

char c= ‘A’;

int I= -5;

cout<<”nZnak: “<< c << “ vyraz: “<< i+2;

Výstup: Znak: A vyraz: -3

Formátování výstupu – manipulátory

-          manipulátory jsou definovány v souboru iomanip.h,

-          hlavní manipulátory jsou tyto:

Manipulátor:   Hodnota:        Význam:

skipws              1                      přeskočí nevýznamné mezery při vstupu

left                   2                      zarovná vstup vlevo

right                 4                      zarovnává výstup vpravo

internal            6                      vložení mezery po znaménku nebo označení číselné soustavy

dec                   0x10                desítková soustava   

oct                   0x20                oktálová soustava

hex                   0x40                hexadecimální soustava

showbase         0x80                zobrazení číselné soustavy u výstupní hodnoty

showpoint        0x100              zobrazení desetinné tečky

uppercase        0x200              výstup hexadecimálních čísel velkými písmeny

showpos          0x400              výstup kladných čísel se znaménkem +

scientific          0x800              výstup čísel v pohyblivé řádové čárce s exponentem

fixed                 0x1000            výstup čísel v pohyblivé řádové čárce v desetinném tvaru

unitbuf             0x2000            vyprázdnění vyrovnávacích pamětí všech streamů

stdio                 0x4000            vyprázdnění vyrovnávacích pamětí vstupů na stdout, stderr

Příklad:

cout<< oct << 100 << “ “;

cout<< dec << 100 << “ “ << hex << 100;

Výstup: 144 100 64

-          pro nastavení dalších manipulátorů , které jsou definovány ve třídě ios, se používá funkce:

setioflags(long);

-          funkce nastaví všechny manipulátory, pro které odpovídající bit v parametru má hodnotu 1,

-          hodnotu parametru funkce sestavíme jako součet hodnot jednotlivých manipulátorů, použijeme k tomu operátor bitového součtu |,

-          pro přístup k manipulátorům použijeme operátor :: (např. ios::left),

-          nastavení manipulátorů zrušíme funkcí:

resetioflags(long);

-          další manipulátory:

o       endl – přechod na nový řádek,

o       ws – vynechá nevýznamné mezery (je určen pro vstup),

o       ends – při výstupu ukládá ukončující nulu na konec řetězce,

o       setw(šířka) – nastavení šířky výstupu ve znacích,

o       setprecision(počet míst) – pro nastavení počtu míst výpisu čísla v pohyblivé řádové čárce,

o       setfill(znak) – definuje znak pro vyplnění výstupu s pevnou délkou.

-          některé manipulátory se dají nahradit funkcemi, definovanými ve třídě ios:

Manipulátor                       lze nahradit funkcí

setw(n)                               width(n)

precision(n)                       precision(n)

setfill(c)                              setf(l)

setiosflags(l)                      setf(l)

resetiosflags(l)                   unsetf(l)

Vstup ze standardního zařízení

-          výstup přes stream cin je obdobou funkce scanf,

-          pro výstup se používá překrytý operátor >>:

cout >> výstup

-          hodnoty výstupu  v pořadí, v jakém jsou v příkazu výstupu zapsány zleva doprava,

-          pro ověření, zda vstup hodnot proběhl bez chyb, lze použít překrytí operátoru ! nebo konverze na typ void *,

-          lze také použít funkci good, která  vrací nenulovou hodnotu, jestliže je vstup úspěšný,

-          jestliže pokračujeme nebo opakujeme čtení, je nutné příznak vynulovat funkcí:

void clear(int=0);

-          dále po chybném čtení zůstávají na vstupu nepřečtené znaky. K jejich odstranění lze použít funkci:

istream &ignore(int n=1, int delim=EOF);

-          n je maximální počet znaků odstraněných ze vstupu,

-          delim je znak, po jehož odstranění ze vstupu se funkce ukončí.

-          další funkce:

int peek();

-          umožňuje zjistit hodnotu znaku na vstupu,

istream &putback(char);

-          naposledy přečtený znak vrátí opět na vstup.

11.2.   Streamy pro datové vstupy

-          všechny třídy jsou v souboru fstream.h.

Otevření a uzavření souboru

-          otevření souboru je možné dvěma způsoby:

o       při vzniku objektu – v konstruktoru se uvádí cesta k souboru,

o       členskou funkcí open, pro tento případ se používá implicitní konstruktor (bez parametrů).

-          uzavření souboru je rovněž dvěma způsoby:

o       automaticky destruktorem při zániku objektu,

o       členskou funkcí close.

Otevření souborů použitím konstruktorů

-          deklarace konstruktorů:

ifstream (const char far *, int=ios::in, int=filebuf::openprot);

ofstream (const char far *, int=ios::out, int=filebuf::openprot);

fstream (const char far *, int, int=filebuf::open prot);

-          v 1. parametru uvedeme cestu k souboru,

-          v 2.parametru jsou atributy otevření souboru:

o       ios::in – otevření pro čtení (implicitní pro ifstream),

o       ios::out – otevření pro zápis (implicitní pro ofstream),

o       ios::app – otevření pro pokračování v zápisu (append),

o       ios::binary – binární soubor (implicitně je textový),

o       ios::ate – při otevření je soubor nastaven na konec,

o       ios::nocreate – otevření jen pro přepsání souboru,

-          3. parametr je pro sdílení souboru:

o       filebuf::sh_compact – stejné jako implicitní hodnota openprot, soubor lze sdílet (pokud to dovolí OS),

o       filebuf::sh_none – soubor nelze sdílet,

o       filebuf::sh_read – lze sdílet jen při čtení,

Příklad:

ofstream Soub(“Test”);

Soub<<’A’;

ofstream Soub(“Test”,ios::app);

Soub<<’C’;

ifstream Soub(“Test”);

char c,d;

Soub>> c >> d

Otevření souborů s použitím funkce open

-          deklarace ve třídě ifstream:

void open(const char far *, int=ios::in, int=filebuf::openprot);

-          deklarace ve třídě ofstream:

void open(const char far *, int=ios::out, int=filebuf::openprot);

-          deklarace ve třídě fstream:

void open(const char far *, int, int=filebuf::openprot);

Uzavření souboru funkcí close

-          zápis deklarace funkce:

void close();

Formátový vstup/výstup

-          pro formátový zápis a čtení ze souboru se používají překryté operátory << a >> obdobným způsobem jako pro standardní zařízení.

Neformátový vstup/výstup

Funkce write

-          slouží pro neformátovaný zápis:

ostream &write(const signed char *, int n);

ostream &write(const unsigned char *, int n);

-          v 1. parametru je adresa pole obsahující zapisovaná data,

-          v 2. parametru je počet zapisovaných bytů.

Funkce put

-          slouží pro neformátový zápis jednoho znaku:

ostream put(char);

Funkce read

-          slouží pro neformátované čtení:

istream &read(signed char *, int);

istream &read(unsigned char *, int);

-          v 1. parametru je adresa pole, do kterého se uloží přečtená data,

-          v 2. parametru je počet přečtených bytů.

Funkce get

-          je určena pro čtení řetězce:

istream &get(signed char *, int len, char=’n’);

istream &get(unsigned char *, int len, char=’n’);

-          v 1. parametru je výstupní pole,

-          v 2. parametru je maximální délka řetězce,

-          ve 3. parametru je ukončující znak.

-          pro čtení znaku:

istream &get(signed char &);

istream &get(unsigned char &);

Funkce getline

-          slouží k neformátovanému čtení řetězce:

istream &getline(signed char *, int len, char=’n’);

istream &getline(unsigned char *, int len, char=’n’);

Test konce souboru

-          lze použít funkci eof:

int eof();

-          funkce vrátí hodnotu 0, není-li konec souboru,

-          vrací nenulovou hodnotu, je-li konec souboru,

-          počet přečtených znaků lze zjistit funkcí:

int gcount();

Příznaky chyb při zpracování

-          zda zpracování souboru bylo úspěšné, lze zjistit funkcí:

int good();

-          jestliže operace proběhly úspěšně, funkce vrací nenulovou hodnotu,

-          jestliže vrátí 0, potom:

o       došlo k chybě ve zpracování souboru,

o       při čtení bylo dosaženo konce souboru.

-          další funkce:

int fail();

-          vrací nenulovou hodnotu, pokud došlo k chybě při zpracování souboru,

-          funkce:

int bad();

-          vrací nenulovou hodnotu jen při závažné chybě,

-          lze použít i překrytý operátor ! – hodnota operace je nenulová, jestliže došlo k chybě při zpracování souboru,

-          jestliže po chybě budeme pokračovat ve zpracování souboru, je nutné příznak chyby vynulovat funkcí:

void clear();

Přímý přístup k souboru

-          pro zjištění pozice vstupu (čtení) je funkce:

long tellg();

-          pro zjištění pozice výstupu (zápisu) je funkce:

long tellp();

-          obě funkce vrací aktuální pozici, na které právě probíhá zpracování souboru,

-          pro nastavení pozice pro čtení(vstup) je funkce:

istream& seekg(long);

istream& seekg(long,seek_dir);

-          pro nastavení pozice pro výstup(zápis) je funkce:

istream& seekp(long);

istream& seekp(long,seek_dir);

-          první parametr udává pozici,

-          druhý parametr může nabývat jednu ze tří hodnot, které jsou ve třídě ios:

o       beg – hodnota prvního parametru je vztažena k počátku souboru,

o       cur – hodnota prvního parametru je vztažena vzhledem k aktuální pozici,

o       end – hodnota prvního parametru je vztažena vzhledem ke konci souboru.

11.3.   Streamy pro vstup/výstup v paměti

-          třídy jsou definovány v souboru strstream.h.

Streamy pro vstup z paměti

-          ekvivalent standardní funkce sscanf pro čtení hodnot z paměti je mezi streamy třídy istsstream,

-          má dva konstruktory s deklaracemi:

istrstream (const char *);

istrstream (const char *, int n);

-          první konstruktor použijeme, jestliže hodnoty čteme z řetězce,

-          druhý pro případ, kdy vstupem je pole (délka pole je udána v druhém parametru).

Streamy pro výstup do paměti

-          ekvivalent standardní funkce sprintf pro čtení hodnot z paměti je mezi streamy třídy ostsstream,

-          má tento konstruktor:

ostrstream (char *, int, int=ios::out);

-          v 1. parametru zadáme adresu výstupního pole,

-          v 2. parametru je délka výstupního pole,

-          3. parametr může nabýt hodnot:

o       ios::out – výstupní hodnoty jsou ukládány od počátku pole,

o       ios::ate – výstupní hodnoty jsou ukládány jako pokračování předchozího zápisu,

o       ios::app – stejné jako ate.

Streamy pro vstup/výstup v paměti

-          třída strstream nám umožňuje současný vstup i výstup v paměti,

-          konstruktor:

strstream (char *, int, int);

-          v 1. parametru zadáme adresu výstupního pole,

-          v 2. parametru je délka výstupního pole,

-          3. parametr má běžné hodnoty - ios::out, ios::ate, ios::app, ios::binary (binární zápis nebo čtení).

12.         Překrytí (overloading) operátorů

-          překrytí operátorů umožňuje některé členské funkce nahradit operátory,

-          překrýt lze všechny operátory kromě:

o       .          výběr členu

o       .*        pointer na člen

o       ::         vymezení rozsahu platnosti

o       ?:        podmíněný výraz

-          při překrytí zůstávají zachovány základní vlastnosti operátorů:

o       arita – unární operace při překrytí zůstává unární, binární binární,

o       priorita – ve výrazu, který obsahuje překryté operátory, je pořadí vykonání operace určeno standardními prioritami operátorů.

-          překrytí operátoru lze definovat jen pro třídy (až na některé speciální případy),

-          jsou dva způsoby, jak definovat překrytí operátorů:

o       členskou funkcí třídy,

o       funkcí, která není členská.

-          u překrytí členské funkcí se používá tvar:

Třída

 

operace

 

libovolný datový typ

 


binární

operace

 

Třída

 


unární

-          u překrytí nečlenskou funkcí se používá stejný tvar, ale může se použít i:

libovolný datový typ

 

operace

 

Třída

 


-          deklarace překrytí:

-         

dekl operator op (dekl2);

o       dekl je deklarace typu výsledku operace,

o       op je překrytý operátor,

o       dekl2  je deklarace pravého operandu operace.

 Příklad:

short operator + (short j)

-          překrytí běžných (prefixových) unárních operátorů je definováno členskou funkcí tvaru:

-         

dekl operator op ();

o       dekl je deklarace typu výsledku operace,

o       op je překrytý operátor,

Příklad:

int operator ! ()

12.1.   Překrytí operátoru []

-          na rozdíl od standardního významu operátoru indexu, ve kterém je index celočíselný typ, lze při překrytí operátoru index použít jako libovolný typ,

-          operand reprezentující index se v definici funkce překrytí uvádí na místě druhého operandu:

dekl operator [] (operand_indexu) ;

12.2.   Překrytí operátoru volání funkce ( )

-          operátor volání funkce je opět překryt jako binární operátor,

-          druhý operand je seznam formálních parametrů funkce:

dekl operator ( ) (seznam formálních parametrů) ;

12.3.   Překrytí operátorů ++ a - -

-          operátory lze překrýt v prefixové i postfixové podobě,

-          překrytí v prefixové podobě:

dekl operator ++ ();

dekl operator - - ();

-          překrytí v postfixovém tvaru se provádí pomocí binární operace, druhý operand má typ int, jeho uvedení má jen formální význam a slouží pouze pro označení, že jde o postfixový operátor:

dekl operator ++ (int);

dekl operator - - (int);

12.4.   Pointer na objekt

-          jako výsledek překrytých operací se často používá pointer na objekt třídy a ještě častěji reference na objekt třídy,

-          pro tyto účely je zaveden pointer označovaný klíčovým slovem this, jeho hodnotou je adresa objektu, ve kterém je uveden (použit),

-          při překrytí se potom použije tímto způsobem:

return this;

-          pointer this nelze použít ve statické funkci,

-          z pointeru this se dostaneme k referenci na objekt třídy přes operátor dereference *:

return *this;

12.5.   Konverze typu ( )

-          členskou funkcí lze definovat konverzi třídy na jiný datový typ:

operator dekl ();

-          dekl je deklarace datového typu, na který má být třída konvertována.

Příklad:

class Int

           operator int () }

void main()

12.6.   Překrytí operátorů << a >>

-          oba operátory lze jsou z hlediska překrytí binární operátory:

třída &operator << (operand);

třída &operator >> (operand);

12.7.   Překrytí operátoru funkcemi, které nejsou členské

-          používá se zejména tehdy, jestliže v binárním operátoru má být třída druhým operandem,

-          aby funkce překrytí měla přístup ke všem členům třídy, je ve třídě uvedena jako spřátelená (friend),

-          deklarace pro unární operátor:

dekl operator op (ident &);

-          ident – jméno třídy

-          deklarace pro binární operátor:

dekl operator op (ident &, dekl2); dekl operator op (dekl1,ident &);

-          ident – jméno třídy

-          dekl, dekl1 , dekl2 jsou deklarace typu výsledku operace, typu levého operandu a pravého operandu.

Překrytí operátorů << a >>

-          ve třídě istream respektive ostream je definováno překrytí těchto operátorů pro běžné datové typy,

-          pro další typy lze definovat globální funkce, v níž se nový datový typ uvádí jako druhý parametr a voláme ho referencí:

istream &operator >> istream &,ident &);

ostream &operator << ostream &,ident &);

-          ident je jméno třídy, pro kterou definujeme překrytí operátorů.

13.         Vzory (templates)

-          vzory jsou třídy, ve kterých není explicitně stanoven typ dominantních datových členů třídy nebo typ dat, s kterými pracují členské funkce třídy,

-          konkrétní datový typ je specifikován až v deklaracích objektů třídy,

-          základní deklarace vzoru:

template<class T> class ident ;

-          jméno T je označení datového typu,

-          také máme možnost použít klíčové slovo typename:

template<typename T> class ident ;

-          ze vzoru generujeme třídy nahrazením symbolického typu konkrétním datovým typem:

ident<dekl> objekt;

-          ident je jméno vzoru,

-          dekl je deklarace datového typu, který je dosazen za T,

-          objekt je jméno deklarovaného objektu,

-          jiné využití vzorů je v parametrickém zadání rozsahu datových členů třídy, typicky určení velikosti pole deklarovaného ve třídě:

template<typ ident> class ident ;

-          typ je celočíselný typ,

-          ident je jméno parametru,

-          vzory mohou obsahovat i více argumentů:

template<arg1,…, argk> class ident ;

-          arg1,…, argk jsou argumenty, z nichž každý může být datový typ nebo parametrický údaj.

13.1.   Vzory – funkce

-          vzory se symbolickými typy mohou být vedle tříd použity i pro funkce,

-          zápis definice vzoru funkce:

template<arg1,…, argk> dekl ident (..parametry..);

-          arg1,…, argk jsou datové typy (parametrické údaje vzor funkce obsahovat nemůže, ty lze použít jen u tříd),

-          funkci definovanou jako vzor voláme běžným způsobem (dosazené skutečné parametry musí opět podporovat všechny operace použité v definici vzoru funkce).

14.         Výjimky (exceptions)

-          v průběhu výpočtu programu může některá akce selhat (nebyl otevřen soubor, nebyla alokována paměť, …),

-          u jazyka C++ nedochází k ukončení programu, ale ošetření výjimečných stavů se ponechává na programátorovi,

-          standardní funkce nebo operátory vrací pro tento účel příznak, že došlo k chybě,

-          použití výjimek je ve dvou směrech:

1.      U standardních funkcí a operátorů výjimky nahrazují původní příznaky chyb.

2.      Při psaní programu můžeme při sestavování tříd výjimky využít pro ošetření chyb a jiných nežádoucích stavů, ke kterým může dojít v objektech třídy při výpočtu.

-          pro začlenění výjimek do třídy musíme nejprve uvnitř třídy deklarovat samostatnou třídu (nebo třídy) popisující výjimku:

class identt {..deklarace dat.členů a definice funkcí

              class ident1 ;

              class ident2 ;

             

              class identm ; };

-          ident1 , … , identm jsou jména deklarovaných tříd pro výjimky,

-          při chybě generujeme ve třídě výjimku:

throw identj ( );

-          identj je jméno třídy popisující daný typ výjimky (volání implicitního konstruktoru třídy identj),

-          každou činnost (příkaz) s objektem třídy, při kterém může dojít k výjimce, uzavřeme do složeného příkazu try,

-          bezprostředně za příkazem try uvedeme složené příkazy catch pro zachycení výjimky, v nich výjimku ošetříme:

try

  catch (identt:: identi)

  catch (identt:: identj)

 

  catch (identt:: identk)

-          při výskytu výjimky je nejprve vytvořen objekt,

-          při přechodu k bloku catch je tento objekt předán,

-          objekt má dvě funkce:

o       je-li více tříd pro jednu výjimku, pak dle typu objektu blok catch rozliší, ke které výjimce došlo,

o       do datových členů objektu lze uložit doplňující informace popisující, proč k výjimce došlo,

-          jestliže může dojít jen k jednomu typu výjimky, nebo chceme všechny výjimky zachytit jedním příkazem catch, můžeme použít tento zápis:

try

  catch (…)

Příklad:

class Int

operator / (int j) }

class Deleni_Nulou ; };

void main()

catch (Int::Deleni_Nulou)

}

-          ukončení programu při neošetřené výjimce je realizováno voláním funkce terminate, tato funkce je standardně definována v programu, lze místo ní použít vlastní funkci (nevracející hodnotu a bez parametrů):

void ident ( );

-          adresu této funkce musíme předat programu:

set_terminate (ident);

-          třídy deklarované pro výjimky mohou jako každé jiné třídy obsahovat:

o       datové členy – využívají se pro uložení bližších údajů o příčině výjimky, předání údajů je přes konstruktor třídy,

o       členské funkce – jsou využívány pro výpis příčiny výjimky a ošetření výjimky.

-          třídy pro výjimky mohou být děděny dalšími třídami, lze to využít:

o       ve třídě pro zachycení výjimky dědíme datové členy a funkce pro uložení údajů a ošetření výjimek z jiné třídy,

o       naopak třída děděná třídami pro zachycení výjimek získává vlastnost zachytit všechny výjimky, které se zachytí dědícími třídami.

-          jestliže se některá chyba může opakovat, je účelné sestavit si pro tento účel vlastní funkci, můžeme pak chybu nechat neošetřenou a vrátit ji zpět k ošetření, to uděláme příkazem:

throw;

-          hierarchie může pak být takováto:

try

        catch (identt:: identi)

    }

catch (identt:: identj)

-          v deklaraci a definici funkce lze explicitně uvést výjimky, které funkce generuje:

dekl ident(..parametry..) throw (ident1,…,identk);

-          speciálním případem zápisu je deklarace funkce, která nemůže generovat žádnou výjimku:

dekl ident(..parametry..) throw ();

-          jestliže funkce s explicitním uvedením výjimek generuje neočekávanou výjimku, program je předčasně ukončen funkcí unexpected, , lze místo ní použít vlastní funkci (nevracející hodnotu a bez parametrů):

void ident ( );

-          adresu této funkce musíme předat programu:

set_unexpected (ident);

14.1.   Výjimky při alokaci paměti operátorem new

-          mechanismus zachycení výjimky při alokaci je řešen odlišným způsobem,

-          místo třídy používáme funkci (nevracející hodnotu a bez parametrů):

void ident ( );

-          adresu této funkce musíme předat programu:

set_new_handler (ident);

15.         Návrh a koncepece programu

15.1.   Direktivy podmíněného překladu

-          zápis části programu s direktivami podmíněného příkazu:

#if podmínka

  Část programu začleněna do překladu v případě, že podmínka je splněna (různá od nuly).

#endif

-          direktiva může mít také část s #else:

#if podmínka

  Část programu začleněna do překladu v případě, že podmínka je splněna (různá od nuly).

#else

  Část programu začleněna do překladu v případě, že podmínka není splněna (je rovna nuly).

#endif

-          vedle direktivy #if lze použít dvě další direktivy:

#ifdef ident

#ifndef ident

-          direktiva #ifdef do překladu začlení část programu, jestliže v předchozí části programu byla uvedena direktiva:

#define ident

-          direktiva #ifndef do překladu začlení část programu, jestliže v předchozí části programu nebyla uvedena direktiva:

#define ident

-          nebo byla zrušena direktivou:

#undef ident

15.2.   Rozdělení programu na dvě části – project

-          velké programy je účelné rozdělit do více zdrojových částí:

zdrojový soubor 1

 


překlad

 

zdrojový soubor k

 

překlad

 

modul 1

 

modul k

 

knihovny

 


                                                                             

sestavení

 


-          pro vzájemné propojení jednotlivých zdrojových souborů máme prostředky:

1.      Hlavičkové soubory, ve kterých uvádíme:

o       prototypy (deklarace ) funkcí,

o       deklarace odvozených a nových datových typů,

o       deklarace konstant,

o       vzory tříd a funkcí.

2.      Deklarace typu extern.

-          soubory začleníme do hlavního programu pomocí direktivy #include.

15.3.   Formální parametry hlavní funkce – main

-          v hlavní funkci lze uvést formální parametry, kterými se při spuštění programu předávají hodnoty uvedené na příkazové řádce:

void main(int argc, char *argv[]);

-          argc je počet parametrů,

-          argv je pole pointerů, v poli jsou uloženy adresy řetězců, které obsahují jednotlivé části příkazového volání programu,

-          argv[0]cesta k programu,

-          argv[1]první parametr volání,

-          argv[2] – druhý parametr volání atd.

15.4.   Návratová hodnota hlavní funkce – main

-          hlavní funkce může mít deklarovanou návratovou hodnotu typu int,

-          program ji vrací po ukončení,

-          návratová hodnota se vrací funkcí return.

15.5.   Funkce ukončení programu

-          program se ukončí při dosažení konce funkce main.

-          dále lze program ukončit:

o       v libovolném místě hlavní funkce main příkazem return,

o       ve všech funkcích použitím funkcí:

        exit

void exit(int status);

·         uzavřou se všechny otevřené soubory a program se ukončí,

·         status je výsledkový kód (návratová hodnota) programu.

        exit

void abort( );

·         program je ukončen okamžitě – abnormální ukončení.

15.6.   Deklarace asm

-          používá se pro vložení asemblerovského kódu do programu:

asm(instrukce_asembleru);

15.7.   Standardně definovaná makra

-          seznam předdefinovaných maker:

Jméno marka        Význam

_LINE_                 číslo řádku zdrojového souboru

_FILE_                 název zdrojového souboru

_DATE_               datum kompilace programu

_TIME_                čas kompilace programu

_LINE_                 číslo řádku zdrojového souboru

16.         Nové prvky jazyka

16.1.   Třída pro uložení řetězců – string

Pro uložení a práci s řetězci byla vytvořena třída string, která je deklarována v souboru cstring.h. Ve třídě je definována řada funkcí a překrytých operátorů, které poskytují obdobné možnosti práce s řetězci jako standardní funkce ze souboru string.h.

Deklarace implicitního konstruktoru:

string();

Konstruktory s jedním parametrem:

string(const string far &s);

string(const string far *cp);

string(char c);

Konstruktory umožňují vytvářet objekty:

o       z řetězce, který je v jiném objektu,

o       z běžného řetězce,

o       vytvořením řetězce z jednoho znaku.

Konstruktory se dvěmi parametry:

string(char c, size_t n);

Do objektu je uložen řetězec délky n, který má na všech pozicích znak c.

Operace konkatencae

            Pro operaci konkatenace (připojení dalšího řetězce k řetězci uloženému v objektu) lze použít funkci append nebo operátor +=.

string far &append(const string far &s);

string far &append(const char far *cp);

string far &operator += (const string far &s);

string far &operator += (const char far *cp);

Operace srovnání

            Pro srovnání je funkce compare a operátory = =, !=, <, >, <= a >=. Umožňují vzájemně srovnat dva řetězce v objektech nebo srovnat řetězec v objektu s běžným řetězcem. Funkce compare vrací stejné hodnoty jako funkce strcmp.

Operace vstupu a výstupu

Ve třídě jsou také překryté operátory >> a <<. Výsledkem operátoru  << respektive >> je reference na třídu istream respektive ostream.

Ostatní funkce

-          délku řetězce vrací funkce length

-          zda je řetězec prázdný, lze zjistit pomocí funkce is_null. Výsledek funkce je 1 pro prázdný řetězec, jinak 0,

-          pro přístup k libovolnému znaku řetězce jsou operátory indexu [] a funkce (). Jejich použití je shodné:

char operator [] (size_t);

char far &operator [] (size_t);

První překrytí vrací znak, což je rvalue. Druhé překrytí je reference na znak. U reference jde o lvalue a lze mu tedy přiřadit hodnotu.

DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 824
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Distribuie URL

Adauga cod HTML in site



Termeni si conditii de utilizare | Contact
© SCRIGROUP 2019. All rights reserved