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

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

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

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

C programozási nyelv

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

Programozás alapjai gyakorlat. 2. gyakorlat C alapok

Programozás I. gyakorlat

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

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

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

8. gyakorlat Pointerek, dinamikus memóriakezelés

Programozás C és C++ -ban

5. gyakorlat. Konstansok Tömbök Stringek

C programozás. 1 óra Bevezetés

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

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 alapjai C nyelv 7. gyakorlat. Függvények. Függvények(2)

Programozás C++ -ban

Bevezetés a programozásba I.

1. Bevezetés szeptember 9. BME Fizika Intézet. Szám. szim. labor ea. Tőke Csaba. Tudnivalók. feladat. Tematika. Moodle Házi feladatok

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

3. Osztályok II. Programozás II

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

Dr. Schuster György október 14.

A C programozási nyelv I. Bevezetés

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

Programozás I gyakorlat

7. gyakorlat Sorozatok, Fájlkezelés

Vezérlési szerkezetek

Programozás C++ -ban

Láncolt lista. az itt adott nevet csak a struct deklaráción belül használjuk

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.

A C programozási nyelv I. Bevezetés

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

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

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

Dinamikus csatolású függvénykönyvtár készítése és használata Plugin-szerű betöltés Egyszeű C++ osztályok készítése

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

Programzás I gyakorlat

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

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.

C++ programok fordítása

Alprogramok, paraméterátadás

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

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

Gregorics Tibor Tanácsok modularizált programok készítéséhez 1

Programozás I gyakorlat

7. gyakorlat. Fájlkezelés IO haladó Függvények haladó

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

1. Alapok. Programozás II

Vezérlési szerkezetek. Szelekció Ciklusok

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

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

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Függvények. Dr. Bécsi Tamás 6. Előadás

A függvény kód szekvenciáját kapcsos zárójelek közt definiáljuk, a { } -ek közti részt a Bash héj kód blokknak (code block) nevezi.

4. Laborgyakorlat. A fájlokról ezeket az adatokat, a fájlrendszer tárolja. Számunkra az 1, 3, 4. oszlopok lesznek az érdekesek.

Programozás alapjai C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

Bevezetés a programozásba Előadás: Fordítási egység

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

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

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

Elemi alkalmazások fejlesztése I. Olvassunk be egy fájlból egész számokat egy tömbbe. Keressük meg a tömb valamely

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

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

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

Programozás I gyakorlat

Adatbázis Rendszerek II. 5. PLSQL Csomagok 16/1B IT MAN

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

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

Programozás C++ -ban 2007/1

II. Mérés SZÉCHENYI ISTVÁN EGYETEM GYŐR TÁVKÖZLÉSI TANSZÉK

OOP #14 (referencia-elv)

Óbudai Egyetem. C programozási nyelv

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

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

BASH SCRIPT SHELL JEGYZETEK

C programozási nyelv

Programozás alapjai II. (1. ea) C++

Programozás alapjai II. (1. ea) C++

és az instanceof operátor

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

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

GPU Lab. 5. fejezet. A C++ fordítási modellje. Grafikus Processzorok Tudományos Célú Programozása. Berényi Dániel Nagy-Egri Máté Ferenc

Operációs rendszerek. 9. gyakorlat. Reguláris kifejezések - alapok, BASH UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

1. Alapok. #!/bin/bash

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

A C# programozási nyelv alapjai

Informatika terméktervezőknek

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

BASH script programozás II. Vezérlési szerkezetek

Gregorics Tibor Modularizált programok C++ nyelvi elemei 1

INFORMATIKA javítókulcs 2016

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

Programozási Nyelvek: C++

Cekla. Készítette Doxygen Tue Sep :13:44

Operációs rendszerek. 9. gyakorlat. BASH recap, reguláris kifejezések UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

Webprogramozás szakkör

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

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

Python tanfolyam Python bevezető I. rész

Átírás:

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

Házi (f0174) Egy sor kiíratási formátuma: "nev: %s; pont: %d;". Olvasd be a kiírt számot úgy, ha tudod, hogy a kiírt sztring nem tartalmazhat pontosvesszőt, de bármi mást igen. Ellenőrizd le, hogy az input sor valóban helyes-e. Módosítsd úgy a programot, hogy az stdin és stdout fájlokat, valamint a fscanf és fprintf függvényeket használja. Módosítsd úgy a programot, hogy valódi fájlokat használjon. Hibaüzenettel és hibakóddal lépjen ki a program, ha valamelyik fájl megnyitása nem sikerült.

Felsorolás - Enum C-ben létrehozhatunk egy olyan adattípust, aminek mi határozzuk meg az értékkészletét (tehát azt, hogy milyen értékeket vehet fel) Ezt az elemek felsorolásával tehetjük meg Később ilyen típusú változóknak a felsorolt értékeket adhatjuk értékül A rendezés relációt a felsorolás sorrendjével definiáltuk Alakja enum <név> { elem1, elem2,, elemn } [változó];

Felsorolás - Enum #include <stdio.h> Hasznos, ha nem számként szeretnénk bizonyos értékeket tárolni, de szeretnénk, ha lenne köztük rendezés reláció Pl. hét napjai, érdemjegyek int main() { enum het { Hetfo, Kedd, Szerda, Csutortok, Pentek, Szombat, Vasarnap } nap; for(nap=hetfo; nap <= Vasarnap; nap+ +) { } printf("%d\n", nap); return 0; }

Felsorolás - Enum Az enum típus értékei valójában egész számokra képződnek le (így biztosított a rendezés) Alapesetben 0-tól indulnak az értékek és egyesével nőnek Ezt felülírhatjuk úgy, ha valamelyik érték mellé értékadást írunk Pl. enum het { hetfo = 5,... }; #include <stdio.h> int main() { enum het { Hetfo = 1, Kedd, Szerda, Csutortok, Pentek, Szombat, Vasarnap } nap; for(nap=hetfo; nap <= Vasarnap; nap++) { } printf("%d\n", nap); Ekkor ez az érték kapja ezt a számot értékül, a többiek pedig innen nőnek egyesével } return 0;

Feladat (f0150) Vizsgáld meg az enum.c programot. Javítsd ki a kovetkezo() függvény módosításával úgy, hogy az első kiírás (az év első tíz napja) helyes legyen! És most javítsd ki a második ciklust (a hét napjai), hogy ne legyen végtelen ciklus! Ha kell használhatsz másfajta ismétlést is! Mi történik, ha Hetfo = 1 -ként adod meg az enum het típus első elemét? Mi történik, ha Szombat = 10 -ként adod meg a hatodik elemet? Tudod-e az enum több elemének is ugyanazt az értéket adni? Mi történik, ha mindegyiknek ugyanazt adod?

Feladat (f0154) Módosítsd úgy, hogy az enum kulcsszó csak egyszer szerepeljen benne, de a program lényegében ne változzon meg! A megvalósításhoz nem használhatsz #define-t! Tipp: volt valami ilyesmi a struktúráknál is...

Preprocesszor makrók Létrehozhatunk makrókat, amit a preprocesszor (előfeldolgozó) dolgoz majd fel Ez a fordítás előtt történik, tehát még fordítás előtt módosíthatjuk vele a kódot Ezt a már ismert #define utasítással lehet Egy makrónak van neve és értéke, lehetnek paraméterei is Az értékre nincs semmi megkötés, mivel egyszerűen csak bemásolódik

Preprocesszor makró példák #define DEBUG Itt nincs értéke, csak létrehoztunk egyet #define N 3 Ezt már ismerjük, van neve és értéke is #define NL printf("\n") A makró értéke egy parancs, ezt fogja behelyettesíteni

Feladat (f0151) Vizsgáld meg a preproc.c programot Hol jelez hibát a fordító? Mi lesz, ha elhagyjuk a main függvény elől az int-et? Vizsgáld meg a preprocesszált állományokat. Mit tapasztalsz? Miért működik az egyik, és miért nem a másik verzió? (A preprocesszált fájlokat a gcc -E kapcsolójával tudod előállítani, ami a standard kimenetre ír, tehát érdemes lehet a kimenetet a shell-ben egy.i kiterjesztésű fájlba irányítani.)

Paraméteres PP makrók Van neve, paramétere és értéke Ahova a nevet írtuk, oda behelyettesíti az értéket (mint eddig), de a paramétereket is #define MIN(X,Y) ( (X)<(Y)? (X) : (Y)) Tehát ha valahova ezt írjuk, hogy printf("%d", MIN(a+b, a+c)); A fordítóhoz ez jut már el: printf("%d", ( (a+b) < (a+c)? (a+b) : (a+c) ));

Paraméteres PPmakrók A zárójeleket ne hagyjuk le, mert a PP nem gondolkodik, csak másol és így más lehet a jelentése. Pl. #define negyzet(x) X*X negyzet(a) -> a*a negyzet(a-1) -> a-1*a-1 Csak rövid, egyszerű dolgokra használjuk Nézzük meg a maximum, minimum megállapító makrókat, valamint a minimum megállapítót három paraméter esetén! 02_ppmakro.c

Feladat (f0260) Készíts egy-egy paraméteres makrót egy szám négyzetének, két szám minimumának, maximumának, valamint négy szám minimumának és maximumának kiszámolására. Nézzük meg preprocesszálás után, fordítás előtt a kódunkat! gcc -E prep.c > prep.i

Makró fordításkor Fordításkor is definiálhatunk makrókat, nem csak a programkód elején gcc -Dnev=ertek

Feltételes fordítás Egy makrót a #undef nev utasítással tudunk törölni, innentől kezdve nem él ez a makró Vannak olyan preprocesszor utasítások, amik kihagynak a fordításból bizonyos kódrészleteket, ha egy adott feltétel teljesül.

Feltételes PP utasítások #if ha egy feltétel teljesül, akkor lefordítjuk az utána lévő részt #elsif ugyan olyan, mint az else if, csak itt így kell írni #else else ág, ha a hozzá tartozó if nem teljesült #endif feltételvizsgálat vége, az if és endif közötti részre vonatkozik a feltétel #ifdef ha a makró definiált, akkor igaz #ifndef ha a makró nem definiált, akkor igaz

Feladat (f0269) Írj egy programot, ami egy láncolt listába olvas be egész számokat egy konstansként megadott végjelig, majd fordított sorrendben kiírja a beolvasott értékeket. Ha a program fordításkor a -DDEBUG kapcsolót kapja, akkor a beolvasás és kiírás során is írja ki az aktuális listaelem és a következő listaelem címét.

Tárolási osztályok C-ben lehetőségünk van módosítani a változók tárolási osztályát, ezzel befolyásolva a tárolási tulajdonságot (pl. élettartam, érvényességi kör) Ezt a változó típusa elé írt módosítóval tehetjük meg, mint pl. a méretét vagy az előjelét, ezeknek a sorrendje mindegy

Tárolási osztályok auto alapértelmezett, ha nem írunk semmit, akkor ezt a tárolási osztályt használja. Akkor célszerű kiírni, ha sok más változónál módosítjuk az alapértelmezést, akkor ezzel nyomatékosíthatjuk, hogy ez viszont változatlan. register a program megpróbálja a regiszterben tartani a változó értékét, ezáltal gyorsabb lesz a program, viszont nem használhatunk pointereket rá (a regiszterben tartásra nincs garancia) volatile gyakran változó értékű változók esetén hasznos, mindig a memóriából olvassa ki az értéket, még akkor is, ha cachelve van vagy a regiszterben van. Így kicsit lassabb lesz, de mindig az aktuáis értéket kapjuk extern valahol máshol deklaráltuk a változót, de itt is érvényes. Több modulból álló program esetén hasznos

Tárolási osztályok const konstans, az értéke nem változtatható. Pointerekkel megkerülhető, de nem állhat értékadás bal oldalán static a program indulásakor lesz lefoglalva, és a program futásának végén szabadul fel, így megőrzi az értékét. Pl. függvényeknél elérhetők a korábbi futások eredményei

Feladat (f0219) Vizsgáld meg a tarolas.c programot! Minimális változtatással tedd fordíthatóvá! Mi történik, ha a counter() függvényben kihagyod a static módosítót? Nézd meg a kiírt címeket! Változtasd meg a nemvaltozo értékét úgy, hogy a deklarációját nem módosíthatod!

Konstans pointerek Pointerek is lehetnek konstansok két módon const int *p = NULL; //amire mutat, az nem változik, de mutathat máshova int * const c = NULL; //nem mutathat máshova, de ahova mutat, ott változhat az érték

Feladat (f0220) Fordítsd le a deklaraciok.c programot! Milyen hibákat tapasztalsz fordítás közben? Javítsd ki! Ezek után futás közben miért száll el a program? (Ha nem teszi, növeld meg N értékét, és próbáld megválaszolni azt is, hogy kisebb értékkel miért nem szállt el!)

Parancssori paraméterek A linux alapoknál láthattuk, hogy az egyes programoknak paraméterben adhatjuk át az értéket, amin dolgozni szeretnénk. Ugyanez C-ben is megvalósítható. Az így adott paramétereket a main függvény paramétereként láthatjuk. Ekkor a main függvényt a következőre kell módosítani int main(int argc, char *argv[]) vagy int main(int argc, char **argv) vagy int main(int argc, char **argv, char **envp)

Parancssori paraméterek int main(int argc, char **argv) argc: bemenetként kapott paraméterek száma (0. a program neve) argv: egy stringeket tároló tömb (azaz stringeket tartalmazó memóriaterületek címeit tartalmazó tömb), itt vannak a paraméterek, pontosan argc darab int main(int argc, char **argv, char **envp) argc és argv ugyan az, mint az előbb envp: környezeti változók tömbjei. Ennek nem kapjuk meg a méretét, az utolsó elemet végejellel, azaz NULL pointerrel jelöljük

Feladat (f0240) Írj egy programot, ami összeadja a parancssorban kapott valós számokat, és kiírja az összegüket. Figyelem: a számokat most stringként (char*) kapjuk!

Feladat (f0237) Egészítsük ki úgy az előző órai kép invertálós programot, hogy a képeket fájlból olvassuk és fájlba írjuk, a fájlok nevét pedig a program paramétereként kell megadni.

Moduláris programozás Egy bizonyos programméret felett már érdemes logikai egységekre bontanunk a programunkat Könnyebb munkamegosztás Könnyebb bővítés, fejlesztés Forráskód áttekinthetőbb és újrafelhasználható lesz C-ben ezt modulokkal valósíthatjuk meg Minden modul egy header (.h) és egy source (.c) fájlból áll Kell lennie pontosan egy modulnak, amiben a main függvény lesz, ennek nem lesz headerje

Moduláris programozás Ha egy forrásban használni szeretnénk egy másik modult, akkor a header fájlt be kell includeolni hozzá Ha nem a rendszer include könyvtárában lévő headert szeretném használni, akkor <sajat.h> helyett sajat.h alakban kell írni a header nevét Forrásfájlokat sosem szabad includeolni, csakis header fájlokat!

Moduláris programozás Header fájlba kerül a modulunk interfésze Deklaráljuk a függvényeket (de nem szabad itt definiálni, tehát a függvény törzs a forrásba megy majd), azaz leírjuk a függvény prototípusát Definiáljuk a konstansokat, típusokat, globális változókat (ezeknél használni kell az extern tárolási osztályt) Nem szabad egy headert többször includeolni ugyan oda, ezt feltételes PP makrókkal biztosíthatjuk A forrás fájlba kerülnek a függvény definíciók és a globális változók, nem externként

Moduláris programozás Fordításkor meg kell adnunk az összes forrásfájlt Header fájlokat nem Ebből egy futtatható állomány lesz Létrehozhatunk a modulokból függvénykönyvtárakat. Ekkor nem kell main függvényt tartalmazó modul, hanem csak a modulokat lefordítjuk egyesével, és object fájlokban tároljuk. Ekkor az implementációnk rejtve marad, de mégis máshol felhasználható Header fájlban csak akkor includeoljunk, ha muszáj, sok kavarodás történhet.

Moduláris programozás Nézzünk meg egy moduláris programot! lib.h a modul header fájlja lib.c a modul source fájlja libmain.c a main modul Fordítás egyenként, majd linkelés gcc -Wall -pedantic -c lib.c gcc -Wall -pedantic -c libmain.c gcc -Wall -pedantic -o lm lib.o libmain.o Fordítás és linkelés egyben gcc -Wall -pedantic -o lm lib.c libmain.c

Feladat (f0262) Hozz létre egy típust háromdimenziós pontok tárolására. Készíts egy függvényt, ami két ilyen térbeli pont távolságát adja vissza, valamint egy függvényt, ami három oldalhossz alapján kiszámolja egy háromszög területét. A fenti programelemekből készíts egy modulként használható lib.h és lib.c párost. Ezek után írj egy tetra.c nevű programot ami négy háromdimenziós koordináta-hármasból kiszámítja egy pontok által határolt térrész (egyfajta szabálytalan "tetraéder", oldalaikkal és csúcsaikkal érintkező négy háromszög által határolt test, melynek csúcsai a megadott pontok) felszínét. A szükséges adatokat a program parancssori paraméterként kapja meg.

Továbbiak Jövő héten nagy ZH Utána héten nagy ZH újraírási lehetőség (bárki megírhatja, de minden esetben az új pontszám fog élni)