Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
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

TERMENI importanti pentru acest document

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.

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

Základní datové typy

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

Základní

Odvozené

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

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

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.

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;

pL pL+1

Příklad:

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

pI

*pI=1000;

E8

pI

*(pI+2)=10;

E8

0A

pI

*++pI=5;

E8

0A

pI

++*pI;

E8

0A

pI

*pI++=2;

E8

0A

pI

(*pI)--;

E8

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=

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

Příkazy jazyka

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;

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.

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.

Prázdný příkaz

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

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.

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

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++)

Pole, struktutovaný a výčtový typ

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;

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)

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

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

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

Funkce a reference

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, … ;

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 ..

Vstupy a výstupy

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:

Příklad

printf(“%05u“,10);

Výstup:

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

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:

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:

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.

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

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.

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í

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.

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.

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);

Standardní funkce, pole pointerů

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.

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

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ů.

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ů.

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.

Pole pointerů

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

Příklad:

#include <stdio.h>

const char *Mesice

void main()

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.

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.

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.

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) ;

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.

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

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ů.

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;

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..);

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;

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.

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.

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.

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..)

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í.

Dědění tříd

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:

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:

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).

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é.

Streamy

stream je termín pro datový tok,

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


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  přeskočí nevýznamné mezery při vstupu

left  zarovná vstup vlevo

right  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

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.

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.

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í).

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 ! ()

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) ;

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ů

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);

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;

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()

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);

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ů.

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.

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).

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:

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

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);

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);

Návrh a koncepece programu

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

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:

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í.

Deklarace typu extern.

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

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 cesta k programu,

argv první parametr volání,

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

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.

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í.

Deklarace asm

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

asm(instrukce_asembleru);

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

Nové prvky jazyka

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.



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 1518
Importanta: rank

Comenteaza documentul:

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

Creaza cont nou

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

Distribuie URL

Adauga cod HTML in site