Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

OSNOVA: a) Ukazateleb) Pole a ukazatel c) Pole ukazatelůd) Ukazatele - příklady e) Funkce – úvodf) Hlavičky funkcí g) Rekurze funkcíh) Knihovny funkcí.

Podobné prezentace


Prezentace na téma: "OSNOVA: a) Ukazateleb) Pole a ukazatel c) Pole ukazatelůd) Ukazatele - příklady e) Funkce – úvodf) Hlavičky funkcí g) Rekurze funkcíh) Knihovny funkcí."— Transkript prezentace:

1 OSNOVA: a) Ukazateleb) Pole a ukazatel c) Pole ukazatelůd) Ukazatele - příklady e) Funkce – úvodf) Hlavičky funkcí g) Rekurze funkcíh) Knihovny funkcí i) Funkce - příklady j) Preprocesor k) ANSI-C knihovny Jiří Šebesta Ústav radioelektroniky, FEKT VUT v Brně Počítače a programování 1 pro obor EST KPC1E TUTORIÁL 4

2 Ukazatel (1/10) Ukazatel (pointer) je datový typ sloužící k uložení adresy v paměti počítače Požadovaná velikost pro uložení ukazatele v paměti (počet bytů) je dána paměťovým prostorem, který daný počítačový systém využívá Pro malé mikrokontrolé- rové aplikace je ukazatel obvykle 16ti bitový (2 B) s adresací paměťového prostoru do 64 kB (adresa hexadecimálně 0x0000 až 0xFFFF)

3 Pokud je fyzický paměťový prostor větší, používá se segmentace – velký pamě- ťový prostor je rozdělen na segmenty (stránky) o veli- kosti 64 kB a ukazatel definuje adresu na dané stránce, tzv. blízký ukazatel, nebo je použit tzv. vzdálený ukazatel, který obsahuje i identifikaci příslušné pamě- ťové stránky a adresu (off- set) v rámci dané stránky Ukazatel (2/10)

4 U 32 bitových systémů se používá 32 bitový ukazatel, tj. 4 B a adresy v hexadecimálním rozsahu 0x do 0xFFFFFFFF, celkem 4 GB U 64 bitových systémů se používá 64 bitový ukazatel, tj. 8 B, celkem 16 HB (hexabytů) Pozn. 1 kB = 2 10 B = 1024 B 1 MB = 2 20 B = 1024 kB = B 1 GB = 2 30 B = 1024 MB, 1 TB = 2 40 B = 1024 GB 1 PB = 2 50 B = 1024 TB, 1 HB = 2 60 B = 1024 HB, atd. Ukazatel (3/10)

5 Ukazatelová aritmetika (Pointer aritmetics) zahrnuje výpočetní operace nad ukazateli. Adresovatelnou jednotkou může být 1 byte, 1 slovo (2 B), v jazyce C velikost datového typu (char = 1B, int = 4B, …), jenž ukazatel adresuje. int *a, *b; //pointers to integer int x; int y[5] = {1, 2, 3, 4, 5}; a = &x; //pointer a contents address of variable x *a = y[2]; //fill address defined by a by y[2], x=y[2] printf("%d\n", x); b = &(y[3]); //pointer b contents address of var. y[3] *b = *a; //content of address pointed by a is copied to content of address pointed by b printf("%d\n", y[3]); Příklad: KPC1E_Ex42.c Ukazatel (4/10)

6 Prvky jednorozměrného pole jsou v paměti řazeny za sebou, indexovat (ukázat na x -tý prvek) pole lze pomocí ukazatelů. int *adr; //pointer to integer int arr[50], i; adr = &(arr[49]);//pointer is set to the last element for(i=0; i<50; i++) { *adr = i;//a number is paste to the address //defined by pointer adr adr--;//pointer is shifted down (-1 element //of arr = -4 bytes due to int type } for(i=0; i<50; i++) printf("%d\n", arr[i]); Příklad: KPC1E_Ex43.c Ukazatel (5/10)

7 Jméno pole bez indexu je ukazatelem na první prvek pole: zápis A[0] je ekvivalentní *A zápis A[5] je ekvivalentní *(A+5) int *adr; //pointer to integer int arr[50], i; adr = arr;//pointer is set to the first element for(i=0; i<50; i++) { *adr = i;//a number is paste to the address //defined by pointer adr adr++;//pointer is shifted up (+1 element //of arr = +4 bytes due to int type } for(i=0; i<50; i++) printf("%d\n", arr[i]); Příklad: KPC1E_Ex44.c Ukazatel (6/10)

8 Př. Aplikace relačních operátorů na ukazatele int *a, *b, *c; // pointers to integer int arr[20], i; a = arr; for(i=0; i<20; i++) {*a = i; a++;} for(i=0; i<20; i++) printf("%3d", arr[i]); b = arr+5; c = arr+15; a = arr; for(i=0; i<20; i++) { if (b a) //address a must be between b and c *a=0; a++; } for(i=0; i<20; i++) printf("%3d", arr[i]); Příklad: KPC1E_Ex45.c Ukazatel (7/10)

9 Př. Integer v paměti po bytech int *a; //pointer to int char *b; //pointer to char int arr[5], i; for(i=0; i<5; i++) arr[i] = i; a=arr; for(i=0; i<5; i++) //int address and value displaying { printf("%x %3d\n", a, *a); a++; } b=arr; for(i=0; i<20; i++) //char (byte) addr. and value disp. { printf("%x %3d\n", b, *b); b++; } Příklad: KPC1E_Ex46.c Ukazatel (8/10)

10 Př. Float v paměti po bytech unsigned char *a; //pointer to uchar float num = 1.2; //float value in memory int i; a=# for(i=0; i<4; i++) //four bytes of float value in mem. { printf("%x ", a);//address printf("%x\n", *a);//content a++; } Příklad: KPC1E_Ex47.c Pro hodnotu 1,2 uloženou jako typ float je v paměti uloženo (hexa) 9A F, uspořádání je od nejméně významného bytu pro nejvíce významný Ukazatel (9/10)

11 1,2 ve float rozlišení má tedy tvar hexa: 0x 3 F A binárně: 0b znaménko: 0 = + exponent: 0b = 127 mantisa: 0b = Ukazatel (10/10)

12 int *a; //pointer to int int arr[4][5], i, j; for(i=0; i<4; i++) { for(j=0; j<5; j++) { arr[i][j]= 10*i+j;v printf("%3d", arr[i][j]); } printf("\n"); } a=arr; for(i=0; i<20; i++, a++) //20 elements of array in mem printf("%x %3d\n", a, *a); //printing Příklad: KPC1E_Ex48.c Dvourozměrné pole v paměti Pole a ukazatel (1/3)

13 Vícerozměrné pole v paměti int *a; //pointer to int int arr[3][3][3], i, j, k; for(i=0; i<3; i++) for(j=0; j<3; j++) for(k=0; k<3; k++) arr[i][j][k] = 100*i + 10*j + k; for(i=0; i<27; i++, a++) //27 elements of array 3x3x3 printf("%x %3d\n", a, *a); //in memory printing Příklad: KPC1E_Ex49.c Pole a ukazatel (2/3)

14 Vícerozměrné pole a ukládání jeho prvků v paměti: Ekvivalentní zápis: arr[i][j][k] = *(arr+i*3*3+j*3+k) Pole a ukazatel (3/3)

15 Pole ukazatelů (1/2) Př. Aplikace pole ukazatelů – vyhledání pozic znaků v textu char text[] = "okolo kola okolkovala koala"; char *o[10], *c; //o is array of pointers int i=0, j; printf("Original string: %s\n\n", text); printf("Addr. of the beginning of text: %x\n\n", text); o[i] = strchr(text, 'o'); while(o[i]) { c = o[i]+1; i++; o[i] = strchr(c, 'o'); //save addres of ’o’ to //array of pointers }

16 Pole ukazatelů (2/2) printf("Addresses of the character o:\n"); for(j=0; j

17 Ukazatele - příklady (1/7) Př. Záměna znaků pomocí ukazatele char text[]="okolo kola okolkovala koala"; char *a; printf("Original string: %s\n\n", text); a=text; while(*a!=NULL) { if(*a=='o') *a='k'; else if(*a=='k') *a='o'; a++; } printf("Changed string: %s\n", text); Příklad: KPC1E_Ex51.c

18 Ukazatele - příklady (2/7) Př. Vyhledání a náhrada textu bez std. funkcí pomocí ukazatelů char text[]="sokol kolem jezdil kolem dokola"; char test[]="kol"; char ntext[]=" "; char *a, *b, *c; int tst; a=text; b=test; printf("Original string: %s\n\n", text); for(a=text; *a!=NULL; a++) { tst=1; c=a; for(b=test; *b!=NULL; b++,c++) if (*c!=*b) tst=0;

19 Ukazatele - příklady (3/7) if(tst) { c=ntext; for(b=test; *b!=NULL; b++, c++, a++) { *a=*c; } printf("Changed string: %s\n", text); Příklad: KPC1E_Ex52.c

20 Ukazatele - příklady (4/7) Př. V řetězcové proměnné wtxt a btxt ve jsou uloženy zhuštěně pozice figurek bílého, resp. černého, na šachovnici se 64 políčky (8x8) ve formě písmeno řádku (A až H) a číslo sloupce (1 až 8). Doplňte program, který postupně projde texty ve wtxt a btxt a do pole field vloží na příslušná místa znaky 'W' a 'B' označující figurku příslušného hráče a situaci vytiskněte do konzolového okna. Procházení řetězci i polem řešte pomocí ukazatelů. #include int main() { char wtxt[]="A6B8A4D7E2C3F1F2"; char btxt[]="C3A7B1D1E4E5F5H3H5"; char field[64]; char *p, *t, i, j;

21 Ukazatele - příklady (5/7) p=field; for(i=0, p=field; i<64; i++, p++) *p= ' '; p=wtxt; do { t=field+8*(*p-'A'); p++; t+=(*p-'1'); *t='W'; p++; } while(*p!='\0');

22 Ukazatele - příklady (6/7) p=btxt; do { t=field+8*(*p-'A'); p++; t+=(*p- '1' ); *t='B'; p++; } while(*p!='\0'); printf("\n |"); for(i='1'; i<='8'; i++) printf("%c|", i); printf("\n -"); for(i='1'; i<='8'; i++) printf("--");

23 Ukazatele - příklady (7/7) for(i='A', p=field; i<='H'; i++) { printf("\n%c |", i); for(j='1'; j<='8'; j++, p++) printf("%c|", *p); } return 0; } Výstup na obrazovce: Příklad: KPC1E_Ex53.c

24 Funkce – úvod (1/3) Funkce: posloupnost příkazů uvedená hlavičkou Využití: – opakovaně volaná sekvence = jeden kód pro danou část vykonávaného algoritmu, ušetří se programová paměť – strukturování programu = funkce pro danou skupinu úloh (algoritmů) jsou zapouzdřeny ve společné knihovně (nezávislý soubor), volání dané funkce se provádí jen předáváním parametrů v hlavičce – např. y=cos(x), zdrojový soubor pro vykonání kosinu je skrytý v knihovním souboru – ošetření událostí = v případě vzniku události na základě přerušení (aktivační signál) se zavolá příslušná funkce, např. pohyb myší zavolá funkci, která přepočítá novou pozici kurzoru

25 Co se děje při volání funkce: Funkce – úvod (2/3)

26 Základní dělení funkcí: - funkce bez parametru - funkce s parametrem - volané parametrem – nezmění obsah vstupních pro- měnných, ty jsou kopírovány do nových proměnných alokovaných během provádění funkce - volané odkazem – mohou měnit obsah vstupních proměnných, předává se adresa proměnné, proto ji lze kdykoli během vykonávání funkce změnit) -funkce s/bez návratové hodnoty – pokud potřebujeme vrátit více než jednu hodnotu (výstup), musíme místa pro uložení výstupů definovat jako volání odkazem Funkce – úvod (3/3)

27 Hlavičky funkcí (1/13) void func_name(void) { } void warning(void) // no input, no output { printf("Your computer is being destroyed"); getchar(); } void main(void) { warning(); // calling the function } Funkce bez parametru a bez návratové hodnoty:

28 double func_name(double A) { } int pow3(int A) // 1 input, 1 output { int y = A*A*A; return y; } Funkce s jedním parametrem volaným hodnotou a s návratovou hodnotou: void main(void) { int n; for(n=0; n<20; n++) printf("%d^3 is %d\n", n, pow3(n)); } Hlavičky funkcí (2/13)

29 double func_name(double A, double B) { } float pow_n(float A, int B) // 2 inputs, 1 output { float y=1; int n; for(n=0; n<=B; n++) if(n>0) y*=A; return y; } Funkce se dvěma parametry volanými hodnotou a s návratovou hodnotou: Funkce pro n-tou mocninu racionálního čísla Hlavičky funkcí (3/13)

30 int main(void) { int n; float y[9]; float m = 5.123; for(n=2; n<11; n++) { y[n-2] = pow_n(m, n); printf("%dth power of %f is %f\n", n, m,y[n-2]); } getchar(); return 0; } Příklad: KPC1E_Ex54.c Hlavičky funkcí (4/13)

31 ??? func_name(char* A) { } int numinstr(char *s) { int n, cnt=0; for(n=0; s[n]!='\0'; n++) if(s[n]>='0‘ && s[n]<='9') cnt++; return cnt; } Funkce s parametrem typu řetězec Funkce pro nalezení počtu znaků číslic v řetězci Hlavičky funkcí (5/13)

32 int main(void) { char txt1[]="ab9bj65D9"; char txt2[]="34x9z56A0"; char txt3[]="3cvz1111E"; int n1, n2, n3; n1=numinstr(txt1); n2=numinstr(txt2); n3=numinstr(txt3); printf("%d in 1st, %d in 2nd, %d in 3rd", n1, n2, n3); getchar(); return 0; } Příklad: KPC1E_Ex55.c Hlavičky funkcí (6/13)

33 ??? func_name(int *A, int *B) { } void polar2cart(float *A, float *B) // A is magnitude {// B is phase in deg. float pha; pha=3.1415**B/180; *B=*A*sin(pha); // B is imag. part *A=*A*cos(pha);// A is real part } Funkce s parametry volanými odkazem Parametry jsou ukazatele odkazující na pozice proměnných v paměti Funkce pro převod z polárních do kartézských souřadnic Hlavičky funkcí (7/13)

34 int main(void) { float x=2.0; float y=90.0; printf("Magnitude is %f and phase is %f deg.", x, y); polar2cart(&x, &y); printf("Real part is %f and imag. part is %f", x, y); getchar(); return 0; } Příklad: KPC1E_Ex56.c Hlavičky funkcí (8/13)

35 float mean(float *vect, int n) // vect is input vector { // n is length of the vector int m; float s=0; // s is partial sum for(m=0; m

36 int main(void) { float x[5], m; int len_x=5, n; srand(time(NULL)); for(n=0; n

37 typedef int t_mat[3][3]; void func_name(t_mat A, t_mat B) { } Definice proměnn é vlastn í ho typu pomoc í typedef int func_name(t_mat A) { } t_mat func_name(t_mat A) { } ! Funkce může vracet pouze hodnotu (ne pole) Hlavičky funkcí (11/13)

38 typedef int t_mat[3][3]; int det_mat(t_mat x)// determinant of 3x3 matrix { int det=0, m, n, pplus, pminus; for(m=0; m<3; m++) { pplus=1; pminus=1; for(n=0; n<3; n++) { pplus*=x[(m+n)%3][n]; pminus*=x[(m+n)%3][2-n]; } det+=pplus-pminus; } return det; } Funkce pro výpočet determinantu matice 3x3 Hlavičky funkcí (12/13)

39 int main(void) { t_mat mat; int m, n; srand(time(NULL)); for(m=0; m<3; m++)//random matrix for(n=0; n<3; n++) mat[m][n]=rand()%198-99; //from -99 to +99 printf("The determinant is %d", det_mat(mat)); getchar(); return 0; } Příklad: KPC1E_Ex58.c Hlavičky funkcí (13/13)

40 Rekurze funkcí (1/1) unsigned int factorial(unsigned int n) { if(n) // test if n is not zero return n*factorial(n-1); // n is not zero else // n is zero return 1; } int func_name(int A) { … x=func_name(y); … } Funkce může v jejím těle volat sebe samu – rekurzivní funkce Příklad: KPC1E_Ex59.c Funkce pro výpočet faktori á lu

41 my_lib.c: soubor obsahující zdrojové kódy našich funkcí my_lib.h: soubor obsahuj í c í hlavičky našich funkc í ze stejnojmenného souboru, v hlavičce jsou definovány typy proměnných a jméno funkce, jednotlivé hlavičky musí být odděleny středníkem pomocí direktivy #include "my_lib.h" vložené na začátek programu aktivuji přístup k funkcím z příslušného knihovního souboru my_lib.c, linker přidá knihovnu k projektu Ze souboru vlastních funkcí lze vytvořit knihovnu: Knihovny funkcí (1/10)

42 Postup v Code::Blocks: File > New > File my_lib.c + my_lib.h do adresáře projektu nebo do vlast- ního adresáře s vlastními knihovnami Knihovny funkcí (2/10)

43 Nastavení cest pro kompilátor v Code::Blocks: Settings > Compiler přidat cesty se zdrojovými soubory a hlavičkami knihoven tak, aby se přeložili i zdrojové kódy vlastních knihovních funkcí Knihovny funkcí (3/10)

44 Knihovny funkcí (4/10) Př. Vlastní knihovna funkcí pro práci s maticemi 3x3 hlavičkový soubor matops.h typedef int t_mat [3][3]; int det_mat(t_mat A);// determinant of A void print_mat(t_mat A);// printing A void gen_mat(t_mat A, int start, int stop); // gener. A void copy_mat(t_mat A, t_mat B); // copying A to B void add_mat(t_mat A, t_mat B);// A=A+B void sub_mat(t_mat A, t_mat B);// A=A-B void clr_mat(t_mat A);// zeroing A definice vlastních typů proměnných definice hlaviček funkcí s typy vstupních i výstupních parametrů

45 zdrojový soubor knihovny matops.c #include typedef int t_mat[3][3]; int det_mat(t_mat A)// compute determinant { int det=0, m, n, pplus, pminus; for(m=0; m<3; m++) { zdrojov é k ó dy jednotlivých funkc í podle hlavičkov é ho souboru matops.h Knihovny funkcí (5/10)

46 pplus=1; pminus=1; for (n=0; n<3; n++) { pplus*=A[(m+n)%3][n]; pminus*=A[(m+n)%3][2-n]; } det+=pplus-pminus; } return det; } Knihovny funkcí (6/10)

47 void print_mat(t_mat A)// printing matrix A {int m,n; for(m=0; m<3; m++) {for(n=0; n<3; n++) { printf("%4d ", A[m][n]); } printf("\n"); } void gen_mat(t_mat A, int start, int stop) // random {int m, n;// generation of matrix A srand(time(NULL)); for(m=0; m<3; m++) for(n=0; n<3; n++) A[m][n]=rand()%(stop-start+1)+start; } Knihovny funkcí (4/10)

48 void copy_mat(t_mat A, t_mat B) // copying A to B { int m, n; for(m=0; m<3; m++) for(n=0; n<3; n++) A[m][n]=B[m][n]; } void add_mat(t_mat A, t_mat B) // A=A+B { int m, n; for(m=0; m<3; m++) for(n=0; n<3; n++) A[m][n]+=B[m][n]; } Knihovny funkcí (4/10)

49 void sub_mat(t_mat A, t_mat B)// A=A-B { int m, n; for(m=0; m<3; m++) for(n=0; n<3; n++) A[m][n]-=B[m][n]; } void clr_mat(t_mat A)// zeroizing A { int m,n; for(m=0; m<3; m++) for(n=0; n<3; n++) A[m][n]=0; } Knihovny funkcí (4/10)

50 #include #include "matops.h" int main(void) { t_mat mat1, mat2, mat3; // this type was defined //in mathops.h int m, n; gen_mat(mat1, -9, 9); print_mat(mat1); printf("The det. of mat1 is %d\n",det_mat(mat1)); copy_mat(mat3, mat1); sub_mat(mat1, mat2); … Př. Program, který využ í v á na š i knihovnu matops.h Příklad: KPC1E_Ex60.c + matops.c(h) Knihovny funkcí (4/10)

51 Funkce - příklady (1/2) Př. Vytvořte knihovnu funkcí pro vý- počet plochy 2-D geometrických objektů (funkce sestavte pro obdélníka, elipsu a trojúhelník). double s_rect(double a, double b); double s_ell (double a, double b); double s_tri (double a, double b); Hlavičkový soubor knihovny areas2D.h

52 #include "areas2D.h" double s_rect(double a, double b) { return a*b;} double s_ell (double a, double b) { return *a*b;} double s_tri (double a, double b) { return 0.5*a*b;} Knihovní funkce areas2D.cpp Příklad: KPC1E_Ex61.c + areas2D.c(h) Funkce - příklady (2/2)

53 Preprocesor (1/13) Úkolem preprocesoru je: odstranit komentáře ze zdrojo- vého kódu vložit soubory, které mají být kompilovány odstranit části kódu určeného direktivami #if rozvinout předdefinovaná makra Proces generování spustitelného kódu

54 Činnost preprocesoru lze řídit direktivami: - začínají vždy znakem # Vložení jiného souboru do souboru – direktiva #include #include nový_řádek – pro vložen í standardn í ho hlavičkov é ho souboru (mus í být v adres á ři pro standardn í hlavičkov é soubory) př. #include #include "jméno souboru" nový_řádek – pro vložen í vlastn í ho zdrojov é ho (hlavičkov é ho) souboru (mus í být v adres á ři projektu nebo lze specifikovat i s cestou) př. #include "my_lib.h" Preprocesor (2/13)

55 #include MAKRO nový_řádek – pro vložen í (rozvinut í ) MAKRA specifikovan é ho dř í ve uvedenou direktivou #define (viz d á le) (nesm í obsahovat " ) př. #include my_macro #define identifikátor řetězec nový_řádek – makro bez parametrů př. #define PI za všechna PI nahrad í ve zdrojov é m textu Definice maker – direktiva #define Makro (makroinstrukce) nahrazuje posloupnost znaků posloup- nost í nahrazuj í c í ch znaků Preprocesor (3/13)

56 #define identifikátor(seznam_parametrů) řetězec nový_řádek – makro s parametry př. #define ABS(re,im) sqrt(((re)*(re))+((im)*(im))) Každý výskyt identifik á toru je nahrazen řetězcem, to neplat í v ko- ment á ř í ch, řetězc í ch mezi " " a mezi v direktivě #include Nen í -li řetězec uveden, identifik á tor je preprocesorem ze zdrojo- v é ho textu odstraněn Vkl á d á n í z á vorek je důležit é pro specifikaci priority oper á torů: Pokud bude makro #define ABS(re,im) sqrt(re*re+im*im) a ve zdrojovém kódu c=ABS(a+1,b-1) pak po nahrazen í preprocesorem bude c=sqrt(a+1*a+1+b-1*b-1) po zjednodušen í výrazu c=sqrt(2*a) Preprocesor (4/13)

57 #include #define PI #define ABS(re,im) sqrt(((re)*(re))+((im)*(im))) int main() { float r=12, ar=1.6, ai=2.2; printf("Circle area is %f\n", PI*r*r); printf("Absolute value of %f + j*%f is %f\n", ar, ai, ABS(ar,ai)); return 0; } Příklad: KPC1E_Ex62.c Př. Makro pro absolutní hodnotu komplexního čísla Preprocesor (5/13)

58 #include #define ROOT1(a,b,c) (-(b)+sqrt((b)*(b)-4*(a)*(c)))/(2*(a)) #define ROOT2(a,b,c) (-(b)-sqrt((b)*(b)-4*(a)*(c)))/(2*(a)) int main() { float fa=1.3, fb=5.6, fc=1.2; int ia=1, ib=5, ic=2; printf("Roots for %3.1fx^2+%3.1fx+%3.1f=0 are %5.3f and %5.3f\n", fa, fb, fc, ROOT1(fa, fb, fc),ROOT2(fa, fb, fc)); printf("Roots for %dx^2+%dx+%d=0 are %5.3f and %5.3f\n", ia, ib, ic, ROOT1(ia, ib, ic), ROOT2(ia, ib, ic)); return 0; } Příklad: KPC1E_Ex63.c Parametry v makru mohou reprezentovat různé datové typy – makro je univerzáln í (v příkladu float a int ) Preprocesor (6/13)

59 Nevhodné použití makra #include #define POW3(A) ((A)*(A)*(A)) int main() { int x = 10; printf("%d^3 = %d\n", x, POW3(x)); printf("%d\n", POW3(++x)); return 0; } Příklad: KPC1E_Ex64.c V prvním použití makra POW3 je vše v pořádku, při druhém použití makra POW3 bude rozvoj následující: ((++x)*(++x)*(++x)), výsledek bude 12*12*13 = 1872 proč? Preprocesor (7/13)

60 Operátory # a ## v makrech Operátory # a ## se používají v makrech s parametry. Za operátor # se dosad í řetězec, který je stejný jako parametr makra. Operátor ## spojí své dva parametry v jeden řetězec. #include #define SUM(A,B) printf("%s = %d\n",#A " + " #B,(A)+(B)) #define JOINT(A,B) A ## B int main() { int n1=10, n2=20; SUM(5,6); SUM(JOINT(n,1),JOINT(n,2)); return 0; } Příklad: KPC1E_Ex65.c Preprocesor (8/13)

61 Standardn í makra (ANSI C) __TIME__ - aktuální čas spuštění preprocesoru (vrací řetězec) __DATE__ - aktuální datum spuštění preproc. (vrací řetězec) __FILE__ - jméno souboru zpracovávaného preprocesorem __LINE__ - číslo aktuálního řádku (vrací int ) __STDC__ - definuje, zda překladač splňuje normu ANSI (vrací int – 1 splňuje / 0 nesplňuje) #include int main() { printf("%s\n", __TIME__); printf("%s\n", __DATE__); printf("%s\n", __FILE__); printf("%d\n", __LINE__); printf("%d\n", __STDC__); return 0; } Př í klad: KPC1E_Ex66.c Preprocesor (9/13)

62 #undef identifikátor – od daného místa se ruší platnost makra př. #define PI … #undef PI … // PI se už dále nenahrazuje #define PI 3.14 …// PI se zde nahrazuje za 3.14 Rušení platnosti maker – direktiva #undef Preprocesor (10/13)

63 #if podmínka_A zdrojový kód pro splněnou podmínku_A #elif podmínka_B zdrojový kód pro splněnou podmínku_B (nesplněna podmínka_A ) #elif podmínka_C zdrojový kód pro splněnou podmínku_C (nesplněna A i B ) #else zdrojový kód pro stav, kdy žádná z předchozích podmínek nebyla splněna #endif Podmíněný překlad – direktivy #if, #endif, #elif, #else V podmínkách musí být výrazy, které může vyhodnotit preproce- sor (nelze používat hodnoty proměnných atd.). Preprocesor (11/13)

64 Podmíněný překlad lze využít při různých úrovních ladění #include #define DEBUGING 2 int main() { int a = 10; #if DEBUGING==1 a++; #elif DEBUGING==2 a=a*a*a; #else a=0; #endif printf("%d\n", a); return 0; } Příklad: KPC1E_Ex67.c Preprocesor (12/13)

65 Pomocí #if defined lze vyhodnocovat, zda již existuje určité makro (bylo-li definováno), zkráceně #ifdef. Pomocí #if !defined lze vyhodnocovat, zda neexistuje určité makro (nebylo-li definováno), zkráceně #ifndef. Podmíněný překlad – direktivy #ifdef, #ifndef Nejčastěji se používá pro ošetření násobné definice: #ifndef PI #define PI #endif #ifdef PI c=2*PI*r; #endif Preprocesor (13/13)

66 Trigonometrické funkce (úhly vždy v Radiánech): double sin(double x); double cos(double x); double tan(double x); double asin(double x); double acos(double x); double atan(double x); double atan2(double y, double x); Knihovna matematických funkcí math.h ANSI-C knihovny (1/6) double sinh(double x); double cosh(double x); double tanh(double x); printf("%f", 180/3.1415*atan2(sqrt(3)/3,1))

67 Exponenciální, logaritmické a mocninné funkce: double exp(double x); double log(double x); double log10(double x); double pow(double x, double y); //x^y double sqrt(double x); ANSI-C knihovny (2/6) Ořezávání a další pomocné funkce (viz př.): double ceil(double x); double floor(double x); double fabs(double x); double ldexp(double x, int n); double frexp(double x, int* exp); double modf(double x, double* ip); double fmod(double x, double y);

68 Př. #include int main() { double a=-1.11, b=2.21, i, f; int c=2, e; printf("atan2(%.2f,%.2f)=arctg(%.2f/%.2f)=%.2f\n\n", a, b, a, b, atan2(a,b)); printf("exp(%.2f)=e^%.2f=%.2f\n\n", a, a, exp(a)); printf("log(%.2f)=ln(%.2f)=%.2f\n\n", b, b, log(b)); printf("log10(%.2f)=%.2f\n\n", b, log10(b)); printf("fabs(%.2f)=%.2f\n\n", a, fabs(a)); printf("ceil(%.2f)=%.2f\n\n", a, ceil(a)); printf("floor(%.2f)=%.2f\n\n", a, floor(a)); ANSI-C knihovny (3/6)

69 printf("ldexp(%.2f, %d)=%.2f*2^%d=%.2f\n\n", a, c, a, c, ldexp(a,c)); printf("f=frexp(%.2f, &e): ", b); f=frexp(b, &e); printf("f=mantissa=%.4f; e=exponent=%d, ", f, e); printf("i.e. x=mantissa*2^exponent=%.4f*2^%d= %.2f\n\n", f, e, f*pow(2,e)); printf("f=modf(%.2f, &i): ", a); f=modf(a, &i); printf("f=fractional_part=%.2f;i=integral_part=%.2f\ n\n", f, i); printf("fmod(%.2f,%.2f)=remainder(%.2f/%.2f)=%.2f\n\ n", b, a, b, a, fmod(b,a)); return 0; } Příklad: KPC1E_Ex68.c ANSI-C knihovny (4/6)

70 Další knihovny assert.h – makro assert pro účely ladění ctype.h – funkce pro testování znaků, do jaké skupiny patří, např. islapha(char x) vrátí 1 (true) pokud je znak x z rozsahu 'A' až 'Z' nebo 'a' až 'z' errno.h – makra a proměnná errno pro definici chyby float.h – předdefinované konstanty pro maxima a minima hodnot racionálních typů limits.h – předdefinované konstanty pro maxima a minima hodnot celočíselných typů locale.h – nastavení a čtení národního nastavení, např. des. tečka/čárka apod. setjmp.h – funkce pro nastavení parametrů volání u funkcí ANSI-C knihovny (5/6)

71 signal.h – makra a funkce pro reporty signálů vznikajících během výkonu programu stdarg.h – makra pro práci s argumenty stddef.h – standardní definice (např. NULL ) stdio.h – funkce pro vstupy a výstupy stdlib.h – různé základní funkce, např. konverze z řetězců na číselné hodnoty a naopak string.h – funkce pro práci s řetězci time.h – funkce pro práci s časem ANSI-C knihovny (6/6)

72 Téma následujícího tutoriálu DĚKUJI ZA POZORNOST – Struktury – Unie – Výčtový typ – Dynamické proměnné – Programování se soubory – Záloha databáze v souboru – Algoritmy


Stáhnout ppt "OSNOVA: a) Ukazateleb) Pole a ukazatel c) Pole ukazatelůd) Ukazatele - příklady e) Funkce – úvodf) Hlavičky funkcí g) Rekurze funkcíh) Knihovny funkcí."

Podobné prezentace


Reklamy Google