Nem-OO nyelvi elemek
Dobra Gábor · 2019.02.27.
A mai óra célja a fontosabb nem-OO nyelvi elemek elsajátítása, és az OO előkészítése.
Felkészülés a gyakorlatra
- Jegyzet 1. fejezete
- Ajánlott a referenciákról szóló extra írás elolvasása
A gyakorlatvezető segítségével ismételjétek át a referencia fogalmát! Hogyan érdemes tekinteni a referenciákra? Mit szabad és mit nem szabad velük?
Összefoglaló
- A referencia nem egy pointer, hanem az eredeti változó maga (álnéven, fantomként, valami ilyesmi).
- A referencia nem lehet null.
- A referencia nem állítható át másik változóra.
- Ha az a kérdés, mit szabad egy referenciával, és mit nem, akkor "olyan, mint egy pointer", mert a háttérben mindig az van.
- A függvény dönti el, hogy a paramétereit érték vagy referencia szerint kéri.
- A referencia lehet balérték. Példa:
int& kisebb(int& a, int& b)
{
return a < b ? a : b;
}
int main()
{
int a = 5;
int b = 4;
kisebb(a, b) = 0;
std::cout << a << " " << b << std::endl;
}
A gyakorlatvezető segítségével ismételjétek át a const fogalmát! Mit jelent, mire vonatkozik, mire jó?
Összefoglaló
- A const arra vonatkozik, ami tőle balra van, kivéve amikor legbaloldalt van.
- A const nem feltétlenül azt jelenti, hogy az a változó nem változtatható meg, hanem hogy azon a néven nem változtatható meg.
- Tehát egy const bármikor rákerülhet egy változóra, de nem szedhető le róla kulturáltan.
- Pointereknél, pl.
const char* const
melyik const mit jelent (rajz), 4 lehetőség.char**
-nál már 8.
Referencia és const
használatával elkülönül egymástól a kódban az
X*
mint pointer / tömb,X&
mint változtatandó paraméter, ésX const&
mint drágán másolható paraméter.
A gyakorlatvezető segítségével ismételjétek át a függvény-overload fogalmát! Mit jelent, mikor melyik függvény hívódik?
Összefoglaló
- Ugyanazon a néven több függvény.
- A hívás helyén, a konkrét argumentumok döntik el, hogy mikor melyik.
- Ambiguous overload: nem egyértelmű, melyik kell.
Mi kell ahhoz, hogy az alábbi kód működjön? Írjuk meg a kisebb
függvényt!
void valami_C_szar(int * valami);
int main()
{
int a = 5;
int b = 4;
kisebb(a, b) = 0; // !
std::cout << a << " " << b << std::endl;
std::cout << kisebb(3, 4) << std::endl;
valami_C_szar(&kisebb(a, b));
}
Megoldás
int& kisebb(int& a, int& b)
{
return a < b ? a : b;
}
int const& kisebb(int const& a, int const& b)
{
return a < b ? a : b;
}
Feladat: kapunk két fájlnevet, a fájlok tele vannak valós számokkal. Mondjuk meg, hogy melyik számok szerepeltek mindkét fájlban!
Kiindulási alapnak vegyük azt az interfészt, amit Prog1 9. gyakorlatán megírtunk!
/* inicializalatlan strukturat hoz alapallapotba */
void halmaz_init(Halmaz *ph);
/* halmazt felszabadit az utolso hasznalat utan */
void halmaz_felszabadit(Halmaz *ph);
/* igazzal ter vissza, ha benne van az adott elem */
bool halmaz_benne_van_e(Halmaz *ph, double mi);
void halmaz_betesz(Halmaz *ph, double mit);
void halmaz_kivesz(Halmaz *ph, double mit);
/* kilistazza egy halmaz tartalmat */
void halmaz_kiir(Halmaz *ph);
Milyen lehetőségeink vannak az adatszerkezetre?
Megoldás
- Statikus tömb pl. 256 elemmel, rendezetlenül
- Dinamikus tömb, rendezetlenül
- Dinamikus tömb, rendezve
- Láncolt lista, rendezve vagy rendezetlenül. Az összes közül a legrosszabb ötlet.
- Bináris fa. Ez lenne a legjobb, de egy baj van, a
halmaz_kivesz
algoritmusa nem volt Prog1-en.
Válasszuk az első megoldást, mert még nem akarunk memóriakezeléssel foglalkozni (majd 3 hét múlva). Ha betelik a halmaz, lehet kivételt dobni, std::length_error
pont erre való.
struct Halmaz
{
int db;
double adat[256];
};
Alakítsuk ezt át, hogy használja az eddig megismert nyelvi elemeket!
Megoldás
Halmaz*
helyettHalmaz&
- Ahol lehet,
Halmaz&
helyettHalmaz const&
void halmaz_init(Halmaz& h);
void halmaz_felszabadit(Halmaz& h);
bool halmaz_benne_van_e(Halmaz const& h, double mi);
void halmaz_betesz(Halmaz& h, double mit);
void halmaz_kivesz(Halmaz& h, double mit);
void halmaz_kiir(Halmaz const& h);
A halmaz_felszabadit
így üres lesz, de a halmaz_init
-tel együtt maradjon meg párban, hogy könnyen át lehessen írni dinamikusra! Amennyi a malloc
, annyi a free
!
A fenti függvények felhasználásával írjuk meg a feladat megoldásához szükséges függvényeket, és a főprogramot!
Megoldás
Szükséges függvények:
void fajlok_metszete(char const *fajl1, char const* fajl2);
Halmaz halmaz_beolvas(char const * fajl);
Halmaz halmaz_metszet(Halmaz const& h1, Halmaz const& h2);
- Írd meg az alábbi függvényeket! Puskázhatsz a fent linkelt Prog1 gyakorlat megoldásaiból.
void halmaz_init(Halmaz& h);
void halmaz_felszabadit(Halmaz& h);
bool halmaz_benne_van_e(Halmaz const& h, double mi);
void halmaz_betesz(Halmaz& h, double mit);
void halmaz_kivesz(Halmaz& h, double mit);
void halmaz_kiir(Halmaz const& h);
- Alakítsd át a
Halmaz
típust és a függvényeit, hogy dinamikus tömbön dolgozzanak! - Alakítsd át a
Halmaz
típust és a függvényeit, hogy rendezett tömbön dolgozzanak! Melyik függvény mennyit gyorsul ezáltal?