Bevezetés a programozásba I. 9. gyakorlat Intelligens tömbök, mátrixok, függvények Surányi Márton PPKE-ITK 2010.11.09.
C++-ban van lehetőség (statikus) tömbök használatára ezeknek a méretét fordítási időben kell tudnia a fordítónak (mint PlanG-ban) Deklarálás: típus változónév[méret]; Pl: int tomb[5]; FONTOS! A méretnek konstans számnak kell lennie, tehát változó NEM lehet!
Példa használatra #include <cstdlib> int main() { srand( time(0) ); int array[10]; for (int i = 0; i < 10; ++i) { array[i] = rand() % 100; return 0;
Intelligens tömbök a statikus tömbök egyik fő hátránya, hogy nem változtatható a mérete, és a méretnek nem adható meg változó másik hátránya, hogy "nem tudja" a saját méretét, vagyis nem lehet lekérdezni ezért az STL (Standard Template Library)-ben van egy intelligens tömb, a vector.
std::vector a vector is az std névtérben található. használatához szükség van a vector header-re: #include <vector> deklaráláskor meg kell adnunk, hogy milyen típusú elemeket akarunk a vector-ban: std::vector<t> [változónév]; Ahol T a típus (int, double, string,... akármilyen típus lehet) a konstruktorban megadható, hogy mekkora legyen a kezdeti mérete: Pl: std::vector<t> array(15);
Deklarálás De megadható változó is (most például a konzolról olvassuk be a méretet): int size; std::cin» size; std::vector<t> array(size); Ha nem adunk meg méretet, akkor nulla lesz a mérete! Pl: vector<int> adatok;
Műveletek a konstruktorban megadható az elemek kezdőértéke is: Pl: vector<int> tomb(5,-3); Ez létrehoz egy 5 méretű tömböt, amiben int-eket tárolunk, és -3 lesz a kezdőértékük. a vektor egyes elemeit a [] operátorral érhetjük el: Pl: tomb[5] = 40; cout «tomb[7] «endl; (az indexelés itt is 0-tól indul)
Műveletek (folytatás) a vektort árméretezhetjük: tomb.resize(7); Ekkor 7 lesz a mérete (ez ugye azt jelenti, hogy 0 indextől 6-ig lesznek elemei) a méretét a length() vagy a size() tagfüggvénnyel kérhetjük le. Pl: for (int i = 0; i < tomb.size(); ++i) {
További fontos műveletek clear() : kiüríti a vector-t (tehát a mérete 0 lesz) Pl: tomb.clear(); push_back(kif); : a vector méretét eggyel növeli, így a végén lesz egy üres hely, és oda teszi a kif értékét. Pl: szamok.push_back(45); (ahol szamok egy int feletti vector) pop_back(); : a vector utolsó elemét kiveszi (csökken a mérete)
Megjegyzés Megjegyzés: for (int i = 0; i < tomb.size(); ++i) { Ha ezt lefordítjuk, akkor a fordító warning-ot ad: warning: comparison between signed and unsigned integer expressions A probléma, hogy előjeles és előjel nélküli típus között végzünk összehasonlítást.
Megjegyzés (folyt.) Egy módszer a kikerülésére: legyen előjel nélküli az i (unsigned int) for (unsigned int i = 0; i < tomb.size(); ++i) { De egy mégszebb megoldás, ha a vector size_type-ját használjuk: for (vector<t>::size_type i = 0; i < tomb.size(); ++i) { Ahol T értelemszerűen az a típus, amilyen típusú elemeket tárolunk a vector-ban. (Érdeklődőknek: iterator: http://www.cppreference.com/wiki/container/vector/begin)
Műveletek (folytatás) Érdemes átnézni a referenciát: http://www.cppreference.com/wiki/container/vector/start
std::vector - Példa Feladat: Olvassunk be a konzolról egész számokat, amíg nullát nem kapunk, és írjuk ki az átlagnál kisebb számokat. Specifikáció: BE: egész számok, amíg nullát nem kapunk KI: az átlagnál kisebb számok
#include <vector> #include <iostream> using namespace std; int main() { cout << "Kerem a szamokat! (vegjel:0)\n"; int be; vector<int> szamok; // nem adtunk meg cin >> be; // eloreolvasas while (be!= 0) { szamok.push_back(be); cin >> be;
// atlagszamolas: -> osszegzes: int sum = 0; for (size_t i = 0; i < szamok.size(); ++i) { sum += szamok[i]; double dsum = sum; double atlag = dsum / szamok.size(); // kiirjuk, ami kisebb az atlagnal: cout << "Atlagnal (" << atlag << ") kisebb elemek:" << endl; for (size_t i = 0; i < szamok.size(); ++i) { if (szamok[i] < atlag) { cout << szamok[i] << ", "; cout << endl; return 0;
Mátrixok dióhéjban Mátrixokat is hozhatunk létre: alapgondolat: mivel a T paraméter bármilyen típus lehet, miért ne lehetne vector? Pl: vector<vector<int> > matrix; Ekkor az indexelés: matrix[5][6];
Függvények Alprogramok programjaink írása során már többször előfordult, hogy ugyanazt, vagy hasonló kódrészletet írtunk, ezáltal többször kellett megírnunk ugyanazt, vagy átmásolni a kódot. az ismétlődő részeket kiemelhetjük, alprogramba tehetjük, és meghívhatjuk az alprogramot a főprogramból így áttekinthetőbb és egyszerűbb lesz a főprogram
Függvények Alprogramok amikor a főprogram futása elér egy alprogram-hívást, akkor a főprogram átadja a vezérlést az alprogramnak, majd ha az lefutott, akkor a vezérlés visszakerül a főprogramhoz Két fő fajtája van az alprogramoknak: eljárás: utasítássorozat függvény: végrehajt egy olyan számítást, utasítássorozatot, aminek van egy végeredménye. Ezt visszaadja a függvény. Ez a függvény visszatérési értéke.
Függvények Kommunikáció az alprogramokkal Két fő módja van a komminukálásnak: paramétereken keresztül (ez alapvetően egyirányú (a hívótól az alprogramnak), de később látjuk majd, hogy lehet kétirányú is) visszatérési értéken keresztül (ez inkább egyirányú (az alprogramtól a hívónak)) Egy alprogram megadásának két része van: deklarációs rész: megadjuk az alprogram (visszatérési) típusát, nevét, paramétereinek típusát, nevét törzs: megadjuk, hogy mit csinál az alprogram
Függvények A C++-ban csak függvények vannak, de lehet írni visszatérési érték nélküli függvényt is, ez nevezhető eljárásnak. Egy függvény deklarációja így néz ki: [visszatérési típus] [függvény neve]([paraméterek: [típus] [név] ] ) { Példa: [függvény törzse] int osszead(int a, int b) { return (a+b);
Függvények Használata Pl: main-en belül: cout «osszead(5,6) «endl; Ekkor az 5 és a 6 lemásolódik az a és b változókba, amik a függvény lokális változói. Lefut a függvény, és visszaad egy int értéket, majd ezt kiírjuk. Tehát: az osszead(29,45) egy kifejezés.
Függvények FONTOS: nem csak konstans érték, hanem változó illetve kifejezés is átadható a függvénynek! int x,y; cin» x» y; cout «osszead(x,y) «endl; De akár ezt is írhatnánk: int x,y,z; cin» x» y» z; cout «osszead(osszead(x,y),z) «endl;
Függvények int osszead(int a, int b) { return (a+b); itt a-t és b-t lokális változóknak nevezzük, mert ezek a változók csak az adott függvényen belül érvényesek, és láthatók. a return utáni utasítások nem fognak végrehajtódni, mert a return utasítás visszaadja a vezérlést a hívónak a return után egy kifejezés állhat, aminek a típusa meg kell, hogy egyezzen a függvény visszatérési típusával
Függvények Feladat Feladat: Feladat: Írjuk ki 20*20 csillagot a képernyőre. használjunk egy függvényt arra, hogy kiírjon egy sorban 20 csillagot, ez nyilván visszatérési érték nélküli lesz a főprogramban pedig meghívjuk ezt a függvényt 20-szor Specifikáció: BE: (nincs) KI: 20*20-as négyzet csillagokból
Függvények #include <iostream> using namespace std; // csillag fuggveny: // BE: (nincs) // KI: kiir 20 db csillagot void csillag() { for (int i = 0; i < 20; ++i) { cout << "*"; cout << endl; int main() { for (int i = 0; i < 20; ++i) { csillag(); return 0;
Függvények Fejlesszük tovább a feladatot, hogy n*n-es négyzetet írjon ki, n-et pedig kérjük be a felhasználótól!
Függvények #include <iostream> using namespace std; // csillag fuggveny: // BE: x: csillagok szama // KI: kiir x db csillagot void csillag(int x) { for (int i = 0; i < x; ++i) { cout << "*"; cout << endl; int main() { int n; cin >> n; for (int i = 0; i < n; ++i) { csillag(n); return 0;
Függvények Követekző órán... paraméterátadási módok függvények és vectorok együttműködése dekompozíciós feladatok
Függvények Feladatok V-1.cpp Véletlen tömb: egy tömb elemeit töltsd fel véletlenszámokkal. (A következő feladatok akár véletlennel, akár másképp feltöltött vektorokkal foglalkoznak) V-2.cpp Számítsd ki egy vektor átlagát! VI-2.cpp Valósítsd meg az int kozos(int a, int b) függvényt, ami a közös osztók számát adja vissza
Függvények Házi feladat V-3. Adjuk meg egy vektor szórását! V-4. Adjuk meg, hogy van-e két egyforma elem a vektorban! VI-11.cpp Valósítsd meg a void alahuzvakiir(string s) függvényt, ami a paraméterül kapott szöveget új sorba kiírja, és "=" karakterekkel aláhúzza!
Függvények Szorgalmi feladat szorgalmi_matrix.cpp Szorozz össze két N x N-es mátrixot! (N-et kérd be a felhasználótól, a mátrix elemei pedig vagy legyenek véletlen számok, vagy kérd be a felhasználótól) (Írasd ki mindkét mátrixot, és az eredményt is!) (Megjegyzés: érdemes függvény írni a kiíratáshoz) szorgalmi_sort.cpp Rendezd növekvő sorba egy vektor elemeit! (ne az STL-beli sort-ot használjuk )