Mutatók. Programozás II. Hatwágner F. Miklós március 4. Széchenyi István Egyetem, Gy r

Hasonló dokumentumok
Függvények. Programozás I. Hatwágner F. Miklós november 16. Széchenyi István Egyetem, Gy r

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós április 4. Széchenyi István Egyetem, Gy r

Programozás 6. Dr. Iványi Péter

A C programozási nyelv V. Struktúra Dinamikus memóriakezelés

Programozás C nyelven FELÜLNÉZETBŐL elhullatott MORZSÁK. Sapientia EMTE

A C programozási nyelv III. Pointerek és tömbök.

Járműfedélzeti rendszerek II. 3. előadás Dr. Bécsi Tamás

A C programozási nyelv III. Pointerek és tömbök.

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós május 6. Széchenyi István Egyetem, Gy r

A C programozási nyelv I. Bevezetés

Miről lesz ma szó? A PROGAMOZÁS ALAPJAI 1. Dinamikus változók. Dinamikus változók. Dinamikus változók. Dinamikus változók. 7.

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós október 11. Széchenyi István Egyetem, Gy r

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós március 3. Széchenyi István Egyetem, Gy r

A C programozási nyelv I. Bevezetés

Programozás alapjai C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

Függvény pointer. Feladat: Egy tömbben soroljunk fel függvényeket, és hívjuk meg valahányszor.

Szövegek C++ -ban, a string osztály

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós augusztus 29. Széchenyi István Egyetem, Gy r

C programozási nyelv Pointerek, tömbök, pointer aritmetika

Programozás alapjai C nyelv 7. gyakorlat. Függvények. Függvények(2)

Függvények. Programozás alapjai C nyelv 7. gyakorlat. LNKO függvény. Függvények(2) LNKO függvény (2) LNKO függvény (3)

Mutatók és címek (ism.) Programozás alapjai C nyelv 8. gyakorlat. Indirekció (ism) Néhány dolog érthetőbb (ism.) Változók a memóriában

A C programozási nyelv VI. Parancssori argumentumok File kezelés

Mérnöki programozás 7. Szerkesztette: dr. Vass Péter Tamás

Programozás II. 4. Dr. Iványi Péter

1. Alapok. Programozás II

C programozás. 6 óra Függvények, függvényszerű makrók, globális és

Programozas 1. Strukturak, mutatok

Programozás alapjai C nyelv 10. gyakorlat. Standard függvények. Union

main int main(int argc, char* argv[]) { return 0; } main return 0; (int argc, char* argv[]) main int int int main main main

Tartalom Keresés és rendezés. Vektoralgoritmusok. 1. fejezet. Keresés adatvektorban. A programozás alapjai I.

Programozás 5. Dr. Iványi Péter

Programozás I gyakorlat. 10. Stringek, mutatók

Objektumok tulajdonságai

Keresés és rendezés. A programozás alapjai I. Hálózati Rendszerek és Szolgáltatások Tanszék Farkas Balázs, Fiala Péter, Vitéz András, Zsóka Zoltán

Információs Technológia

Programozás I. 5. Előadás: Függvények

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós március 31. Széchenyi István Egyetem, Gy r

Pénzügyi algoritmusok

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Függvények. Dr. Bécsi Tamás 6. Előadás

Programozás alapjai C nyelv 5. gyakorlat. Írjunk ki fordítva! Írjunk ki fordítva! (3)

C memóriakezelés. Mutató típusú változót egy típus és a változó neve elé írt csillag karakterrel hozhatjuk létre.

Mutatók és mutató-aritmetika C-ben március 19.

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós szeptember 27. Széchenyi István Egyetem, Gy r

10. gyakorlat. Pointerek Tárolási osztályok

1.1. A forrásprogramok felépítése Nevek és kulcsszavak Alapvető típusok. C programozás 3

/* Az iter függvény meghívása és a visszatérő érték átadása a gyok változóba */ gyok = iter( n, a, e ) ;

A verem (stack) A verem egy olyan struktúra, aminek a tetejéről kivehetünk egy (vagy sorban több) elemet. A verem felhasználása

Típusok és konstansok

Kivételkezelés a C++ nyelvben Bevezetés

Programozás alapjai 9.Gy: Struktúra 2.

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Mutatók. Dr. Bécsi Tamás 7. Előadás

Programozás C nyelven (10a. ELŐADÁS) Sapientia EMTE

Programozás alapjai C nyelv 4. gyakorlat. Mit tudunk már? Feltételes operátor (?:) Típus fogalma char, int, float, double

OOP #14 (referencia-elv)

Java II. I A Java programozási nyelv alapelemei

A C programozási nyelv II. Utasítások. A függvény.

Bevezetés a C++ programozási nyelvbe

Bevezetés a C programozási nyelvbe. Az Általános Informatikai Tanszék C nyelvi kódolási szabványa

Struktúrák (struct) A struktúra szerkezetét meghatározó deklaráció általános formája:

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós október 15. Széchenyi István Egyetem, Gy r

6. gyakorlat Egydimenziós numerikus tömbök kezelése, tömbi algoritmusok

M veletek és kifejezések

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

Programozás alapjai gyakorlat. 4. gyakorlat Konstansok, tömbök, stringek

11. gyakorlat Sturktúrák használata. 1. Definiáljon dátum típust. Olvasson be két dátumot, és határozza meg melyik a régebbi.

Programozás C nyelven (9. ELŐADÁS) Sapientia EMTE

Java II. I A Java programozási nyelv alapelemei

7/8. gyakorlat Karaktertömbök és sztringkezelés

Programozás I gyakorlat

10. gyakorlat Tömb, mint függvény argumentum

Programozás II. 2. Dr. Iványi Péter

Programozás C nyelven (10. ELŐADÁS) Sapientia EMTE

Informatika terméktervezőknek

Programozási Nyelvek: C++

A PROGAMOZÁS ALAPJAI 1. Függvény mint függvény paramétere. Függvény mint függvény paramétere. Függvény mint függvény paramétere

Programozás alapjai 1. (BMEVIEEA100)

Mit tudunk már? Programozás alapjai C nyelv 4. gyakorlat. Legnagyobb elem keresése. Feltételes operátor (?:) Legnagyobb elem keresése (3)

A helyi információ és az id kezelése

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

értékel függvény: rátermettségi függvény (tness function)

Algoritmizálás + kódolás C++ nyelven és Pascalban

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós február 18. Széchenyi István Egyetem, Gy r

Apple Swift kurzus 3. gyakorlat

Információs Technológia

Megoldott programozási feladatok standard C-ben

Programozás C és C++ -ban

Kivételek, kivételkezelés a C++ nyelvben

Alprogramok, paraméterátadás

8. gyakorlat Pointerek, dinamikus memóriakezelés

tétel: különböző típusú adatokat csoportosít, ezeket egyetlen adatként kezeli, de hozzáférhetünk az elemeihez is

Programozás alapjai 8.Gy: Program struktúra

Programozás alapjai. 5. előadás

5. Gyakorlat. struct diak {

PHP alapjai, bevezetés. Vincze Dávid Miskolci Egyetem, IIT

Országzászlók (2015. május 27., Sz14)

Programozás alapjai gyakorlat. 2. gyakorlat C alapok

Adatszerkezetek és algoritmusok

Programozási nyelvek Java

Átírás:

Mutatók Programozás II. Széchenyi István Egyetem, Gy r 2014. március 4.

Dinamikus memóriakezelés A C fordító a memóriát három részre osztja: 1 els dleges adatterület konstansok, statikus objektumok 2 verem (stack) lokális objektumok, függvények paraméterei 3 heap dinamikusan, futásid ben foglalt, változó méret memóriablokkok Memóriakezel fv.-ekhez beszerkesztend : stdlib.h void* calloc(size_t darab, size_t meret) darab*meret bájt méret blokk lefoglalása és nullázása void* malloc(size_t meret) meret bájt méret blokk lefoglalása Tulajdonságok: V. t. érték: lefoglalt terület címe, vagy NULL, ha sikertelen volt a m velet Automatikus tárillesztés, méret illesztés bármilyen objektum elhelyezhet

Dinamikus memóriakezelés void* realloc(void* blokk, size_t uj_meret) Átméretezi a korábban lefoglalt blokk -ot. V. t. sikeres esetben az átméretezett terület címe (egyezhet a régi értékkel). A régi blokk tartalmát igyekszik meg rizni. Sikertelen esetben a v. t. érték NULL, de adat nem vész el. void free(void* blokk) Korábban lefoglalt blokk felszabadítása. NULL átadása esetén azonnal visszatér, de érvénytelen mutató átadása végzetes hibát okozhat!

Dinamikus memóriakezelés Egydimenziós tömb (vektor) használata #include <stdio.h> #define MERET 3 int main(void) { int tomb[meret] = {1, 2, 3}; int i; printf("'tomb' elemei: \n"); for(i=0; i<meret; i++) { printf("%d ", tomb[i]); } putchar('\n'); } Kimenet 'tomb' elemei: 1 2 3

Dinamikus memóriakezelés Dinamikus, egydimenziós tömb #include <stdio.h> #include <stdlib.h> #define MERET 3 int main(void) { int *dintomb, i; if((dintomb = (int*)malloc(meret*sizeof(int)))) { *dintomb = 1; *(dintomb+1) = 2; dintomb[2] = 3; printf("'dintomb' elemei: \n"); for(i=0; i<meret; i++) printf("%d ", *(dintomb+i)); putchar('\n'); free(dintomb); } else { fprintf(stderr, "Nem sikerült memóriát foglalni " "'dintomb' részére.\n"); } return 0; } Kimenet 'dintomb' elemei: 1 2 3

Dinamikus memóriakezelés Egydimenziós mutatótömb #include <stdio.h> #define MERET 3 int main(void) { char* muttomb[meret] = {"Egy", "két", "há"}; int i; printf("'muttomb' elemei: \n"); for(i=0; i<meret; i++) printf("%s (%p) (%p)\n", muttomb[i], &muttomb[i], &muttomb[i][0]); putchar('\n'); return 0; } Kimenet 'muttomb' elemei: Egy (0xbfa8e490) (0x80485b0) két (0xbfa8e494) (0x80485b4) há (0xbfa8e498) (0x80485b9)

Dinamikus memóriakezelés Dinamikus, egydimenziós mutatótömb (1/2) #include <stdio.h> #include <stdlib.h> #include <string.h> #define MERET 3 #define MACSEK "Lukrécia" int main(void) { char** dinmuttomb; int i; if((dinmuttomb = (char**)malloc(meret*sizeof*dinmuttomb))) { *dinmuttomb = "Frakk"; *(dinmuttomb+1) = "Szerénke"; if((dinmuttomb[2] = (char*)malloc(strlen(macsek)+1))) { strcpy(*(dinmuttomb+2), MACSEK); printf("'dinmuttomb' elemei: \n"); for(i=0; i<meret; i++) printf("%s ", *(dinmuttomb+i)); putchar('\n'); free(dinmuttomb[2]);

Dinamikus memóriakezelés Dinamikus, egydimenziós mutatótömb (2/2) } else { fprintf(stderr, "Nem sikerült memóriát foglalni %s " "részére.\n", MACSEK); } free(dinmuttomb); } else { fprintf(stderr, "Nem sikerült memóriát foglalni " "'dinmuttomb' részére.\n"); } return 0; } Kimenet 'dinmuttomb' elemei: Frakk Szerénke Lukrécia

Dinamikus memóriakezelés Kétdimenziós tömb (mátrix) #include <stdio.h> #define MERET 3 int main(void) { int mtx[meret][meret] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, i, j; printf("'mtx' elemei (és címeik): \n"); for(i=0; i<meret; i++) { printf("mtx[%d]: (%p)\n ", i, &mtx[i]); for(j=0; j<meret; j++) printf("[%d][%d]=%d (%p) ", i, j, mtx[i][j], &mtx[i][j]); putchar('\n'); } return 0; } Kimenet 'mtx' elemei (és címeik): mtx[0]: (0xbfcfde34) [0][0]=1 (0xbfcfde34) [0][1]=2 (0xbfcfde38) [0][2]=3 (0xbfcfde3c) mtx[1]: (0xbfcfde40) [1][0]=4 (0xbfcfde40) [1][1]=5 (0xbfcfde44) [1][2]=6 (0xbfcfde48) mtx[2]: (0xbfcfde4c) [2][0]=7 (0xbfcfde4c) [2][1]=8 (0xbfcfde50) [2][2]=9 (0xbfcfde54)

Dinamikus memóriakezelés Dinamikus, kétdimenziós tömb (mutatótömb) (1/2) #include <stdio.h> #include <stdlib.h> #define MERET 3 int main(void) { int** dinmtx, i, j; if((dinmtx = (int**)calloc(meret, sizeof(int*)))) { for(i=0; i<meret; i++) { if((*(dinmtx+i) = (int*)malloc(meret*sizeof**dinmtx))) { for(j=0; j<meret; j++) *(*(dinmtx+i)+j) = i*meret+j+1; } else { fprintf(stderr, "Nem sikerült memóriát foglalni " "'dinmtx[%d]' részére.\n", i); } } printf("'dinmtx' elemei (és címeik): \n"); for(i=0; i<meret; i++) { if(dinmtx[i]) { printf("dinmtx[%d]: (%p)\n ", i, &dinmtx[i]); for(j=0; j<meret; j++) printf("[%d][%d]=%d (%p) ", i, j, dinmtx[i][j],&dinmtx[i][j]); putchar('\n'); free(*(dinmtx+i)); } } free(dinmtx);

Dinamikus memóriakezelés Dinamikus, kétdimenziós tömb (mutatótömb) (2/2) } else { fprintf(stderr, "Nem sikerült memóriát foglalni " "'dinmtx' részére.\n"); } return 0; } Kimenet 'dinmtx' elemei (és címeik): dinmtx[0]: (0x8ee0008) [0][0]=1 (0x8ee0018) [0][1]=2 (0x8ee001c) [0][2]=3 (0x8ee0020) dinmtx[1]: (0x8ee000c) [1][0]=4 (0x8ee0028) [1][1]=5 (0x8ee002c) [1][2]=6 (0x8ee0030) dinmtx[2]: (0x8ee0010) [2][0]=7 (0x8ee0038) [2][1]=8 (0x8ee003c) [2][2]=9 (0x8ee0040)

Dinamikus memóriakezelés Dinamikus, kétdimenziós tömb (alternatív megoldás) #include <stdio.h> #include <stdlib.h> #define MERET 3 int main(void) { int* dinmtx2, i, j; if((dinmtx2 = (int*)calloc(meret*meret, sizeof(int)))) { for(i=0; i<meret; i++) *(dinmtx2+i*meret+i) = 1; printf("'dinmtx2' elemei: \n"); for(i=0; i<meret; i++) { for(j=0; j<meret; j++) printf("%d ", *(dinmtx2+i*meret+j)); putchar('\n'); } free(dinmtx2); } else { fprintf(stderr, "Nem sikerült memóriát foglalni " "'dinmtx2' részére.\n"); } return 0; }

Dinamikus memóriakezelés Kimenet 'dinmtx2' elemei: 1 0 0 0 1 0 0 0 1

Dinamikus memóriakezelés Karakterláncnak futásid ben memóriát foglaló getline() (1/2) #include <stdio.h> #include <stdlib.h> int dingetline(char** eredm) { int i = 0, meret = 16; char *s = NULL, *uj, c; if(!(s = (char*)malloc(meret))) { *eredm = NULL; return 0; } while((c=getchar())!='\n' && c!=eof) { *(s+i++) = c; if(i == meret-1) { meret *= 2; uj = (char*)realloc(s, meret); if(uj) s = uj; else break; } } *(s+i) = '\0'; *eredm = s; return i; }

Dinamikus memóriakezelés Karakterláncnak futásid ben memóriát foglaló getline() (2/2) int main(void) { char* s; printf("adjon meg egy tetsz leges hosszúságú szöveget!\n"); dingetline(&s); if(s) { printf("ezt adta meg: %s\n", s); free(s); } else { fprintf(stderr, "Sikertelen memóriafoglalás.\n"); } return 0; } Kimenet Adjon meg egy tetsz leges hosszúságú szöveget! 12345678901234567890 Ezt adta meg: 12345678901234567890 Ld. még: getline()

Tömb paramétert fogadó függvények Vektor átadása függvénynek #include <stdio.h> #define MERET 3 /* void nyomtat(int[], int); */ void nyomtat(int*, int); int main(void) { int tomb[meret] = {1, 2, 3}; /* tomb++; error: lvalue required as increment operand */ nyomtat(tomb, MERET); return 0; } void nyomtat(int* t, int db) { int* utso = t+db; while(t<utso) printf("%d ", *t++); putchar('\n'); } Kimenet 1 2 3

Tömb paramétert fogadó függvények Mutatótömb átadása függvénynek #include <stdio.h> #define MERET 3 void nyomtat(char* [], int); int main(void) { char* tomb[meret] = {"Nils Holgersson", "Pocok", "Márton"}; nyomtat(tomb, MERET); return 0; } void nyomtat(char* t[], int db) { int i; for(i=0; i<db; i++) printf("%s ", *t++); putchar('\n'); } Kimenet Nils Holgersson Pocok Márton

Tömb paramétert fogadó függvények Mátrix átadása függvénynek (1/2) #include <stdio.h> #define MERET 3 void nyomtat(int (*)[], int, int); /* void nyomtat(int [][MERET], int, int); */ /* void nyomtat(int [MERET][MERET], int, int); */ /* void nyomtat(int**, int, int); */ /* void nyomtat(int [][], int, int); error: array type has incomplete element type */ int main(void) { int tomb[meret][meret] = {{1, 2, 3}, {8, 9, 4}, {7, 6, 5}}; nyomtat(tomb, MERET, MERET); return 0; } void nyomtat(int (*t)[meret], int s, int o) { /* void nyomtat(int t[][meret], int s, int o) { */ /* void nyomtat(int t[meret][meret], int s, int o) { */ /* void nyomtat(int **t, int s, int o) { expected `int **' but argument is of type `int (*)[3]' */ /* void nyomtat(int (*t)[], int s, int o) { error: increment of pointer to unknown structure error: arithmetic on pointer to an incomplete type */

Tömb paramétert fogadó függvények Mátrix átadása függvénynek (2/2) int i, j, *elem; for(i=0; i<s; i++) { elem = *t++; for(j=0; j<o; j++) printf("%d ", *elem++); putchar('\n'); } } Kimenet 1 2 3 8 9 4 7 6 5

Tömböt visszaadó függvények Automatikus tárolási osztályú tömb (címe) nem adható vissza biztonságosan! Mátrixot visszaadó függvény #include <stdio.h> #define MERET 3 int mtx[meret][meret] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; int (*vissza(void))[meret] { return mtx; } int main(void) { int (*pmtx)[meret], i, j; printf("'mtx' elemei:\n"); pmtx = vissza(); for(i=0; i<meret; i++) { for(j=0; j<meret; j++) printf("%d ", pmtx[i][j]); putchar('\n'); } return 0; }

Tömböt visszaadó függvények Ennél a megoldásnál az egymást követ hívások ugyanazt a puert használják; mi lenne, ha különféleképpen paraméterezett itoa() hívások szerepelnének ugyanannak a printf()-nek paramétereiként? Vektort visszaadó függvény #include <stdio.h> #define MAX 128 char* itoa(int i) { static char buf[max]; sprintf(buf, "%d", i); return buf; } #define ERTEK 123 int main(void) { printf("%d karakteres alakja: %s\n", ERTEK,itoa(ERTEK)); return 0; }

Tömböt visszaadó függvények Vektort visszaadó függvény (dinamikus változat) #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 128 char* itoa(int i) { char buf[max], *s; int hossz; sprintf(buf, "%d", i); hossz = strlen(buf); if((s = (char*)malloc(hossz+1))) { strcpy(s, buf); return s; } else return NULL; } #define ERTEK 123 int main(void) { char *s1, *s2; printf("%d és %d karakteres alakjai: %s, %s.\n", ERTEK, ERTEK*2, s1=itoa(ertek), s2=itoa(ertek*2)); free(s1); free(s2); return 0; }

Parancssori paraméterek Minden C programban lennie kell pontosan egy, programot indító main() fv.-nek (konzol alk. esetén). Paraméterei: elhagyhatóak, nem ANSI szabványosak. A main() lehetséges alakjai: int main(); Nem mondunk semmit a paraméterezésr l. int main(void); Nem fogad paramétereket. int main(int argc); Csak a paraméterek száma ismert (beleszámítja a program nevét is). int main(int argc, char* argv[]); A paraméterek száma és értéke is ismert; argv mutatótömb, melynek argc index eleme NULL mutató.

Parancssori paraméterek Parancssori paraméterek lekérdezése, 1. változat #include <stdio.h> int main(int argc, char* argv[]) { while(*argv) printf("%s\n", *argv++); return 0; } Parancssori paraméterek lekérdezése, 2. változat #include <stdio.h> int main(int argc, char* argv[]) { int i; for(i=0; i<argc; i++) printf("%s\n", argv[i]); return 0; } Kimenet./proba 42 Lolka "Batka manó"./proba 42 Lolka Batka manó

Parancssori paraméterek Microsoft-specikus megoldás: az stdlib.h bekapcsolása után elérhet ek: extern int argc extern char** argv Parancssori paraméterek lekérdezése, 3. változat #include <stdio.h> #include <stdlib.h> int main(void) { int i; for(i=0; i< argc; i++) printf("%s\n", argv[i]); return 0; } Megjegyzés: argv[0] azt a karakterláncot tartalmazza, amivel a programot elindították.

Példa parancssori paraméterek használatára pelda30m.c (1/3) /* pelda30m.c -- Adott szöveg keresése szöveg soronként Indítas: pelda30m -x -n keresend _szöveg */ #include <stdio.h> #include <string.h> #include <ctype.h> #define MAXSOR 1000 int getline(char s[], int lim); int main(int argc, char *argv[]) { char sor[maxsor+1]; /* Beolvasott sor */ char *k; /* Mutató a parancssor elemzéséhez */ long sorszam = 0L; /* Sorszámláló */ int kiveve = 0; /* Ha 1, azon szöveg sorok írandók ki, melyekben nincs benn a ker. szöveg */ int szam = 0; /* Ha 1, a kiírt szöveg sorokat sorszámmal kell ellátni. */

Példa parancssori paraméterek használatára pelda30m.c (2/3) /* A parancssor opcionális paramétereinek (-x -n) lekezelése */ while(--argc>0 && (*++argv)[0]=='-') for(k=argv[0]+1; *k!='\0'; k++) switch(tolower(*k)) { case 'x': kiveve = 1; break; case 'n': szam = 1; break; default: printf("\n\r\tkeresés: -%c illegális kapcsoló!\n", *k); argc = 0; break; } /* A keresett szöveg paraméter */ if(argc!=1) printf("\n\rindítás: pelda30m -x -n keresend _szöveg!!!\n"); else { printf("gépeljen be szöveg sorokat üres sorig vagy EOF-ig!\n" "Kiírjuk%s, melyikben %sszerepel %s!\n", szam?" sorszámával együtt":"",kiveve?"nem ":"",*argv);

Példa parancssori paraméterek használatára pelda30m.c (3/3) while(getline(sor, MAXSOR)>0) { sorszam++; if((strstr(sor, *argv))!= kiveve) { if(szam) printf("%ld: ", sorszam); printf("%s\n", sor); } } } return 0; } int getline(char s[], int lim) { /* */ } Kimenet./pelda30m -n alma Gépeljen be szöveg sorokat üres sorig vagy EOF-ig! Kiírjuk sorszámával együtt, melyikben szerepel alma! eper Balmazújváros 2: Balmazújváros

Környezeti változók Kulcs-érték párok = jellel elválasztva. Feladatuk lehet pl. programok m ködését befolyásoló paraméterek tárolása, programok keresési útvonalainak tárolása (PATH), stb. Ahány konzolt nyitunk, annyi halmaz jön létre a változókból! Környezeti változók használata C:\Users\hatwagner>set ALLUSERSPROFILE=C:\ProgramData APPDATA=C:\Users\hatwagner\AppData\Roaming CommonProgramFiles=C:\Program Files\Common Files C:\Users\hatwagner>set kulcs A következõ környezeti változó nem definiált: kulcs. C:\Users\hatwagner>set kulcs=ertek C:\Users\hatwagner>set kulcs kulcs=ertek C:\Users\hatwagner>set kulcs= C:\Users\hatwagner>set kulcs A következõ környezeti változó nem definiált: kulcs.

Környezeti változók Környezeti változók lekérdezésének módjai: a main() fv. harmadik paraméterén keresztül int main(int argc, char* argv[], char* env[]); char *getenv(const char *name); Beszerkesztend az stdlib.h, csak a kulcsot kell megadni; ha nem létezik a kulcs, NULL értéket ad vissza A visszaadott mutató nem alkalmas a változó értékének biztonságos módosítására! Módosítás és törlés: int putenv(char *string); Beszerkesztend az stdlib.h. string alakja: kulcs=érték. Ha nincs ilyen kulcs, létrehozza a megadott értékkel, egyébként módosítja az értéket. Csak kulcs megadásával lehet a változót törölni. 0 v. t. érték jelzi a sikeres módosítást, 1 pedig a hibát.

Környezeti változók Változók listázása #include <stdio.h> int main(int argc, char* argv[], char* env[]) { while(*env) printf("%s\n", *env++); return 0; } Változó lekérdezése, módosítása (1/2) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> #define KULCS "szereplo" #define ERTEK "Pumukli" #define CSERE "Eder mester" int main(void) { char* kv; char uj[128]; SetConsoleOutputCP(1250);

Környezeti változók Változó lekérdezése, módosítása (2/2) if((kv = getenv(kulcs))) { printf("%s értéke %s\n", KULCS, kv); if(!strcmp(kv, CSERE)) { sprintf(uj, "%s=%s", KULCS, ERTEK); putenv(uj); printf("%s értékét %s-ra cseréltük.\n", KULCS, ERTEK); } } else { printf("%s nem definiált.\n\n", KULCS); } return 0; }

Programbefejezés A main() fv. int típusú v. t. értéke a státusz kód, vagy kilépési kód. Megállapodás szerint 0 jelzi a sikeres programlefutást bármely más érték pedig a különféle hibákat. stdlib.h beszerkesztése szimbolikus állandók: EXIT_SUCCESS 0 EXIT_FAILURE 1 Státuszkód el állítható: main()-ben kiadott return segítségével bármely fv.-ben kiadott exit(), abort() hívásokkal (stdlib.h)

Programbefejezés void exit(int status); status értékét kapja meg a szül folyamat meghívja a regisztrált kilépési függvényeket (ld. atexit()) puereket üríti nyitott fájlokat lezárja void abort(void); stderr Abnormal program termination SIGABRT jelzést vált ki ha nincs regisztrált jelzéskezel (ld. signal()), 3-as státuszkóddal kilép

Programbefejezés vissza.c #include <stdio.h> int main(void) { char c; printf("adja meg a visszatérési értéket 0-9 között! "); while((c=getchar())<'0' c>'9'); return c-'0'; } korny.bat @echo off vissza.exe if ERRORLEVEL 2 goto ketto if ERRORLEVEL 1 goto egy if ERRORLEVEL 0 goto nulla :nulla ECHO A program hibamentesen lefutott. goto vege :egy ECHO Hibakod: 1. goto vege :ketto ECHO Hibakod: 2, vagy tobb. :vege

Függvény (kód) mutatók Függvények belépési pontját címz mutatók int fv(double, int); int (*pfv)(double, int); int *ipfv(double, int); egészet címz mutatóval visszatér függvény pfv: kódmutató változó, fv: konstans kódmutató Értékadás hozzárendeléssel: pfv = fv; Inicializációval: int (*pfv)(double, int) = fv; Prototípus is elég a hozzárendeléshez Meghatározatlan paraméterlistájú függvényt címz mutató is kaphat értéket: int (*mpfv)() = fv; Függvényhívás: int i = fv(1.2, 3); int i = (*pfv)(1.2, 3); Függvény bármilyen függvényre mutató kifejezéssel meghívható

Függvény (kód) mutatók Kódmutatókkal végezhet m veletek: címük képzése sizeof operátor operandusai lehetnek végrehajtható rajtuk az indirekció értéket kaphatnak meghívhatók velük függvények paraméterként átadhatók függvényeknek kódmutatótömbök hozhatók létre függvény visszatérési értéke lehet explicit típuskonverzióval más típusra alakíthatóak Nem alkalmazható rájuk mutatóaritmetika, kivéve egyenl ségi relációk (== és!=)

Kódmutató paramétert fogadó függvények Rekurzív gyorsrendezés: stdlib.h void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); Szövegsorok sorba rendezése (1/2) #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100 int hasonlit(const void *, const void *); int getline(char*, int); int main(void) { char* sorok[max]; char sor[max]; int db, hossz, i;

Kódmutató paramétert fogadó függvények Szövegsorok sorba rendezése (2/2) printf("szövegsorok olvasása üres sorig vagy EOF-ig,\n" "majd sorba rendezett kiírása.\n"); for(db=0; (hossz=getline(sor, MAX)); db++) { if(!(sorok[db] = (char*)malloc(hossz+1))) break; strcpy(sorok[db], sor); } qsort(sorok, db, sizeof(char*), hasonlit); printf("sorba rendezve:\n"); for(i=0; i<db; i++) { printf("%s\n", sorok[i]); free(sorok[i]); } return 0; } int hasonlit(const void *p1, const void *p2) { return strcmp(*(const char**)p1, *(const char**)p2); } int getline(char *s, int lim) { /* */ }

Kódmutató paramétert fogadó függvények Kilépési fv. regisztrálása: stdlib.h int atexit(void (*function)(void)); Normál programbefejezéskor (main() return, exit()) meghívásra kerülnek Hívás a regisztrálással ellentétes sorrendben Hiba esetén nem zérus értéket ad vissza Kilépési függvények kipróbálása #include <stdio.h> #include <stdlib.h> void kfv1(void) { printf("els kilépési függvény!\n"); } void kfv2(void) { printf("második kilépési függvény!\n"); }

Kódmutató paramétert fogadó függvények Kilépési függvények kipróbálása int main(void) { printf("kilépési függvények\n"); if(atexit(kfv1)) { fprintf(stderr, "Hiba az 1. fv. regisztrálásakor!\n"); return 1; } if(atexit(kfv2)) { fprintf(stderr, "Hiba a 2. fv. regisztrálásakor!\n"); return 2; } return 0; } Kimenet Kilépési függvények Második kilépési függvény! Els kilépési függvény!

Kódmutatótömb, kódmutató visszatérési érték Kódmutatókból álló tömbök is létrehozhatók: Kódmutatótömb int fv1(double, int); int fv2(double, int); int fv3(double, int); int (*pfvt[])(double, int) = {fv1, fv2, fv3}; int i; i = (*pfvt[1])(1.2, 3); Kódmutató visszatérési érték: signal.h void ( *signal(int signum, void (*handler)(int)) ) (int); A függvény neve signal Paraméterei: int (jelzés azonosítója) és void(*handler)(int) (jelzéskezel fv., vagy SIG_IGN, SIG_DFL) V.t. érték: void(*)(int) (mint a 2. paraméter; régi jelzéskezel, vagy SIG_ERR hiba esetén)

Kódmutató visszatérési érték Jelzés kezelése #include <stdio.h> #include <stdlib.h> #include <time.h> #include <signal.h> void jk(int jelzes) { printf("%d: Kilépés a programból.\n", jelzes); exit(0); } int main(void) { printf("véletlenszámok el állítása CTRL+C-ig\n"); srand((unsigned)time(null)); if(signal(sigint, jk)==sig_err) { fprintf(stderr, "Jelzéskezel regisztrálása " "sikertelen.\n"); return 1; } while(1) printf("%d\t", rand()); return 0; }

Kódmutató visszatérési érték Kimenet./muvelet 680461512 311919537^C86 328563258 680461512 311919537 1334620320 1157555306 319024189 1180293652 1356184519 1411874091 270367037 999655971 1820643988 1912920013 489573322 2010300691 1999578148 153292354 1690102416 1714190859 2077520037 5592: Kilépés a programból.

Explicit típuskonverzió, típusdeníció (typedef) Típuskonverzió int fv(double, int), i; int (*pfv)(double, int) = fv; void (*vpfv)(double); vpfv = ( void(*)(double) )pfv; (*vpfv)(1.2); /* Vajon m ködni fog? */ pfv = ( int(*)(double, int) )vpfv; i = (*pfv)(1.2, 3); /* OK */ Meglév típusokhoz új nevet deniálhatunk (szinonímák) a typedef segítségével. Általános alak: typedef tipus azonosito; Növeli a programkód hordozhatóságát (típusok paraméterezhet sége), olvashatóság javítása Az új típusnév elfedi a típus jellegét (tömb, függvény, egyszer változó, stb.) A típusdeníció korábbi típusdeníciókat is felhasználhat

Típusok és típusdeníció (typedef) Típusok megadása típusdenícióval és anélkül /* i1, i2 egészek */ int i1; typedef int ti; ti i2; /*pi1, pi2 egészet címz mutatók */ int *pi1; typedef int *tpi; tpi pi2; /* ia1, ia2 3 elem, egészekb l álló tömbök */ int ia1[3]; typedef int tia[3]; tia ia2; /* ipa1, ipa2 3 elem mutatótömbök */ int *ipa1[3]; typedef int *tipa[3]; tipa ipa2; /* pia1, pia2 3 elem, egészekb l álló tömböt címz mutatók */ int (*pia1)[3]; typedef int (*tpia)[3]; tpia pia2; /* pf1, pf2 egésszel visszatér, paramétert nem fogadó függvényt címz mutatók */ int (*pf1)(void); typedef int (*tpf)(void); tpf pf2;

Típusok és típusdeníció (typedef) Típusok megadása típusdenícióval és anélkül /* f1, f2 értéket vissza nem adó függvények, melyek olyan függvényt címz mutatót várnak paraméterként, mely egésszel tér vissza és double paramétert fogad */ void f1(int(*pf)(double)); typedef void tf(int(*pf)(double)); tf f2; /* fr1, fr2 paramétert nem fogadó függvények, melyek olyan függvényt címz mutatót adnak vissza, ami egész visszatérés és double paramétert fogad */ int (*fr1(void))(double); typedef int (*tfr(void))(double); tfr fr2; /* int atexit(void (*function)(void)); */ typedef void (*ft)(void); int atexit(ft function); /* void (*signal(int signum,void(*handler)(int)))(int); */ typedef void (*jt)(int); jt signal(int signum, jt handler);

Típusdeníció (typedef) Bináris keresés: stdlib.h void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); M velet végzése parancssorban megadott értékekkel (1/3) #include <stdio.h> #include <stdlib.h> #include <string.h> typedef double(*fv)(double, double); double osszeadas(double, double); double szorzas(double, double); int hasonlit(const void *, const void *); int main(int argc, char* argv[]) { double eredm; char **n, *nev[] = {"osszeadas", "szorzas"}; fv aktmuv, muvelet[] = {osszeadas, szorzas}; int i;

Típusdeníció (typedef) M velet végzése parancssorban megadott értékekkel (2/3) printf("m veletek végzése számokkal\n"); if(argc<3) { printf("használat:./muvelet osszeadas szorzas " "szam1 szam2 \n"); return 1; } n = bsearch(argv+1, nev, sizeof(nev)/sizeof(*nev), sizeof(char*), hasonlit); if(!n) { printf("ismeretlen m velet!\n"); return 2; } aktmuv = muvelet[n-nev]; eredm = atof(argv[2]); for(i=3; i<argc; i++) eredm = (*aktmuv)(eredm, atof(argv[i])); printf("eredmény: %.3f\n", eredm); return 0; }

Típusdeníció (typedef) M velet végzése parancssorban megadott értékekkel (3/3) double osszeadas(double a, double b) { return a+b; } double szorzas(double a, double b) { return a*b; } int hasonlit(const void *p1, const void *p2) { return strcmp(*(const char**)p1, *(const char**)p2); } Kimenet./muvelet osszeadas 2 3 4 M veletek végzése számokkal Eredmény: 9.000./muvelet szorzas 2 3 4 M veletek végzése számokkal Eredmény: 24.000./muvelet kivonas 2 3 4 M veletek végzése számokkal Ismeretlen m velet!