10. gyakorlat¶
7. ZH¶
A gyakorlat elején 45 percben kerül megírásra a 7. zh. A feladatok témái:
- algoritmus elkészítése
- tömbökkel megoldható feladatok
- önálló függvények megírása (bemenet/kimenet kezelés nélkül)
- szemantikus hibajavítás: szintaktikailag helyes, de rosszul működő függvény(ek) kijavítása
Haladó IO¶
A printf
és scanf
függvényeket (illetve ezek fájlkezelő verzióit) eddig csak éppen használgattuk, egyszerű értékek beolvasására illetve kiírására.
A kiíratásnál már láthattuk, hogy a printf
azért elég "okos", sok mindent tud.
Érdemes viszont ezeket a függvényeket alaposabban ismerni, mert van pár probléma, aminek a megoldásában sokat segíthetnek.
Feladat (f0161)
Feladat:
Készíts egy programot, ami tízes számrendszerbeli alakban beolvas egy előjeltelen egész értéket, és nyolcas számrendszerbe átváltva kiírja azt. Minél nagyobb számokat tud kezelni, annál jobb.
Segítség
Gondolkozz egy pár percet, mielőtt megnéznéd az alábbi ötleteket, mert lehet, hogy magadtól is rájössz egy megoldásra. Segítségképpen egy jótanács: az egész típus C-ben elemi adattípusnak számít, az értéke nem felbontható! Ez azt jelenti, hogy a tárolt érték nem egy 10-es vagy 2-es vagy akárhanyas számrendszerbeli szám, hanem "csak" egy szám (ami éppen a számítógépek fizikai adottságai miatt kettes számrendszerben van tárolva). A szám 10-es vagy 8-as számrendszerbeli alakja pedig egy számleírás, egy karaktersorozat, egy sztring. Vagyis, beolvasáskor egy 10-es számrendszerbeli számleírást (karaktersorozatot) kell számmá alakítani, kiíráskor pedig egy számot kell 8-as számrendszerbeli számleírássá (karaktersorozattá) alakítani.
1. ötlet
Használjuk ki, hogy ha egy n
számot valamilyen a
számrendszerben szeretnénk leírni,
akkor a leírás utolsó számjegyét megkapjuk az n % a
művelettel, az előző számjegyeket
(már ha vannak) pedig úgy, hogy az n / a
számot leírjuk az a
számrendszerben. Vagyis
a számjegyeket fordított sorrendben kapjuk meg, így előbb mondjuk egy karaktertömbben kell
eltárolni őket, és ha mind megvan, akkor lehet kiíratni (megfelelő sorrendben). A
karaktertömb mérete legfeljebb akkora, ahány számjegy a legnagyobb adott típuson
ábrázolható számhoz szükséges. Ez az algoritmus bármilyen a
számrendszer esetén
működik.
Lehetséges megoldás (m0161-1.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
|
2. ötlet
Gondoljuk végig, mit tud a scanf()
és printf()
. Milyen számokat tud beolvasni illetve
milyen formátumokban tud kiírni? Lehet, hogy a 10-esből 8-asba váltásra van egy, az
előzőnél (legalábbis C programozói szinten) egyszerűbb megoldás is?
Lehetséges megoldás (m0161-2.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
Feladat (f0174)
Feladat:
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
ésstdout
fájlokat, valamint afscanf
ésfprintf
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.
Segítség
Figyelj a feladatra: csak a sorszámot kell beolvasni, de előtte még van egy csomó karakter.
Hogyan működik a scanf
?
Ha a formátumsztringben egy fix karakter van (azaz nem valami %
-kal kezdődő konverziós specifikáció), akkor azt megpróbálja beolvasni, és ha nem sikerül, nem megy tovább.
Vagyis a printf
-ben használt formátumsztring jó kiindulási alap, hiszen a fix karakterei egyeznek a beolvasandó soréval.
A %s
-sel ugyanakkor bármilyen sztringértéket ki tudunk írni, míg beolvasáskor egy egybefüggő, whitespace karaktereket nem tartalmazó karaktersorozatot fog beolvasni.
Vagyis pl. a "Hello Vilag!"-ból csak a "Hello"-t, ugyanakkor a "pontos;vesszo"-t teljesen beolvasná.
A feladat szerint itt egy ';'
-t nem, de bármi mást esetleg tartalmazó karaktersorozat áll.
Nézd meg, előadáson hogyan oldottuk meg mondjuk egy szám beolvasása után sor maradék részének "lenyelését".
És honnan fogjuk tudni, hogy sikerült-e beolvasni a számot?
A scanf
visszatérési értéke fogja megmondani, hogy hány értéket sikerült beolvasni.
Jelen esetben ennek 1-nek kell lennie.
Lehetséges megoldás (m0174-1.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Segítség
Ez egyszerű: a scanf(...)
-ből fscanf(stdin, ...)
, a printf(...)
-ből printf(stdout, ...)
lesz.
Lehetséges megoldás (m0174-2.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Segítség
Ilyet már csináltál: kell hozzá két FILE*
típusú változó az stdin
és stdout
helyett,
a fájlokat használat előtt meg kell nyitni az fopen()
függvény segítségével,
használat után pedig le kell zárni az fclose()
-zal.
Ha az fopen()
egy NULL
értékkel tér vissza, az bajt jelent.
Lehetséges megoldás (m0174-3.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
Pointer haladó¶
Feladat (f0186)
Feladat:
Fordítsd le és futtasd a linkedlist.c
programot. Ez egy láncolt listába
olvas be egész számokat egy adott végjelig. Módosítsd a programot, hogy
kiíratáskor kiírja a cella címét, a cella két mezőjének címét és azok
értékét is. Hasonlítsd össze a cellák címeit a kov
mezők értékeivel.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
|
Lehetséges megoldás (m0186.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
Válaszok (f0186)
Egy-egy cella címe megegyezik az előző cella kov
mezőjének értékével.
Az ertek
mezők címei megegyeznek az őket tartalmazó cella címeivel,
míg a kov
mezők címei ennél mindig ugyanannyival (sizeof(int)
-tel,
ami manapság igen nagy valószínűséggel 4 lesz) nagyobbak.
Feladat (f0261)
Feladat:
Í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.
Ötlet
Érdemes az előző feladatból kiindulni. Ha a listába eleve fordítva tesszük bele az elemeket, akkor a kiíratás mehet ugyanúgy előre, mint abban. A trükk: az új elem mindig a lista kezdőeleme lesz, és e mögé fűzzük oda az eddigi listát.
Lehetséges megoldás (m0261.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
|
Függvény pointerek¶
A pointerek mutathatnak nem csak adatra, de algoritmusra, C esetében függvényekre is. Ez azt jelenti, hogy futásidőben tudjuk kiválasztani, hogy (azonos visszatérési típusú és paramétereket váró) függvények közül melyik hívódjon egy adott ponton. A függvény pointer típusú változó deklarációja olyan, mint a függvény deklaráció, csak a szimpla függvénynév helyére egy pointerdeklarációt rakunk (amit a precedencia miatt külön zárójelezünk):
int (*fgv_ptr)(int, int);
Ha mindez elé kiírjuk a typedef
kulcsszót is, akkor a megadott név a függvény pointer típust fogja azonosítani:
typedef int (*fgv_t)(int, int);
Egy-egy függvény neve önmagában a függvényre mutató pointert jelenti.
(Ezért van, hogy ha meg akarjuk hívni, akkor üres paraméterlista esetén is ki kell tenni a ()
zárójelpárt, különben csak egy függvény pointer értéket eredményező kifejezést kapunk.)
Vagyis, ha egy függvény pointernek értéket szeretnénk adni, egyszerűen értékül adjuk neki a függvényt anélkül, hogy a ()
használatával meghívnánk azt.
Ha pl.
1 2 3 |
|
fgv_ptr = osszead;
értékadás a fgv_ptr
számára.
(A fgv_ptr = osszead(...);
viszont értelmetlen, mert meghívná a függvényt, ami nep pointert, hanem int
-et ad vissza.)
Ezek után ha meghívjuk a függvényt a fgv_ptr
-en keresztül, akkor valójában az osszeg
-et hívjuk:
x = fgv_ptr(3, 5);
A függvénypointerek megértését segítheti a következő videó, mely a függvény pointerek alapjait mutatja be:
Feladat (f0282)
Problémafelvetés:
Készíts egy programot, amely egy tetszőleges nagyságú (maximum 9999 jegyű) számról a jól ismert oszthatósági szabályok felhasználásával eldönti, hogy a szám osztható-e egy [2..12] intervallumba eső számmal.
Specifikáció:
A program inputja egy 2 és 12 közötti egész szám, majd szóközzel elválasztva egy legfeljebb 9999 jegyű egész szám. A program outputja egy egyszerű "Igen" vagy "Nem" attól függően, hogy a második szám osztható-e az elsővel.
Algoritmustervezés/Megvalósítás:
A programban a megfelelő oszthatóságot ellenőrző függvényt egy függvény pointeren keresztül hívjuk meg.
Segítség
Érdemes a 6. gyakorlat f0166-os feladatának megoldásából kiindulni.
Lehetséges megoldás (m0282.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
|
A függvény pointerek mélyebb megértést segítheti a függvény pointerek használata a beszúró rendezéshez:
A következő videó pedig a függvény pointereket használja egy számológép megvalósításához:
Látványos feladatok¶
Feladat (f0231)
Problémafelvetés:
Invertálj egy PGM képet, azaz minden képpont intenzitását változtasd az ellenkezőjére (így pl. feketéből fehér, világosból sötét lesz, mint a fotónegatívokon)!
Specifikáció:
A program inputja egy (egyszerűsített) PGM formátumú kép. A PGM formátum egy
szürkeárnyalatos képet ír le a következő formában. A PGM fájl első sora a
P2
szöveg; a második sortól kezdve egész értékeket tartalmaz whitespace
karakterekkel (szóköz, tabulátor, sortörés, stb.) elválasztva. Az első két
érték X és Y, a kép szélessége és magassága, a harmadik M, a képpontok
lehetséges maximális értéke. Ezt további X*Y darab [0..M] intervallumba eső
érték követi, az egyes képpontok intenzitásértékei, sorfolytonosan megadva.
A kimenet egy PGM formátumú kép, az eredeti kép inverze.
Példa input fájlok: torony-o.pgm, progalap.pgm.
1. ötlet
Van egy célorientált, egyszerű megoldás. Gondoljuk végig, mit is kell csinálni? Az input elején van egy "P2\n" sor, ez fix beolvasásnál és kiírásnál is. Ezután van valamennyi egész szám: legalább 3 darab, és az első kettőből kiszámolható, hogy még mennyi. És a kimenet mi lesz? Ugyanúgy a "P2\n" sor, utána pedig ugyanannyi szám, mint amennyit beolvastunk. Az első 3 szám változik? Nem, amint beolvastuk, akár ki is írhatjuk őket. Az utánuk következő számok változnak? Igen, de amint megvan a szám, egyből ki tudjuk belőle (és a 3. számból) számolni, hogy mit kellene kiírni, és ki is írhatjuk.
Lehetséges megoldás (m0231-1.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
2. ötlet
Van egy "szép" megoldás is: csinálunk egy adattípust (struktúrát) a kép tárolására. A beolvasás egy ilyen képet tölt fel adatokkal, a kiírás pedig egy ilyen kép adatait írja ki. A tárolt adatokat pedig a kettő között kedvünkre manipulálhatjuk. A kép adattípusban a kép méreteit, a maximális intenzitást, és a pontok értékét kell tárolni. A pontok értékének tárolására egy dinamikus tömböt érdemes használni (pointer adattípusú mezőn keresztül).
Lehetséges megoldás (m0231-2.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
|
Feladat (f0234)
Problémafelvetés:
Invertálj egy PGM képet, azaz minden képpont intenzitását változtasd az ellenkezőjére (így pl. feketéből fehér, világosból sötét lesz, mint a fotónegatívokon)!
Specifikáció:
A program inputja egy (egyszerűsített) PGM formátumú kép. A PGM formátum egy
szürkeárnyalatos képet ír le a következő formában. A PGM fájl első sora a
P2
szöveg; a második sortól kezdve egész értékeket tartalmaz whitespace
karakterekkel (szóköz, tabulátor, sortörés, stb.) elválasztva. Az első két
érték X és Y, a kép szélessége és magassága, a harmadik M, a képpontok
lehetséges maximális értéke. Ezt további X*Y darab [0..M] intervallumba eső
érték követi, az egyes képpontok intenzitásértékei, sorfolytonosan megadva.
A kimenet egy PGM formátumú kép, az eredeti kép inverze.
A képet az input.pgm
fájlból kell beolvasni és az output.pgm
fájlba kell
kiírni.
Példa input fájlok: torony-o.pgm, progalap.pgm.
Ötlet
Érdemes az előző feladat megoldását bővíteni.
Lehetséges megoldás (m0234-1.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
|
Lehetséges megoldás (m0234-2.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
|
Feladatok¶
Feladat (f0177)
Feladat:
Készíts egy-egy olyan függvényt, ami beolvas,
- 8-as,
- 10-es vagy
- 16-os
számrendszerből átvált
- 8-as,
- 10-es vagy
- 16-os
számrendszerbe, majd kiír egy
unsigned char
,unsigned short
,unsigned int
,unsigned long
vagyunsigned long long
típuson ábrázolt egész értéket. A teljes műveletet beolvasástól kiírásig egyetlen függvény végezze (ez összesen 45 darab függvény megírását jelenti). Írj ezekhez egy főprogramot, ami a felhasználó döntése alapján meghívja valamelyiket.
Feladat (f0178)
Feladat:
Írj egy programot, ami egy táblázatban bemutatja mi történik, ha a char
,
short
, int
, long
és long long
típusú értéket a hh
, h
, l
és ll
módosítókkal
vagy ezek nélkül íratunk ki. (A bemutató akkor lesz látványos, ha az adott
típushoz olyan értéket választunk, ami a nála egyel kisebb típus
értékkészletébe már nem fér bele.)
Mi lehet a magyarázata annak, ha a program esetleg mégsem produkálja az elvárható hibás működést?
Feladat (f0179)
Feladat:
Írj egy programot, ami egy táblázatban bemutatja mi történik, ha a float
,
double
és long double
típusú értéket az l
és L
módosítókkal vagy ezek nélkül
íratunk ki.
Mi lehet a magyarázata annak, ha a program esetleg mégsem produkálja az elvárható hibás működést?
Feladat (f0190)
Feladat:
Olvass be egy teljes sort egy sztringbe, majd írasd ki! A beolvasáshoz és a
kiíráshoz a gets
/fgets
illetve puts
/fputs
függvényeket használd, minden
lehetséges kombinációt próbálj ki! Mi a különbség a gets(...)
, puts(...)
illetve fgets(stdin, ...)
, fputs(stdout, ...)
használata között? Mit
tapasztalsz, ha vegyesen használod őket (gets
/fputs
vagy fgets
/puts
)?
Feladat (f0199)
Problémafelvetés:
Írj egy programot, ami megmondja, hogy egy csoport hallgatói teljesítették-e a félévet programozás alapjai gyakorlatból.
Algoritmustervezés/Megvalósítás:
A főprogram csak az input/output műveleteket végezze, a számolást külön
függvény(ek)ben oldd meg. Készíts egy adatszerkezetet, amiben egy hallgató
nevét, pontjait tároljuk. A program tároljon külön minden részpontszámot és
a hiányzásokat is. A program láncolt listával dolgozzon, a bemenet.txt
nevű fájlból olvassa be az adatokat és a kimenet.txt
nevű fájlba írja ki
az eredményt. Az input végét a fájl vége jelezze. (A programot nem kell
felkészíteni töredék adatokra, ha nincs vége a fájlnak, akkor a következő
hallgató minden adata rendelkezésre áll benne.)
Feladat (f0235)
Problémafelvetés:
Olvass be egy PGM képet, és tedd fekete-fehérré, azaz a sötétebb pontokból csinálj feketét, a világosabbakból pedig fehéret.
Specifikáció:
A program inputja egy (egyszerűsített) PGM formátumú kép. A PGM formátum egy
szürkeárnyalatos képet ír le a következő formában. A PGM fájl első sora a
P2
szöveg; a második sortól kezdve egész értékeket tartalmaz whitespace
karakterekkel (szóköz, tabulátor, sortörés, stb.) elválasztva. Az első két
érték X és Y, a kép szélessége és magassága, a harmadik M, a képpontok
lehetséges maximális értéke. Ezt további X*Y darab [0..M] intervallumba eső
érték követi, az egyes képpontok intenzitásértékei, sorfolytonosan megadva.
A kimenet is egy PGM formátumú kép, az eredeti kép fekete-fehérré alakított
változata (amelyben így csak 0 és M intenzitású képpontok szerepelnek).
A képet az input.pgm
fájlból kell beolvasni és az output.pgm
fájlba kell
kiírni.
Példa input fájlok: torony-o.pgm, progalap.pgm.
További feladatok¶
Feladat (f0152)
Feladat:
Írj egy programot, ami kiírja, hogy hány bitet foglalnak a C nyelv char
,
short
, int
, long
, long long
, float
, double
, és long double
típusai!
Specifikáció:
A programnak nincs inputja, a kimenete pedig a megadott típusok által lefoglalt memória mérete bitekben. Egy sor elején a típusnév, majd a sor végén a típus által foglalt bitek száma, helyiérték szerinti egymás alá igazítva.
Algoritmustervezés/Megvalósítás:
A sizeof()
operátor visszaadja, hogy hány bájtot foglal egy típus.
Feladat (f0155)
Feladat:
Írasd ki a 64 és 95 közé eső kódú karaktereket, valamint az 'a' és 'z' közé eső karakterek kódjait.
Specifikáció:
A programnak nincs bemenete. A kimenete kettő sor. Az elsőben a 64-es és 95-ös kódú karakterek közé eső karakterek vannak kiíratva (a 64-es és 95-ös kódú karaktereket is beleértve) közvetlenül egymás mögött. A második sorban az 'a' és 'z' közé eső karakterek ('a'-t és 'z'-t is beleértve) kódjai vannak kiíratva, egy-egy szóközzel elválasztva egymástól.
Feladat (f0156)
Feladat:
Készíts egy programot, amely bemutatja a különbséget a signed char
és
unsigned char
értékkészlete között! Futtasd a programot, és figyeld meg
az egyes értékek tárolhatóságát, illetve a két típus különbségét!
Specifikáció:
A programnak nincs bemenete. A kimenete több sor, soronként 3 értékkel:
egy egész szám, ezen szám signed char
típusúként értelmezett, illetve
unsigned char
típusúként értelmezett értéke. Az egész szám fedje le a
signed
és unsigned char
típusok értékkészletének unióját, azaz -128-tól
255-ig menjen. A különböző sorokban kiírt értékek helyiérték szerint
legyenek egymás alá igazítva.
Algoritmustervezés/Megvalósítás:
A ciklusban olyan ciklusváltozót használjunk, amelyben a -128 .. 255
értékek gond nélkül ábrázolhatóak (pl. int
). A ciklusmagban a
ciklusváltozó értékét adjuk át egy-egy, az említett típusú változónak,
és a megfelelő helyeken ezek értékeivel dolgozzunk.
Feladat (f0157)
Feladat:
Készíts egy programot, amely bemutatja a túlcsordulás és alulcsordulás
jelenségét a különféle méretű int
típusok signed
és unsigned
változatainak tekintetében!
Algoritmustervezés/Megvalósítás:
Deklarálj 8 változót (signed
/unsigned
, short
/int
/long
/long long
), 0
kezdőértékkel, vonj ki belőlük egyet, majd írasd ki az értékeiket.
Add értékül a változóknak a legnagyobb előjelesen ábrázolható értéket
és adj hozzájuk egyet, majd ezt is írasd ki.
Lehetséges megoldás (m0157.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
|
Feladat (f0158)
Feladat:
Készíts egy programot, amely bemutatja a float
, double
és long double
típusok pontossága közötti különbséget. Vizsgáld meg, melyik milyen
relatív pontossággal dolgozik.
Algoritmustervezés/Megvalósítás:
Deklarálj két-két float
, double
és long double
változót, amikben egy
összeget, illetve egy különbséget tárolsz. Az összeget 0-ról, a
különbséget 1-ről indítsd. (Típusazonos konstansokat, vagyis a 1.0f
,
1.0
és 1.0L
literálokat használd!) Készíts egy ciklust amely lefut
N-szer (ahol N egy tetszőleges konstans, de érdemes 20 körülinek
választani), minden iterációban az összeget növeli a különbséggel, a
különbséget pedig osztja tízzel (itt a /= 10.0f
, /= 10.0
és /= 10.0L
,
vagy *= 0.1f
, *= 0.1
és *= 0.1L
kifejezéseket illetve literálokat
érdemes használni), majd kiírja az összegek aktuális értékét a
választott N tizedesjegy pontossággal.
Lehetséges megoldás (m0158.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
Feladat (f0159)
Feladat:
Készíts egy programot, amely bemutatja a float
, double
és long double
típusok értékkészlete közötti különbségeket, az ábrázolható legkisebb
és legnagyobb abszolút érték nagyságrendje tekintetében. Hatványozz egy
egynél kisebb pozitív számot amíg nullává nem válik, illetve szorozgass
egy egynél nagyobbat, amíg végtelen nem lesz. Az eredményt minden lépés
után mindhárom típusra írasd ki. Milyen értékeket kapsz lépésenként?
Algoritmustervezés/Megvalósítás:
Deklarálj egy-egy float
, double
és long double
változót 0.1-es
kezdőértékkel, majd szorozgasd mindet önmagával, amíg mindhárom 0 nem
lesz. Közben írasd ki az értéküket, exponens alakú kiírást használva.
Tedd meg ugyanezt, csak 10.0-es kezdőértékkel amíg mindhárom egyenlő nem
lesz a végtelennel (ami 1.0/0.0). (Típusazonos konstansokat, vagyis 0.0f
,
0.0
illetve 0.0L
alakú literálokat használj!)
Lehetséges megoldás (m0159.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
Feladat (f0162)
Feladat:
Készíts egy programot, amely beolvas egy valós és egy egész értéket, majd a valós értéket kiírja az egészben megadott abszolút pontossággal (vagyis annyi tizedesjeggyel a végén, amennyi az egész érték).
Feladat (f0163)
Feladat:
Készíts egy programot, amely beolvas egy valós és egy egész értéket, majd a valós értéket kiírja az egészben megadott relatív pontossággal (vagyis a legnagyobb helyiértékű számjeggyel együtt annyi "értékes" számjegye legyen, amennyi az egész érték, pl. a 123.456789-et 5 jegy pontossággal "123.46", "1.2346e2", vagy valami hasonló formában).
Feladat (f0180)
Problémafelvetés:
Készíts kódtáblázatot, amiben 32-től 127-ig soronként megjelennek az adott kódú karakterek és azok kódja oktális, decimális és hexadecimális alakban is.
Specifikáció:
A programnak nincs inputja. Az output egy táblázat, melynek egy-egy sora a következő alakú:
'A' 101 65 x41
Vagyis az oszlopokat 2-2 szóköz választja el, mindegyik oszlop 3 karakternyi széles, az első oszlop maga a karakter két aposztróf között, a második harmadik és negyedik oszlop a karakter kódja oktális, decimális és hexadecimális alakban, az oktális alak 3 számjegy vezető nullákkal, a decimális alak legfeljebb 3 karakter vezető nullák nélkül de 3 szélességben jobbra igazítva, a hexadecimális alak pedig egy 'x' karakter és 2 hexadecimális számjegy (nagybetűs).
Feladat (f0188)
Feladat:
Mi a különbség a %g
, %f
, %e
kiíratási formák között? Készíts egy programot,
ami ugyanazt a valós értéket mindhárom formátum segítségével kiírja, és nézd
meg a különbséget. Többféle értéket is próbálj ki!
Feladat (f0198)
Problémafelvetés:
Írj egy programot, ami megmondja, hogy egy csoport hallgatói teljesítették-e a félévet programozás alapjai gyakorlatból.
Algoritmustervezés/Megvalósítás:
A főprogram csak az input/output műveleteket végezze, a számolást külön függvény(ek)ben oldd meg. Készíts egy adatszerkezetet, amiben egy hallgató nevét, pontjait tároljuk. A program tároljon külön minden részpontszámot és a hiányzásokat is. A program láncolt listával dolgozzon, ahol az input végét egy speciális hallgatónév (például "*") jelezze.
Feladat (f0232)
Problémafelvetés:
Olvass be egy PGM képet, és tedd fekete-fehérré, azaz a sötétebb pontokból csinálj feketét, a világosabbakból pedig fehéret.
Specifikáció:
A program inputja egy (egyszerűsített) PGM formátumú kép. A PGM formátum egy
szürkeárnyalatos képet ír le a következő formában. A PGM fájl első sora a
P2
szöveg; a második sortól kezdve egész értékeket tartalmaz whitespace
karakterekkel (szóköz, tabulátor, sortörés, stb.) elválasztva. Az első két
érték X és Y, a kép szélessége és magassága, a harmadik M, a képpontok
lehetséges maximális értéke. Ezt további X*Y darab [0..M] intervallumba eső
érték követi, az egyes képpontok intenzitásértékei, sorfolytonosan megadva.
A kimenet is egy PGM formátumú kép, az eredeti kép fekete-fehérré alakított
változata (amelyben így csak 0 és M intenzitású képpontok szerepelnek).
Példa input fájlok: torony-o.pgm, progalap.pgm.
Feladat (f0233)
Problémafelvetés:
Tükrözz egy PGM képet a függőleges tengelyére!
Specifikáció:
A program inputja egy (egyszerűsített) PGM formátumú kép. A PGM formátum egy
szürkeárnyalatos képet ír le a következő formában. A PGM fájl első sora a
P2
szöveg; a második sortól kezdve egész értékeket tartalmaz whitespace
karakterekkel (szóköz, tabulátor, sortörés, stb.) elválasztva. Az első két
érték X és Y, a kép szélessége és magassága, a harmadik M, a képpontok
lehetséges maximális értéke. Ezt további X*Y darab [0..M] intervallumba eső
érték követi, az egyes képpontok intenzitásértékei, sorfolytonosan megadva.
A kimenet is egy PGM formátumú kép, az eredeti kép függőleges tengelyre
tükrözött változata.
Példa input fájlok: torony-o.pgm, progalap.pgm.
Feladat (f0236)
Problémafelvetés:
Tükrözz egy PGM képet a függőleges tengelyére!
Specifikáció:
A program inputja egy (egyszerűsített) PGM formátumú kép. A PGM formátum egy
szürkeárnyalatos képet ír le a következő formában. A PGM fájl első sora a
P2
szöveg; a második sortól kezdve egész értékeket tartalmaz whitespace
karakterekkel (szóköz, tabulátor, sortörés, stb.) elválasztva. Az első két
érték X és Y, a kép szélessége és magassága, a harmadik M, a képpontok
lehetséges maximális értéke. Ezt további X*Y darab [0..M] intervallumba eső
érték követi, az egyes képpontok intenzitásértékei, sorfolytonosan megadva.
A kimenet is egy PGM formátumú kép, az eredeti kép függőleges tengelyre
tükrözött változata.
A képet az input.pgm
fájlból kell beolvasni és az output.pgm
fájlba kell
kiírni.
Példa input fájlok: torony-o.pgm, progalap.pgm.
Feladat (f0258)
Problémafelvetés:
Szükségünk lenne egy programra, amely kiszámolja egy adott sugarú körbe illetve gömbbe illeszkedő szabályos síkbeli illetve térbeli alakzatok kerületét, területét, felszínét, illetve térfogatát.
Specifikáció:
A program inputja egyetlen valós szám, a gömb sugara, amelyet parancssori paraméterként kap meg. A program outputja a szabályos síkbeli illetve térbeli alakzatok jellemző értékeinek listája. Az ismerendő síkidomok illetve testek (nem teljes) listája: kör, háromszög, négyzet, öt- és hatszög, tetraéder, kocka, oktaéder, dodekaéder, ikozaéder.
Algoritmustervezés/Megvalósítás:
A program függvénypointerekkel dolgozzon. Legyen egy tömb, melynek elemei struktúrák, amik egy sztringet és egy függvénypointert tartalmaznak. A sztring mondja meg, hogy mit számol ki a függvény. Ezek után a főprogram egyetlen ciklus, ami végigmegy a tömb elemein, kiírja a sztringet és a pointeren keresztül meghívja a függvényt a megadott paraméterrel.
Feladat (f0259)
Feladat:
Olvassuk be egy tömb elemeit, írassuk ki az elemeket, duplázzuk meg, majd
ismét írassuk ki őket. Mindezt úgy, hogy a tömb bejárását egy bejar
nevű
függvény végezze, ami megkapja a tömböt és a műveletet.