CATEGORII DOCUMENTE |
Bulgara | Ceha slovaca | Croata | Engleza | Estona | Finlandeza | Franceza |
Germana | Italiana | Letona | Lituaniana | Maghiara | Olandeza | Poloneza |
Sarba | Slovena | Spaniola | Suedeza | Turca | Ucraineana |
DOCUMENTE SIMILARE |
|
TERMENI importanti pentru acest document |
|
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 slouží k:
Zápis direktivy:
#jméno direktivy parametry
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 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
Datové typy dělíme do tři kategorií:
Základní
Odvozené
Nové
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:
Používá se char nebo unsigned char. Znaky se zapisují s apostrofy. Např. ‘c’, ‘+’.
Logická hodnota číselná hodnota bool
Není pravda 0 false
Je pradva 1, libovolná jiná true
Ř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
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á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ů:
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
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.
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ěť.
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 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 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;
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
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
Obdobné příkazy jako v ostatních procedurálních jazycích.
Příklad:
short q;
A=1;
Je uzavřen složenými závorkami a může obsahovat:
Příklad:
int j;
j=1;
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.
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 obsahuje jen středník.
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.
Je-li v těle cyklu proveden příkaz
break;
je cyklus ukončen. Program pokračuje příkazem, který následuje za cyklem.
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 až 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
Pravidla pro návěští:
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++)
typedef zápis_ve_tvaru_deklarace;
Deklarujeme odvozený datový typ pointeru na int:
typedef int *pInt;
Deklarace pointerů
pInt pi,pi1=0;
je ekvivalentní s deklarací
int *pi,*pi1=0;
Deklarace:
dekl ident[počet_prvků],…;
Zápis prvku pole:
ident[index]
int Pole[10];
Prvky pole jsou
Pole[0], Pole[1],… Pole[9]
Deklarace s iniciací:
dekl ident[počet_prvků]=;
char Pole[10]=
Pro uložení řetězců se používají znaková pole (typu char).
Máme-li pole:
dekl ident[počet_prvků];
pak jsou ekvivaletní zápisy:
*ident ident[0]
*(ident+index) ident[index]
Deklarace:
dekl ident[počet_prvků1] [počet_prvků2]… [počet_prvkům];
Zápis prvku pole:
ident[index1][index2]… [indexm]
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.
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)
struct ident dekl1 ident1=inic1,…,dekln identn=inicn;
struct Dat1, Dat2, *pDat
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:
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).
struct S2
struct S1 ;
struct S2 ;
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;
union U
i | ||||
c[0] |
c[1] |
c[2] |
c[3] |
c[4] |
l | ||||
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;
struct Tepl
Používá se pro deklaraci většího počtu celočíselných konstant.
enum ident dekl1 ident1=výraz1,…,dekln identn=výrazn;
enum Tyden
Potom jednotlivé konstanty mají hodnoty:
Pondeli=0, Utery=1, Streda=2, Ctvrtek=3, Patek=4, Sobota=10, Nedele=11
spec typ &dekl ident=výraz, … ;
Základní vlastnosti:
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, … ;
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
Návrat z funkce typu void (funkce nevracející hodnotu) je:
return;
U funkce, která vrací hodnotu, je návrat příkazem:
return výraz;
Jsou tři druhy formálních parametrů:
Parametry dělíme na:
Příklad:
int F(int p1, int p2)
Používají se pro:
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:
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:
Příklad:
void Rotace(int &p1, int &p2, int &p3)
Volání:
int i=3, j=-2, k=7;
Rotace (i, j, k);
Pro předání výsledku funkce lze použít jeden ze tří způsobů:
Výsledek funkce vracíme hodnotou pro stejné datové typy, pro jaké používáme volání hodnotou ve formálních parametrech.
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);
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);
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)
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 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);
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);
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);
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 . . .
Slouží pro velice krátké funkce.
Vkládá se do programu jako makro.
inline dekl ident(.. parametry ..
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.
Základní funkce:
int printf(const char *format, …
parametr format je řetězec, ve kterém jsou obsaženy:
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:
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
printf(“n%.3f“,10.12345);
Výstup:
printf(“%05u“,10);
Výstup:
V části příznaky lze uvést znaky:
printf(“%+-4i|% i|% i
Výstup:
+1 | 2|-3
Další parametry:
cislo=123456;
printf(“%li %i“,cislo,cislo);
Výstup:
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.
int i,j,k;
scanf(“%i%i%i“,&i,&j,&k);
unsigned i,j,k;
scanf(“%2u%5u%3u“,&i,&j,&k);
printf(“%u %u %u”,i,j,k);
Vstup:
Výstup:
12 34567 890
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);
int getchar(void);
přečte jeden znak ze stand. vstupního zařízení,
makro vrací přečtenou hodnotu.
char ch;
scanf(“%c“,&ch);
ch=getchar()
int *gets(char *s);
přečte obsah celého řádku a uloží do řetězce.
Označení stand. zař. stdout, stdin a stderr jsou rovněž pointery typu FILE, jejich deklaraci bychom mohli zapsat:
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í:
FILE *Soubor;
Soubor=fopen(“Test.txt”,”wt”)
If (!Soubor) printf(“Soubor nelze vytvořit”);
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.
int fprint(FILE *stream, const char *format, …);
FILE *Soubor;
Soubor=fopen(“Test”,”w”)
char S[]=”Jazyk C++”,C=’$’;
fprint(Soubor,“%s%c”,S,C);
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.
FILE *Soubor;
struct Jm=;
Soubor=fopen(“Test”,”w”)
if (fwrite(&Jm,sizeof Jm,1,Soubor)!=1) printf (“Chyba pri zapisu zaznamu Jm”);
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.
int fprint(FILE *stream, const char *format, adresa1,adresa2…);
FILE *Soubor;
int i,j;
char Str
Soubor=fopen(“Test”,”r”)
fscan(Soubor,“%i%i%s”,&I,&j,Str);
unsigned fread(void *ptr,size_t size, size_t count,FILE *stream);
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.
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ů.
int fclose(FILE *stream);
funkce vrátí hodnotu 0, jestliže uzavření bylo úspěšné.
int ferror(FILE *stream);
funkce vrací hodnotu 0, jestliže nenastala chyba.
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.
void perror (const char *s);
funkce vypíše řádek ve formě s: popis chyby.
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.
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));
Výpis:
Cky
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é.
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.
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í |
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.
1.Blízká adresa
rozsah 64 KB,
označení near.
2.Vzdálená adresa
dvojice segment + offset,
označení far.
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.
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);
Zápis alokace paměti:
pointer = new name
Operace new vrací:
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
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)
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.
Pro malé datové modely:
unsigned coreleft();
Pro velké datové modely:
unsigned long coreleft();
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 jsou v souboru <string.h>.
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.
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.
size_t strlen(const char * s);
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.
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.
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.
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.
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.
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á.
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 operace s pamětí jsou v souborech mem.h a memory.h.
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.
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.
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.
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 operace jsou deklarovány v souboru ctype.h.
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.
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.
spec typ *dekl ident[po et prvk;]=seznam;
Příklad:
#include <stdio.h>
const char *Mesice
void main()
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.
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.
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 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) ;
č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.
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
č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ů.
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;
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 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;
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.
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 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 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..)
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ě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:
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.
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..)
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
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.
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ě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
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..)
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é.
stream je termín pro datový tok,
používají se pro vstup a výstup,
všechny třídy se nacházejí v knihovně iostream.h
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
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)
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.
všechny třídy jsou v souboru fstream.h.
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.
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
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);
zápis deklarace funkce:
void close(
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í.
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ů.
slouží pro neformátový zápis jednoho znaku:
ostream put(char
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ů.
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 &
slouží k neformátovanému čtení řetězce:
istream &getline(signed char *, int len, char=’n’);
istream &getline(unsigned char *, int len, char=’n’);
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();
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();
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.
třídy jsou definovány v souboru strstream.h.
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).
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.
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í 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 ! ()
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) ;
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ů
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);
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;
č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()
oba operátory lze jsou z hlediska překrytí binární operátory:
třída &operator << (operand);
třída &operator >> (operand);
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.
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 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 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 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);
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);
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
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.
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.
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.
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í.
používá se pro vložení asemblerovského kódu do programu:
asm(instrukce_asembleru);
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
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.
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);
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.
Ve třídě jsou také překryté operátory >> a <<. Výsledkem operátoru << respektive >> je reference na třídu istream respektive ostream.
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 |
Vizualizari: 1618
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved
Distribuie URL
Adauga cod HTML in site