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

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

8. gyakorlat Pointerek, dinamikus memóriakezelés

Programozás C és C++ -ban

Java II. I A Java programozási nyelv alapelemei

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

Maximum kiválasztás tömbben

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

Programozás C++ -ban

6. fejezet: Ciklusok

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

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

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

Java II. I A Java programozási nyelv alapelemei

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

Bevezetés a programozásba I.

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

Programozas 1. Strukturak, mutatok

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

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

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

OOP I. Egyszerő algoritmusok és leírásuk. Készítette: Dr. Kotsis Domokos

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

Occam 1. Készítette: Szabó Éva

A C programozási nyelv I. Bevezetés

A C programozási nyelv I. Bevezetés

Bevezetés a programozásba. 8. Előadás: Függvények 2.

Programozás I gyakorlat

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:

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

Programozás C++ -ban

3. Osztályok II. Programozás II

Programozás I gyakorlat

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

Pénzügyi algoritmusok

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

Programozási Nyelvek: C++

C++ programozási nyelv

Bevezetés a programozásba I.

1. Alapok. Programozás II

1. Egyszerű (primitív) típusok. 2. Referencia típusok

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

Pénzügyi algoritmusok

Informatika terméktervezőknek

9.fejezet: Függvények és külső eljárások

Bevezetés a programozásba. 9. Előadás: Rekordok

Bevezetés a programozásba II. 5. Előadás: Másoló konstruktor, túlterhelés, operátorok

C++ programozási nyelv Konstruktorok-destruktorok

ISA szimulátor objektum-orientált modell (C++)

Programozás I gyakorlat

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

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

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

Adatszerkezetek 1. Dr. Iványi Péter

OOP #14 (referencia-elv)

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

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

Mintavételes szabályozás mikrovezérlő segítségével

Webprogramozás szakkör

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

Programozási nyelvek II.: JAVA, 4. gyakorlat

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

Bevezetés a programozásba Előadás: A const

5. Gyakorlat. struct diak {

Memóriagazdálkodás. Kódgenerálás. Kódoptimalizálás

A C# PROGRAMOZÁSI NYELV

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

3. Gyakorlat Ismerkedés a Java nyelvvel

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

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

1. Öröklés Rétegelés Nyilvános öröklés - isa reláció Korlátozó öröklődés - has-a reláció

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

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

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

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

Smart Pointer koncepciója

1. Alapok. #!/bin/bash

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

Programozási nyelvek II.: JAVA, 4. gyakorlat

Javacript alapismeretek

5-6. ea Created by mrjrm & Pogácsa, frissítette: Félix

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

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

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ási nyelvek (ADA)

STL gyakorlat C++ Izsó Tamás május 9. Izsó Tamás STL gyakorlat/ 1

Bevezetés a programozásba Előadás: Objektumszintű és osztályszintű elemek, hibakezelés

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

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

1. Írjunk programot mely beolvas két egész számot és kinyomtatja az összegüket.

Programozási nyelvek Java

Operációs rendszerek. 11. gyakorlat. AWK - szintaxis, vezérlési szerkezetek UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

Statikus adattagok. Statikus adattag inicializálása. Speciális adattagok és tagfüggvények. Általános Informatikai Tanszék

Programozás alapjai gyakorlat. 2. gyakorlat C alapok

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

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

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

Programozási segédlet

Bevezetés a C++ programozásba

A C# programozási nyelv alapjai

Átírás:

7. fejezet: Mutatók és tömbök Minden komolyabb programozási nyelvben vannak tömbök, amelyek gondos kezekben komoly fegyvert jelenthetnek. Először is tanuljunk meg tömböt deklarálni! //Tömbök használata #define SPACE " " int main() cout <<"Ez o:t szamot ir ki...n "; int tomb [5] = 1,2,3,4,5; for (int szam = 0; szam<5; szam++) cout <<tomb[szam] <<SPACE; cout <<endl; A fenti egyszerű példából is jól látható, hogy maga a deklaráció semmi gondot nem okoz, mivel egyszerűen beírjuk a tömb típusát (jelen esetben: int), majd elnevezését (most: tomb), végül az egyes elemek számát (most: 5). Fontos, hogy a C++ esetén minden tömb a 0-ás index-szel kezdődik. Tehát a tömb egyes elemei: tomb[0], tomb[1],... Persze a deklaráció történhet külön-külön is. Erre példa a következő: //Tömbök használata 1 / 7

#define SPACE " " int main() int tomb[5]; cout <<"Ez o:t szamot ir ki...n "; for (int szam = 0; szam<5; szam++) tomb[szam] = szam*10; cout <<tomb[szam] <<SPACE; cout <<endl; Itt jól látható, hogy a tömb deklarációja már a main() függvény elején megtörtént, ám a konkrét értékeket csak menet közben adjuk meg (miután 10-zel megszoroztuk az index-et). Ezek, mint látható, csupán egydimenziós tömbök, azaz vektorok. Természetesen kellenek többdimenzi ósok is, azaz m átrixok. Lássuk példaként erre egy igen egyszerű tömböt, egy 10x10-es szorzótáblát! //Tömbök használata: szorzótábla #define SPACE " " int main() int tabla[11][11]; //Azért 11-es mindkét tömb indexe, mert így 1-től 10-ig lehet futtatni mindkét irányt cout <<"Ez egy 10x10-es szorzotablat ir ki:...n"; for (int xindex = 1; xindex<11; xindex++) for (int yindex=1; yindex<11; yindex++) tabla[xindex][yindex] = xindex*yindex; // Ez a tulajdonképpeni szorzás cout <<xindex <<"x" <<yindex <<"="; // Mit is akarunk összeszroozni? if (tabla[xindex][yindex]<10) cout <<SPACE; // Ha túl nagy lenne az eredmény, tesz eléje egy SPACE-t 2 / 7

cout <<tabla[xindex][yindex] <<SPACE; // Kiírja a szorzás eredményét cout << endl; // Sorok végét le kell zárni cout <<endl; Igen, tisztában vagyok azzal, hogy ezt simán meg lehet oldani tömbök nélkül is, de ez véleményem szerint egy tökéletes példa a tömbök használatára. Fontos, túl sok index használata veszélyes lehet, mert igen gyorsan túlterheli a memóriát. Vegyük például a következő tömböt: char century [100][365][24][60][60]; Mérete: 100*365*24*60*60 = 3 153 600 000 byte! Érdekesség, hogy a vektorokat az egyes alprogramok is elfogadják paraméterként. Lássuk például a következőt: // Vektor, mint paraméter void tombkiir (int arg[], int length) for (int n=0; n<length; n++) // Számláló ciklus 0-tól a ciklus hosszáig cout << arg[n] << " "; // A konkrét kiíratás cout << "n"; int tomb1[] = 5, 10, 15; int tomb2[] = 2, 4, 6, 8, 10; // Első tömb deklarálása // Második tömb deklarálása 3 / 7

tombkiir (tomb1,3); // Első tömb kiíratása tombkiir (tomb2,5); // Második tömb deklarálása Kicsit másképpen kell kezelni a mutatókat és egészen másképp kell értelmezni! Már láttuk, hogy a változókat, illetve az állandókat többféleképpen is el lehet érni a memóriában. A pointerek (mutatók) esetében nem kell azzal törődni, hogy hol is vannak a memóriában, hanem egyszerűen használhatjuk az azonosítójukat, ha rá akarunk utalni. Magát a számítógép memóriáját úgy is el lehet képzelni, mint egymás utáni cellák sorozatát, ha egy cella mérete 1-1 byte. Így minden egyes cella könnyedén azonosítható, mert van egyedi azonosító száma, melyet a következő azonosító számot tartalmazó cella követ. Például, ha az 1777-es cellát keressük, akkor pontosan tudhatjuk, hogy az 1776-os és az 1778-as között lesz megtalálható. 8. fejezet: Hivatkozási operátor (&) Amint egy változót deklaráltunk, a szükséges memória címét azonnal hozzárendeljük. Szerencsére nem nekünk kell gondoskodni arról, hogy fizikailag hol is helyezkedjen el magában a memórián belül, mivel ezt a rendszer automatikusan elvégzi helyettünk. A cím, amely meghatározza egy változó memórián belüli címét, ez lesz a hivatkozási (referencia) operátor. Ezt változóra való hivatkozást meg kell előzni egy változó előtti jellel (&), ami az angol nyelvű és rövidített jele. Például: ted = &andy; A pointereket három különféleképpen lehet deklarálni, mégpedig a következő típus szerint: típus * name; Ezek konkrét megvalósítása: 4 / 7

int * number; char * character; float * greatnumber; Ezek sorban: egész, karakter, illetve float típusú változó. Szeretném kihangsúlyozni, hogy a csillag-jel (*), amit a deklarációhoz használunk, csupán azt jelenti, hogy egy pointer-típusú változó következik, semmi mást! Most jöjjön mintaképpen egy kód-részlet: andy = 25; // Itt értéket adunk az andy változónak. Ez legyen 25. Az andy memória-beli helye legyen: 1776. (Ezt a gép adja!) fred = andy; // Ezzel felveszi a fred nevű változó az andy értékét, azaz a 25-öt. ted = &andy; // A ted nevű változó viszont az andy memóriahelyét mutatja, ami lehet valami egész más, pl.: 1776. Teljes kóddal: // Pointer int andy, fred; int * ted; andy = 25; // Itt értéket adunk az andy változónak. Ez legyen 25. Az andy memória-beli helye legyen: 1776. (Ezt a gép adja!) fred = andy; // Ezzel felveszi a fred nevű változó az andy értékét, azaz a 25-öt. ted = &andy; // A ted nevű változó viszont az andy memóriahelyét mutatja, ami lehet valami egész más, pl.: 1776. cout <<andy <<endl; cout <<fred <<endl; cout <<ted; 5 / 7

Egy másik lehetőséges pointer-műveletet tesz lehetővé a csillag (*). Nézzük a következőt: beth = *ted; Ezt a következőképpen kell olvasni: beth egyenlő a ted-re mutató pointerrel értékével. Íme egy egyszerű eset: beth = ted; // beth egyenlő a ted-del ( 1776 ) beth = *ted; // beth egyenlő a ted-re mutató értékkel ( 25 ) Szeretném felhívni a figyelmet a két különböző fenti lehetőség közti különbségre: &: egy hivatkozási operátor és úgy kell olvasni, hogy "a... címe" *: vissza-hivatkozási operátor és úgy kell olvasni, hogy "a... pointer értéke" Így talán jobban láthatók, hogy ezek gyakorlatilag egymás ellentétei. Legyen most egy újabb kódrészlet - érdemes lefuttatni! //További pointerek int elsoertek = 5, masodikertek = 15; int * p1, * p2; // pointerek deklarálása p1 = &elsoertek; // p1 = az elsoertek címe p2 = &masodikertek;// p2 = a masodikertek címe cout <<"A p1 jelenlegi erteke: " <<p1 <<endl; cout <<"A p2 jelenlegi erteke: " <<p2 <<endl; *p1 = 10; // p1 pointer értéke legyen *p2 = *p1; // A p2 pointer értéke legyen a p1 pointer értéke p1 = p2; // p1 értéke legyen p2 *p1 = 20; // A p1 pointer értéke legyen 20 cout << "Az elso: ertek : " << elsoertek << endl; cout << "A masodik ertek: " << masodikertek << endl; 6 / 7

Mivel a dolog még zavaros lehet, ezért jöjjön még egy példa: // További pointerek int numbers[5]; // Inicializáljuk a numbers vektort int * p; // Inicializáljuk a p pointert p = numbers; *p = 10; // A p értéke legyen azonos a numbers-szel. A p pointer értéke legyen 10. p++; *p = 20; // Növeljük meg a p-t eggyel. A p pointer értéke legyen 20. p = &numbers[2]; *p = 30; // A p legyen a numbers[2] címe, a p pointer értéke pedig legyen 30. p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", "; // Ez pedig a kiírás A kiírás a következő lesz: 10, 20, 30, 40, 50 Még valami: tapasztalatból tudom, hogy a pointerek sokaknak zavarosak. Igen, ez így szokott lenni. Az emelt szintű felvételi legtöbb feladatsorát meg lehetett ezen rész nélkül is írni, de persze jóval könnyebb ezzel. Érdemes rajta gondolkozni! Folytatás itt! 7 / 7