21.4.2009 Makra - dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h - jak na vlastní makro: #define je_velke(c) ((c) >= 'A' && (c) <='Z') - a potom použití v programu: if (je_velke('a' + 'B')).. - před překladem z toho preprocesor udělá toto: if ((('A' + 'B') >= 'A' && ('A' + 'B') <='Z')).. - opět je nutno závorkovat jak tělo makra, tak jeho parametr uvnitř těla Makra v ctype.h např.: isalnum(c) je číslo nebo písmeno? isalpha(c) je písmeno? isascii(c) je ascii 0-127? iscntrl(c) je ascii 0-26? např. test jen na tisknutelné znaky bez háčků a čárek: if (isascii(c) &&!iscntrl(c)) putchar(c); isdigit(c) je číslice?
islower(c) je malé písmeno? isupper(c) je velké písmeno? isprint(c) je ascii 32-126 (tisknutelné)? ispunct(c) je interpunkční znaménko? (,. / atp.) isspace(c) je mezera, tab, \n tj. nový řádek? isxdigit(c) je hexadec. cislice (0-9, A-F, a-f)? isgraph(c) je ascii 33-126 (i pseudografické znaky)? Konverzní makra tolower(c) - na malá písmena toupper(c) - na velká písmena toascii(c) - ořízne bit s pořadím 7 (tj. osmý, nejvyšší bit), tj. z 8 bitů znaku bere jen dolních 7, tj. 0. až 7. Pole stručný úvod do začátku, podrobně později - statická pole (ne dynamicky) - číslují se od 0 int policko[100]; // tj. pole je od 0 do 99!!! policko[5] = 7; // pozor je to 6. prvek s indexem 5 policko[99] = 2; // poslední prvek. policko[100] = 78; // C nijak neprotestuje příkaz vykoná - hodnota 78 je zapsána do paměti ZA moje pole, přepisuji paměť, kterou nemám přidělenu => pravděpodobně bude program chybovat. Může tam uložena moje jiná proměnná... - to znamená, že C nekontroluje rozsahy polí a ohlídání je na programátorovi musím si udržovat např. nějakou proměnnou, kde budu délku pole uloženu.
Dvourozměrné pole: int pol2d[5][10]; pol2d[0][0] = 4; "Prolezu" dvourozměrné pole: int pole2d[100][100]; for(i = 0; i < 100; i++) for(j = 0; j < 100; j++) pol2d[j][i] = 5; // po sloupcích vždy pro i-tý sloupec projedu všechny řádky (pomocí j) - nebo s konstantami #define RADKU 100 #define SLOUPCU 50...tady nějaký začátek programu int pole2d[radku][sloupcu]; for(i = 0; i < RADKU; i++) for(j = 0; j < SLOUPCU; j++) pol2d[i][j] = 5; // po řádcích vždy pro i-tý řádek projedu všechny sloupce (pomocí j)
Funkce základy (shrnutí ze cvičení) - základní deklarace funkce: návratový_typ název_funkce(typ_parametru název_parametru_funkce) tělo_funkce; return návratová_hodnota; Např: int pocitej_soucin(int a, int b) int pom; pom = a * b; return(pom); /* lze též return pom; */ Jinak totéž: int pocitej_soucin(int a, int b) return(a * b); Pozn.: funkční prototyp této funkce (např. v hlavičkovém souboru) by vypadal takto: int pocitej_soucin(int a, int b); nebo také: int pocitej_soucin(int, int); ------------------- 21.4.2009 ------------------- Potom volání této funkce: void main(void) int vysledek; vysledek = pocitej_soucin(10, 20); printf("vysledek soucinu %d a %d je %d.",5,6,pocitej_soucin(5,6));
- jiný postup - kompletnější void main(void) int vstup1, vstup2, vysledek; vstup1 = 23; vstup2 = 25; vysledek = pocitej_soucin(vstup1, vstup2); printf("vysledek soucinu %d a %d je %d.",vstup1,vstup2, vysledek); - typ proměnné použité jako parametr u return musí být shodný s typem (návratovým typem) dané funkce - lze provést přetypování návratové hodnoty nebo se udělá implicitní typová konverze. Např.: return((int) (a * b)); - pozor pokud funkci volám, musí už být známa (stačí hlavička funkce, tzv. funkční prototyp) #include <stdio.h> /* funkcni prototyt */ int pocitej_soucin(int a, int b); // tato funkce umi scitat void main(void) int vstup1, vstup2, vysledek; vstup1 = 23; vstup2 = 25; vysledek = pocitej_soucin(vstup1, vstup2); printf("vysledek soucinu %d a %d je %d.\n",vstup1,vstup2, pocitej_soucin (vstup1, vstup2)); system("pause"); int pocitej_soucin(int a, int b)
int pom; pom = a * b; return(pom); /* lze též return pom; */
Nebo: void nazdar(void); /* musím uvést, aby ho ahoj mohl zavolat */ int ahoj(void)...nějaké příkazy... nazdar(); /* u funkcí bez parametrů se uvádí závorky */... atd... void nazdar(void)...nějaké příkazy... int v = ahoj(); /* u funkcí bez parametrů se uvádí závorky */... atd... - používá se hlavně pokud jsou funkce v různých souborech potom se nedávají funkční prototypy na začátek, ale do vlastního hlavičkového souboru (.h): Např.: funkce1.h obsahuje: /* funkcni prototyp */ int pocitej_soucin(int a, int b); funkce1.c obsahuje: #include <stdio.h> #include "funkce1.h" void main(void) int vstup1, vstup2, vysledek; vstup1 = 23; vstup2 = 25; vysledek = pocitej_soucin(vstup1, vstup2); printf("vysledek soucinu %d a %d je %d.\n",vstup1,vstup2, pocitej_soucin (vstup1, vstup2)); system("pause"); na konci nebo v jiném souboru: int pocitej_soucin(int a, int b)
int pom; pom = a * b; return(pom); /* lze též return pom; */ - do hlavičkových souborů se umisťují dále konstanty a deklarace nových datových typů (typedef) Dále k funkcím: - pokud funkce nevrací nic návratový typ je void - pokud nemá parametry parametry jsou void - volání funkce bez parametrů: funkce(); /* závorky jsou nutné!!! */ - nezapomenout parametry funkce se chovají jako lokální proměnné - C umí předat parametry do funkce pouze hodnotou, jinak musím obejít (viz dále - pointery) - lokální proměnné uvnitř funkce z vnějšku nejsou vidět, zanikají při skončení "své" funkce - globální proměnné jsou deklarovány mimo funkci, jsou vidět "všude" - nesmí se umístit do souboru.h mohl bych jej víckrát "includovat" => proměnná by byla v projektu několikrát při linkování dojde ke kolizi... lze ošetřit viz dále. - pokud bude mít lokální proměnná ve funkci stejné jako nějaká globální proměnná => lokální proměnná překryje ve funkci tu globální. int g; double fn; double vypocet(int fn) double g; g = 2.45; // měním lokální g, globální g je překryto g = 3.5 * fn; // jde o lokální fn, ten parametr funkce // zde zbytek programu return(nejaky_vysledek);