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

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

8. gyakorlat Pointerek, dinamikus memóriakezelés

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

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.

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

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

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

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

10. gyakorlat Struktúrák, uniók, típusdefiníciók

5. gyakorlat. Konstansok Tömbök Stringek

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

Programozas 1. Strukturak, mutatok

1. Alapok. Programozás II

Dinamikus mátrixok. Dinamikus többdimenziós tömbök

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

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

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

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

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

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

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

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

Programozás I gyakorlat

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

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

INFORMATIKA javítókulcs 2016

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

Programozás alapjai 2.Gy: A C nyelv alapjai P R O

Pénzügyi algoritmusok

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

Programozás I gyakorlat

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 C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

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

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 gyakorlat. 2. gyakorlat C alapok

INFORMATIKA tétel 2018

Tömbök kezelése. Példa: Vonalkód ellenőrzőjegyének kiszámítása

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

5. Gyakorlat. struct diak {

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

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

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

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

A C programozási nyelv I. Bevezetés

A C programozási nyelv I. Bevezetés

12. gyakorlat Enum; Tárolási osztályok Preprocesszor utasítások; Moduláris programozás

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

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

Programozási Nyelvek: C++

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

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

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

Java II. I A Java programozási nyelv alapelemei

C változók. Feladat: Deklaralj egy valos, egy karakter es ket egesz tipusu valtozot! int main() {

Programozás II gyakorlat. 6. Polimorfizmus

Maximum kiválasztás tömbben

Vezérlési szerkezetek

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

7. fejezet: Mutatók és tömbök

Programozási nyelvek Java

Információs Technológia

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

Készítette: Nagy Tibor István

Programozás I. gyakorlat

Pásztor Attila. Algoritmizálás és programozás tankönyv az emeltszintű érettségihez

Bevezetés a programozásba I.

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 C++ -ban

Alkalmazott modul: Programozás 8. előadás. Strukturált programozás: dinamikus memóriakezelés. Dinamikus memóriakezelés. Dinamikus memóriakezelés

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

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.

Adatszerkezetek Tömb, sor, verem. Dr. Iványi Péter

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

1. Feladat: beolvas két számot úgy, hogy a-ba kerüljön a nagyobb

Algoritmusok és adatszerkezetek gyakorlat 06 Adatszerkezetek

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

Java II. I A Java programozási nyelv alapelemei

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

C string műveletek (string.h alkalmazása)

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

3. Osztályok II. Programozás II

Hatékony memóriakezelési technikák. Smidla József Operációkutatási Laboratórium január 16.

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

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

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)

Programozás C és C++ -ban

C++ referencia. Izsó Tamás február 17. A C++ nyelvben nagyon sok félreértés van a referenciával kapcsolatban. A Legyakoribb hibák:

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

INFORMATIKA tétel 2017

1. Jelölje meg az összes igaz állítást a következők közül!

Pointerek C-ben, C++-ban

Alkalmazott modul: Programozás 10. fejezet. Strukturált programozás: dinamikus memóriakezelés. Giachetta Roberto

1. Gyakorlat. Rövid elméleti összefoglaló. <tárolási osztály>típus <típus > változónév <= kezdőérték><, >;

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

Operációs rendszerek III.

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

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

INFORMATIKA tétel 2019

Átírás:

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

Pointer A pointer egy mutató egy memóriacellára, egyfajta "parancsikon", csak nem fájlokra, hanem változókra. Létrehozás: tipus * név;, ahol a típus a hivatkozott változó típusa. A pointerek használatával kapcsolatos függvények az stdlib.h-ban találhatók.

Pointerek malloc(meret): egy megadott méretű adatterületet egy pointerhez hozzárendel a méret a lefoglalandó tárterület bájtokban sizeof operátor segítségével állapíthatjuk meg A lefoglalt területet használat után fel KELL szabadítani a free(pointer) utasítással. A pointerhez tartozó értéket a * operátorral érjük el, pl. *pointerem. Ezt pointer-dereferenciának hívjuk.

Példa #include <stdlib.h> int main() { int a = 5; int *p; p = malloc( sizeof(int) ); //memóriafoglalás *p = a; //*p = 5 (*p)++; //*p = 6 a = *p; //a= 6 free(p); //memória felszabadítás return 0;

P: Nézzük meg, mi a különbség p, q, illetve *p és *q értéke között. #include <stdio.h> #include <stdlib.h> int main() { int *p, *q; p = malloc(sizeof(int)); q = malloc(sizeof(int)); *p = 3; *q = 3; ez azt vizsgálja, hogy p és q ugyanarra a címre mutat-e printf("p es q %s\n", p == q? "megegyezik" : "nem egyezik meg"); printf("*p == %d, *q == %d\n", *p, *q); *p = 4;

printf("*p == %d, *q == %d\n", *p, *q); free(p); p = q; printf("p es q %s\n", p == q? "megegyezik" : "nem egyezik meg"); printf("*p == %d, *q == %d\n", *p, *q); *p = 4; printf("*p == %d, *q == %d\n", *p, *q); free(p); return 0; ez azt vizsgálja, hogy p és q ugyanolyan értékre mutat-e

P: Futtassuk le a következő programot, és értelmezzük! Melyik érték melyik értékkel egyenlő, és miért? #include <stdio.h> int main() Egy változóhoz tartozó memóriacímet az & { operátorral érhetünk el, pl. &valtozo. Ezt hozzárendelhetjük egy pointerhez: p = &a;. int a = 10; int *pa; pa = &a; printf("%d %#x\n", a, (int)pa); printf("%#x %#x\n", (int)&a, (int)&pa); printf("%d\n", *pa); return 0;

F: Írj egy csere() függvényt, ami megcseréli két int típusú változó értékét. #include <stdio.h> void csere(int x, int y){ int tmp; tmp = x; x = y; y = tmp; int main(){ int x = 3, y = 4; printf("a fuggveny elott: x = %d, y = %d\n", x, y); csere(x,y); printf("a fuggveny utan: x = %d, y = %d\n", x, y); return 0;

F: Mi a hiba? Javítsuk a programot! #include <stdio.h> void csere(int * x, int * y){ int tmp; tmp = *x; *x = *y; *y = tmp; int main(){ int x = 3, y = 4; printf("a fuggveny elott: x = %d, y = %d\n", x, y); csere(&x,&y); printf("a fuggveny utan: x = %d, y = %d\n", x, y); return 0;

Pointerek vs tömbök A C nyelvben a tömbök is egyfajta pointerek: létrehozáskor a [] között megadott darabszámú egymás után elhelyezkedő memóriacella lefoglalódik valahol a memóriában ÉS létrejön (valahol máshol) egy megfelelő típusú pointer, ami az első (nulladik) cellára mutat. Ez a pointer a tömb elérésére használt változó. Mikor a tömb egy adott elemét használjuk (tomb[index]), akkor a "tomb" pointerben tárolt memóriacímhez hozzáadódik "index" értéke és az így kapott címen kezdődő megfelelő méretű cellát érjük el. (tomb[index] *(tomb+index) ) Ezért is kezdődik 0-ról a tömbök indexelése C-ben.

F: Deklarálj egy 20 elemű int tömböt, majd töltsd fel értékekkel az inputról. Deklarálj egy pointert, és a beolvasást azon keresztül valósítsd meg. #include <stdio.h> #define N 20 int main() { int t[n], *p, i; for(i=0; i<n; i++) { p=&(t[i]); scanf("%d", p); for(i=0; i<n; i++) { printf("%d\n", t[i]); return 0;

F: Először olvasd be a tömb méretét, és foglalj neki dinamikusan helyet! #include <stdio.h> #include <stdlib.h> int main() { int *t, *p, i, N; scanf("%d", &N); t=(int*)malloc(n*sizeof(int)); for(i=0; i<n; i++) { p=&(t[i]); scanf("%d", p); for(i=0; i<n; i++) { printf("%d\n", t[i]); free(t); return 0;

F: Olvass be 5 darab maximum 99 karakter hosszú szót úgy, hogy mindegyiknek pontosan annyi helyet foglalsz, amennyi kell! A sztringeket írasd ki, majd szabadítsd fel a lefoglalt területet! #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char buff[100]; char *ptr_tomb[5]; int i;

for(i=0; i<5; i++) { scanf("%s", buff); ptr_tomb[i] = (char*)malloc(strlen(buff)+1); strcpy(ptr_tomb[i], buff); for(i=0; i<5; i++) { puts(ptr_tomb[i]); for(i=0; i<5; i++) { free(ptr_tomb[i]); return 0;

F: Olvasd be egy tömb méretét, foglalj neki dinamikusan helyet, majd olvasd be az elemeit! #include <stdio.h> #include <stdlib.h> int main(){ int *t, *p, i, N; scanf("%d", &N); t=(int*)malloc(n*sizeof(int)); for(i=0, p=t; i<n; i++, p++) { scanf("%d", p); for(i=0, p=t; i<n; i++) { printf("%d\n", *(p++)); free(t); return 0;

Több dimenziós tömbök vs pointer Többdimenziós tömbök folytonosan tárolódnak a memóriában: tipus tomb[2][2]; esetén tomb[0][0] a 0., tomb[0][1] az 1., tomb[1][0] a 2. és tomb[1][1] a 3. egymás utáni memóriacellában tárolódik el. Ezenkívül, a pointerekben tárolt memóriacímet additív aritmetikai műveletekkel (összeadás, kivonás) módosíthatjuk is.

F: Adott egy kétdimenziós tömb. Pointer segítségével járjuk be az összes elemét. #include <stdio.h> #define SIZE 3 int main() { int tomb[size][size] = {{0, 1, 2, {3, 4, 5, {6, 7, 8 ; int i,j; int *pa = NULL; // így a pointer nem mutat sehova sem, azaz "nullpointer" pa = tomb; /* pa = &tomb[0][0] */ for(i = 0; i< SIZE*SIZE; i++) printf("%2d ", pa[i]); printf("\n");

for(i = 0; i< SIZE*SIZE; i++) printf("%2d ", *(pa+i)); printf("\n"); for(i = 0; i< SIZE*SIZE; i++, pa++) printf("%2d ", *pa); printf("\n"); return 0; vigyázat! mivel pa-t növeltük a for ciklusban, ezért a ciklus után már nem a tömb legelső elemére fog mutatni!

2D tömbök 2D-sként 2D-s dinamikus tömböt tömbök tömbjeként lehet létrehozni, ahol a "külső tömb" pointereket tárol. Pl. tomb[n][m] létrehozása dinamikusan úgy történik, hogy létrehozunk egy N-méretű pointertömböt, majd minden eleméhez lefoglalunk egy M méretű tömböt. Ekkor a tomb változó egy pointerre mutató pointer lesz. Itt már természetesen N és M lehet változó is, bekérhetjük felhasználótól, stb. Ennek felszabadításához először a "belső" tömböket kell egyenként felszabadítani, majd a külső pointertömböt.

2D tömb 2D-sként int **tomb; // a tömböt jelentő pointer, intre mutató pointerre mutat, ezért //két * kell tomb = malloc(n * sizeof(int*)); // a külső tömb lefoglalása intre mutató pointereknek for(i = 0; i < N; i++) { // a belső tömbök lefoglalása - inteknek tomb[i] = malloc(m * sizeof(int)); // használat - mintha egy "sima" tömb lenne // felszabadítás for(i = 0; i < N; i++) { // először a belső tömböket free(tomb[i]); free(tomb); // majd a külsőt

2D tömb 1D-sként Egy másik lehetőség, hogy egydimenziós tömböt hozunk létre megfelelő méretben, és abban sorfolytonosan tároljuk a 2D-s tömb elemeit. Ezt egyszerűbb létrehozni és megszüntetni, viszont bonyolultabb használni.

2D tömb 1D-sként int *tomb; // a tömböt jelentő pointer, így csak egy * kell tomb = malloc(n * M * sizeof(int)); // a tömb lefoglalása - N*M elemű kell // használat - ki kell számolni az indexet for(i=0; i < N; i++) { for(j=0; j < M; j++) { tomb[i*m+j] = valami; // eddig i sort léptünk át, egy sor M hosszú // felszabadítás - így egy lépésben lehet, mert csak 1D-s //tömbünk van free(tomb);

F: Dinamikus kétdimenziós tömb létrehozása #include <stdio.h> #include <stdlib.h> int main(){ int *p, **t; int N=3, M=4; int i, j, v=0; /* V1: egydimenziós tömb */ p=malloc(n*m*sizeof(int)); for(i=0; i<n; i++) { for(j=0; j<m; j++) { p[i*m+j]=v++; free(p); //i db sort léptünk át+j. helyen vagyunk

/* V2: sorokat külön-külön */ t=malloc(n*sizeof(int*)); for(i=0; i<n; i++) { t[i]=malloc(m*sizeof(int)); for(i=0; i<n; i++) { for(j=0; j<m; j++) { t[i][j]=v++; for(i=0; i<n; i++) { free(t[i]); free(t); return 0;

Tárolási osztályok A C nyelvben lehetőségünk van a változók tárolási tulajdonságait befolyásolni úgy, hogy különböző "tárolási osztályokba" szervezzük őket. Egy változó tárolási osztályát hasonlóan tudjuk megadni, mint ahogy a méretét/előjelességét is, pl. const int a;. Ezek a típus elé írható módosítók bármilyen sorrendben szerepelhetnek, const unsigned short int a;, unsigned const short int a;, short unsigned const int a;, stb. mindegyike helyes. A használható tárolási osztályok: auto alapértelmezett, nem kötelező kiírni; akkor van értelme, ha hangsúlyozni akarjuk, hogy ez a változó nem különleges, pl. ha több static változó között deklaráljuk. register a fordító MEGPRÓBÁLJA a változót mindig a processzor egy regiszterében tartani, de akár figyelmen kívül is hagyhatja. Így a változó használata sokkal gyorsabb, ezért gyakran változó értékekhez hasznos. Viszont, mivel nincs memóriacíme, nem lehet pointert mutatni rá.

volatile a változó értékét "külső erők" is módosíthatják, például ha egy porthoz van rendelve. Elsősorban különböző driverek és egyéb hardverközeli programok írásakor hasznos. A program minden esetben a memóriából használja a változót, akkor is, ha már a cacheben, vagy egy regiszterben van. Emiatt kicsit lassabb lehet a kezelése. extern a változó deklarációja valahol máshol van, itt csak jelezzük, hogy létezik ilyen. Több modulra bontott programok globális változóihoz használatos, a header-fájlokban. const a változó értéke nem módosítható. Pointeres trükkökkel megkerülhető, csak annyit okoz, hogy a fordító hibát dob, ha egy értékadó művelet bal oldalán szerepeltetjük. static a változó a program futása során végig létezik és elérhető (míg egy hagyományos változó csak akkor, ha a program futása épp a változó blokkjában van). Például függvények lokális változóit szokás staticként deklarálni, így a következő függvényhíváskor a korábbi értéket érhetjük el.

F: Készíts egy pointert, ami egy konstans értékre mutat. F: Készíts egy konstans pointert, ami egy nem konstans értékre mutat. F: Készíts egy pointert, ami egy tömbre mutat. #include <stdio.h> int main() { const int *p=null; int * const c=null; int (*t)[20]; p=malloc(sizeof(int)); *p=2007; /* HIBÁS */ free(p); c=malloc(sizeof(int)); /* HIBÁS */ *c=2007; free(c); return 0;

Feladatok Adottak a const int a=100; int *p; deklarációk. Duplázd meg a értékét! Adottak az int *p, *q változók. A p=malloc(sizeof(int)); után mikor lesz érvényes a free(q); utasítás? Olvasd be egy számsorozat hosszát, majd az elemeit, és írasd ki őket úgy, hogy előbb a negatív, majd a nemnegatív elemeket sorolod fel. Az elemek sorrendje a negatív illetve nemnegatív blokkon belül az eredetihez képest ne változzon. A beolvasást egy void típusú függvény végezze! Hozz létre egy NxM-es mátrixot, ahol N és M értékét a felhasználó adja meg, majd olvasd be az elemeit, szorozd meg egy konstanssal, végül írd ki! Próbáld ki mindkét módszerrel (1D-s tömbben sorfolytonosan és valódi 2D-s tömbben)!

Feladatok Add meg két N-dimenziós vektor összegét. A program először bekéri a vektorok méretét, lefoglal egy megfelelő méretű dinamikus tömböt az eredmény tárolására, majd beolvassa az első vektort, végül hozzáadja a másodikat. (Ehhez nem kell külön tömböt foglalni, a második vektor elemeit egyesével hozzá tudod adni a tömb megfelelő elemeihez.) Ne felejtsd el a végén a memóriát felszabadítani! Hasonlíts össze két mátrixot! Először kérd be a méretüket, foglalj le két megfelelő méretű 2D-s tömböt a tárolásukra, majd kérd be az elemeiket. Végül számold meg, hány pozíción különböznek. Ha egyen se, írd ki azt is, hogy a mátrixok egyenlőek! Az egyik tömböt foglald le valódi 2D-sként, a másikat pedig 1D-s tömbben tárold sorfolytonosan! Ne felejtsd el a végén a memóriát felszabadítani!

Puzzle #include <stdio.h> Miért 50 a megoldás? int f(int *p){ *p = *p+8; return *p*4; int main(){ int a, b; a = 2; b = f(&a); printf("%d", a + b); printf("\n"); return 0;