Programozás I gyakorlat 10. Stringek, mutatók
Karakter típus A char típusú változókat karakerként is kiírhatjuk: #include <stdio.h> char c = 'A'; printf("%c\n", c); c = 80; printf("%c\n", c); printf("%c\n", c + 1); Kimenet: A P Q 2
Karaktertömb Ezzel jelezzük a tömb végét #include <stdio.h> char szoveg[5] = {'a', 'l', 'm', 'a', 0; int i = 0; while (szoveg[i]!= 0) { printf("%c", szoveg[i]); i++; printf("\n"); 3
Karaktertömb, azaz string De nincs szükségünk ilyen ciklusra, mivel ezt a printf is tudja: #include <stdio.h> char szoveg[5] = {'a', 'l', 'm', 'a', 0; printf("%s\n", szoveg); 4
Karaktertömb, azaz string Egyszerűbben is inicializálhatjuk: #include <stdio.h> char szoveg[] = "alma"; printf("%s\n", szoveg); Figyelem! A tömb 5 elemű lesz, a fordító kiegészíti a lezáró 0-val. 5
String beolvasása Ha stringet olvasunk be, akkor nem kell & #include <stdio.h> char szoveg[10]; scanf("%s", szoveg); printf("%s\n", szoveg); 6
Változók helye Alap esetben minden változó a memóriában található int a = 22, b = 42; 112 113 114 115 116 117 118 119 120 121 122 543 32 22 0 0 0 42 0 0 0 563 a b 7
Mutató Olyan változó, amely memóriacímet tartalmaz int a = 12; int * mutatoa = &a; 112 113 114 115 116 117 118 119 120 121 122 543 32 12 0 0 0 114 0 0 0 563 a mutatoa 8
Mutató int típusú változó címét tároljuk int a = 12; int * mutatoa = &a; 112 113 114 115 116 117 118 119 120 121 122 543 32 12 0 0 0 114 0 0 0 563 a mutatoa 9
Mutató A * jelzi, hogy mutatót hozunk létre int a = 12; int * mutatoa = &a; 112 113 114 115 116 117 118 119 120 121 122 543 32 12 0 0 0 114 0 0 0 563 a mutatoa 10
Mutató A mutató változónak adunk egy nevet int a = 12; int * mutatoa = &a; 112 113 114 115 116 117 118 119 120 121 122 543 32 12 0 0 0 114 0 0 0 563 a mutatoa 11
Mutató Az & címképző operátor megadja az a változó memóriacímét int a = 12; int * mutatoa = &a; 112 113 114 115 116 117 118 119 120 121 122 543 32 12 0 0 0 114 0 0 0 563 a mutatoa 12
Mutató * indirekció operátor: az a változó, amire a mutató mutat int a = 12; int * mutatoa = &a; *mutatoa = 20; 112 113 114 115 116 117 118 119 120 121 122 543 32 20 0 0 0 114 0 0 0 563 a mutatoa 13
Mutatóra mutató mutató Egy int* típusú változó címét tároljuk el int a = 42; int * mutatoa = &a; int ** mutatomutatoa = &mutatoa; **mutatomutatoa = 10; 114 115 116 117 118 119 120 121 122 123 124 125 10 0 0 0 114 0 0 0 118 0 0 0 a mutatoa mutatomutatoa 14
Feladat Írj függvényt, amely megcseréli a main-ben lévő két változó értékét. #include <stdio.h> int a = 10; int b = 20; csere(? ); printf("%d %d\n", a, b); 15
Megoldás Adjuk át a két változó mutatóját: #include <stdio.h> void csere(int * pa, int * pb) { int temp = *pa; *pa = *pb; *pb = temp; int a = 10; int b = 20; csere(&a, &b); printf("%d %d\n", a, b); 16
Mutató kiírása A %p memóriacímként értelmezi a kiírandó változó bitmintáját. #include <stdio.h> int a; int b; printf("%p %p\n", &a, &b); 17
Mutatók és tömbök Ha csak a tömb nevét írom le, akkor az a kifejezés a tömb 0. elemének a címét adja meg. #include <stdio.h> int tomb[4] = {1, 2, 3, 4; int * ptr = tomb; printf("%d\n", *ptr); printf("%d\n", *tomb); 18
Mutató aritmetika A mutatóhoz hozzáadhatok 1-et: #include <stdio.h> int tomb[4] = {1, 2, 3, 4; int * ptr = tomb; ptr++; printf("%d\n", *ptr); 19
Mutató aritmetika Milyen memóriacímre fog mutatni? int tomb[4] = {1, 2, 3, 4; int * ptr = tomb; ptr++; A mutató int * típusú, azaz int-re mutat Az int mérete sizeof(int) A mutató által tárolt cím 1*sizeof(int)-el nő 20
Feladat Olvasd be, majd írasd ki a [] jel használata nélkül egy 10 elemű tömb elemeit. 21
Megoldás #include <stdio.h> int tomb[10]; int * ptr = tomb; int i; for (i = 0; i < 10; i++) { scanf("%d", ptr + i); for (i = 0; i < 10; i++) { printf("%d\n", *(tomb + i)); 22
Tömb indexelése tomb[i] = *(tomb + i) 23
Kérdés Mit ír ki az alábbi programrészlet? int tomb[4] = {1, 2, 3, 4; int * ptr = tomb; ptr += 2; printf("%d\n", ptr[1]); 24
Megoldás int tomb[4] = {1, 2, 3, 4; int * ptr = tomb; ptr += 2; printf("%d\n", ptr[1]); 0 1 2 3 1 2 3 4 tomb ptr 25
Megoldás int tomb[4] = {1, 2, 3, 4; int * ptr = tomb; ptr += 2; printf("%d\n", ptr[1]); 0 1 2 3 1 2 3 4 tomb ptr 26
Megoldás int tomb[4] = {1, 2, 3, 4; int * ptr = tomb; ptr += 2; printf("%d\n", ptr[1]); 0 1 2 3 1 2 3 4 tomb ptr ptr[1] 27
Érvénytelen memóriahivatkozás Nem férhetünk hozzá a teljes memória tartalmához! #include <stdio.h> int * ptr = 0; printf("%d\n", ptr[1]); 28
Érvénytelen memóriahivatkozás A számítógép memóriáján több program osztozik Minden program csak a saját területét érheti el! skype myprogram firefox Linux 29
Érvénytelen memóriahivatkozás Amelyik program más területet címez, azt a rendszer likvidálja skype myprogram firefox Linux 30
Stringek összehasonlítása A stringek nem C típusok, csupán tömbök, a ==,!=, >, >=, < és <= operátorok nem magukat a stringeket hasonlítják össze, hanem a kezdőcímüket! #include <stdio.h> char str1[] = "korte"; char str2[] = "korte"; if (str1 == str2) { printf("egyenloek\n"); 31
Stringek összehasonlítása Az strcmp függvényre van szükségünk (string.h) #include <stdio.h> #include <string.h> char str1[] = "korte"; char str2[] = "korte"; if (strcmp(str1, str2) == 0) { printf("egyenloek\n"); 32
Gyakran ismételt kérdések Áhá, tehát az alábbi programban a tomb az egy mutató, tehát meg is növelhetem az értékét? int tomb[2]; tomb++; NEM! Itt a tomb az egy tömb, nem mutató, ezzel hivatkozunk egy memória szakaszra. 33
Gyakran ismételt kérdések Milyen típusú az a és b változó? int * a, b; a: int * b: int Ha azt szeretnénk, hogy b is int * legyen, akkor a b elé is oda kell írni a * karaktert 34