Feladatgyűjtemény a C programozási nyelvhez Smidla József 2011. november 7.
2
Tartalomjegyzék I. Nyelvi alapok 5 1. Kimenet, bemenet 7 2. Változók, operátorok 13 3. Vezérlési szerkezetek 21 3.1. Programozási tételek......................... 21 3.1.1. Csere............................. 21 3.1.2. Lineáris keresés........................ 21 3.1.3. Eldöntés............................ 21 3.1.4. Megszámlálás......................... 21 3.1.5. Minimum kiválasztás..................... 21 3.1.6. Rendezés........................... 21 3.2. Feladatok............................... 21 4. Függvények 37 4.1. Függvényhívások........................... 37 4.2. Rekurzió................................ 43 4.3. Feladatok............................... 43 5. Mutatók 45 6. Struktúrák 51 7. File kezelés 53 8. A standard könyvtár 55 9. Az előfeldolgozó 57 II. Fejlettebb technikák 59 10.Láncolt listák 61 11.Fák 63 12.Bitműveletek 65 13.Memóriakezelés 67 3
4 TARTALOMJEGYZÉK 14.Parancssori paraméterek 69
I. rész Nyelvi alapok 5
1. fejezet Kimenet, bemenet A következő feladatokat úgy oldja meg, hogy az alábbi programot egészítse ki: 1 #include <s t d i o. h> 2 3 int main ( ) { 4 int i 1 = 10, i 2 = 8, i 3 = 3 ; 5 double d = 6 6 6. 6 6 6 ; 6 f loat f = 4 2. 0 ; 7 char ch = M ; 8 char s t r [ ] = " ez egy szoveg " ; 9 10 // Ide i r j a a megoldast! 11 12 return 0 ; 13 } Az alábbi feladatok mindegyikében látható 1-1 példa kimenet olyan formában, hogy az egyes karaktereket (például a szóközöket) jól láthatóan elkülöníthessük egymástól. Ott, ahol tabulátort kell használni, az átláthatóság kedvéért a példában 3 szóköz található, a valóságban ez több is lehet. 1.1.1. feladat Írassa ki az i1 változó értékét minimum 5 karakter széles mezőben, jobbra igazítva: 1 0 1.1.2. feladat Írassa ki az i1 változó értékét minimum 5 karakter széles mezőben, balra igazítva: 1 0 1.1.3. feladat Írassa ki az i1 változó értékét minimum i2 karakter széles mezőben, jobbra igazítva: 1 0 7
8 1. Kimenet, bemenet 1.1.4. feladat Írassa ki az i1 változó értékét minimum 5 karakter széles mezőben, jobbra igazítva, a mező üres karaktereinek helyén 0 legyen: 0 0 0 1 0 1.1.5. feladat Írassa ki az i1 változó értékét, ha a szám pozitív, akkor legyen előtte egy szóköz: 1 0 1.1.6. feladat Írassa ki a d változó értékét minimum 8 karakter széles mezőben, 3 tizedesjegy pontossággal: 6 6 6. 6 6 6 1.1.7. feladat Írassa ki a d változó értékét minimum i1 karakter széles mezőben, 3 tizedesjegy pontossággal: 6 6 6. 6 6 6 1.1.8. feladat Írassa ki a d változó értékét minimum 8 karakter széles mezőben, i1 tizedesjegy pontossággal: 6 6 6. 6 6 6 0 0 0 0 0 0 0 1.1.9. feladat Írassa ki a d/2.0 értékét minimum 8 karakter széles mezőben, 3 tizedesjegy pontossággal: 3 3 3. 3 3 3 1.1.10. feladat Írassa ki a d változó értékét minimum i3 karakter széles mezőben, i1 tizedesjegy pontossággal: 6 6 6. 6 6 6 0 0 0 0 0 0 0 1.1.11. feladat Írassa ki az f változó értékét minimum 8 karakter széles mezőben, 3 tizedesjegy pontossággal: 4 2. 0 0 0 1.1.12. feladat Írassa ki az f változó értékét minimum i1 karakter széles mezőben, 3 tizedesjegy pontossággal: 4 2. 0 0 0 1.1.13. feladat Írassa ki az f változó értékét minimum 8 karakter széles mezőben, i1 tizedesjegy pontossággal: 4 2. 0 0 0 0 0 0 0 0 0 0 1.1.14. feladat Írassa ki az f/4.0 értékét minimum 8 karakter széles mezőben, 3 tizedesjegy pontossággal: 1 0. 5 0 0 1.1.15. feladat Írassa ki az f változó értékét minimum i3 karakter széles mezőben, i1 tizedesjegy pontossaggal: 4 2. 0 0 0 0 0 0 0 0 0 0
9 1.1.16. feladat Írassa ki, hogy a 40 hány százaléka a 90-nek, a kimenetben jelenjen meg a % jel is: 4 4. 4 4 4 4 4 4 % 1.1.17. feladat Írassa ki a d változó értékét minimum 7 karakter széles mezőben, normál alakban: 6. 6 6 6 6 6 0 e + 0 2 1.1.18. feladat Írassa ki az i1 változó értékét oktálisan: 1 2 a 1.1.19. feladat Írassa ki az i1 változó értékét hexadecimálisan: 1.1.20. feladat Írassa ki az i1 változó értékét oktálisan, 6 karakter széles mezőben, a mező üres helyein legyen 0: 0 0 0 0 1 2 1.1.21. feladat Írassa ki az i1 változó értékét hexadecimálisan, 6 karakter széles mezőben, a mező üres helyein legyen 0: 0 0 0 0 0 a 1.1.22. feladat Írassa ki az i1 változó értékét oktálisan, 6 karakter széles mezőben, a szám 0-val kezdődjön, jelezve, hogy oktális számot írunk ki: 0 1 2 1.1.23. feladat Írassa ki az i1 változó értékét hexadecimálisan, 6 karakter széles mezőben, a mező üres helyein legyen 0, a kiírt érték pedig 0x-el kezdődjön, jelezve, hogy hexadecimális számot írunk ki: 0 x 0 0 0 a 1.1.24. feladat Írassa ki az str stringet: e z e g y s z o v e g 1.1.25. feladat Írassa ki az str stringet -k között: e z e g y s z o v e g 1.1.26. feladat Írassa ki az str stringet "-k között: " e z e g y s z o v e g " 1.1.27. feladat Írassa ki az str stringet \ -k között: \ e z e g y s z o v e g \ 1.1.28. feladat Írassa ki az str stringet, majd az utolsó előtti karakter helyére írasson ki 1-et : e z e g y s z o v 1 g 1.1.29. feladat Írassa ki az str stringet, majd az elejét írja felül i1 értékével : 1 0 e g y s z o v e g
10 1. Kimenet, bemenet 1.1.30. feladat Írassa ki az str stringet, majd utána egy tabulátornyi távolságra i1 értékét 4 széles mezőbe, a mező üres helyeire 0-kat rakva: e z e g y s z o v e g 0 0 1 0 M 1.1.31. feladat Írassa ki a ch karaktert: 1.1.32. feladat Írassa ki a ch karakter ASCII kódját decimálisan: 7 7 1.1.33. feladat Írassa ki a ch karakter ASCII kódját hexadecimálisan, az A-F betűket kisbetűsen: 4 d 1.1.34. feladat Írassa ki a ch karakter ASCII kódját hexadecimálisan, az A-F betűket nagybetűsen: 4 D 1.1.35. feladat Írassa ki a ch karakter ASCII kódját hexadecimálisan, az A-F betűket kisbetűsen, a kiírt érték 0x-el kezdődjön: 0 x 4 d 1.1.36. feladat Írassa ki a ch karakter ASCII kódját hexadecimálisan, az A-F betűket nagybetűsen, a kiírt érték 0X-el kezdődjön: 0 X 4 D 1.1.37. feladat Írassa ki a ch karakter ASCII kódját hexadecimálisan, az A-F betűket nagybetűsen, a kiírt érték 0x-el kezdődjön: 0 x 4 D 1.1.38. feladat Írassa ki a d értékét 2 tizedesjegy pontossággal, de úgy, hogy a tizedespont helyett vessző legyen: 6 6 6, 6 7 1.1.39. feladat Írassa ki az i1, i2 és i3 értékét, az egyes számok között legyen 1-1 tabulátornyi távolság: 1 0 8 3 1.1.40. feladat Írassa ki az str string legfeljebb első 7 karakterét "-k közé: " e z e g y " 1.1.41. feladat Írassa ki az str string legfeljebb első i1-2 karakterét -k közé: e z e g y s 1.1.42. feladat Írassa ki az str string legfeljebb első 5 karakterét egy 8 széles mezőbe, a mezőt határolják " karakterek: " e z e g "
11 1.1.43. feladat Írassa ki az str string legfeljebb első 5 karakterét egy 8 széles mezőbe, balra igazítva, a mezőt határolják " karakterek: " e z e g " 1.1.44. feladat Írassa ki az str string legfeljebb első i2 karakterét egy 8 széles mezőbe, a mezőt határolják " karakterek: " e z e g y s " 1.1.45. feladat Írassa ki az str string legfeljebb első i2 karakterét egy i2 + i3 széles mezőbe, balra igazítva, a mezőt határolják " karakterek: " e z e g y s " 1.1.46. feladat Írassa ki az első sorba a " karaktert, majd a következőbe egy tabulatorral beljebb a -t és végül a harmadik sor elejére a \ -t: " \ 1.1.47. feladat Írassa ki a d értékét úgy, hogy a tizedesjegyeket cserélje ki az i1 értékére: 6 6 6. 1 0 1.1.48. feladat Rajzoltasson ki a képernyőre egy 3*3-as mátrixot, amely minimum 5 karakter széles mezőben 1 tizedes pontossággal lebegőpontos számokat tartalmaz: 1. 0 2. 0 3. 0 4. 0 5. 0 6. 0 7. 0 8. 0 9. 0 1.1.49. feladat Írassa ki az -i1 értékét, mintha előjel nélküli változó lenne: 4 2 9 4 9 6 7 2 8 6 1.1.50. feladat Írassa ki az i1*10000 értékét, majd a következő sorba mintha short int típusú lenne: 1 0 0 0 0 0-3 1 0 7 2 1.1.51. feladat Írassa ki a d*i1 értékét egy i1 széles mezőbe, 2 tizedesjegy pontossággal, a mezőt határolják " karakterek, a tizedespont helyén legyen pontosvessző, ha a szám pozitív, akkor is jelenjen meg az előjel, a mező üres helyeire kerüljenek 0 karakterek: " + 0 0 6 6 6 6 ; 6 6 "
12 1. Kimenet, bemenet A következő feladatokat úgy oldja meg, hogy az alábbi programot egészítse ki: 1 #include <s t d i o. h> 2 3 int main ( ) { 4 int a = 0, b = 0, c = 0, d = 0 ; 5 char ch1, ch2 ; 6 7 // Ide i r j a a megoldast! 8 9 return 0 ; 10 } 1.1.52. feladat A getchar segítségével olvasson be egy karaktert a billentyűzetről a ch1 változóba, majd írja ki a képernyőre a beolvasott karaktert: Kerek egy karaktert: t A beolvasott karakter: t 1.1.53. feladat A getchar segítségével olvasson be a billentyűzetről 2 karaktert ( ch1, ch2), majd írja ki őket a képernyőre: Kerem az elso karaktert: r Kerem a masodik karaktert: t A beolvasott karakterek: r es t 1.1.54. feladat Olvassa be az a változó értékét billentyűzetről scanf segítségével, majd a beolvasott értéket írja ki a képernyőre: Kerek egy szamot: 53 A beolvasott szam: 53 1.1.55. feladat Olvasson be a billentyűzetről egyetlen scanf segítségével kettő számot az a és b változókba, majd írja ki a két számot a képernyőre: Kerek ketto szamot :34 54 A szamok: 34, 54 1.1.56. feladat Olvasson be a billentyűzetről 4 számot, egymástól 1-1 ponttal elválasztva, az a, b, c és d változókba, majd írja ki a beolvasott számokat a képernyőre: Kerek negy szamot, ponttal elvalasztva: 1.2.3.4 A szamok: 1, 2, 3, 4
2. fejezet Változók, operátorok Az alábbi feladatokat az alábbi kódot néhány scanf-el és egyetlen printf-el kiegészítve, és a printf paramétereként megadott összetett kifejezéssel oldja meg! 1 #include <s t d i o. h> 2 #include <s t d l i b. h> 3 4 int main ( ) { 5 int a, b, c ; 6 char ch1, ch2 ; 7 8 // Ide i r j a a megoldast! 9 10 return 0 ; 11 } 1.2.1. feladat Írja ki a képernyőre, hogy az első szám nagyobb-e mint a második: Kerem az elso szamot: 5 Kerem a masodik szamot: 5 Az elso szam nagyobb-e mint a masodik: nem Kerem az elso szamot: 10 Kerem a masodik szamot: 5 Az elso szam nagyobb-e mint a masodik: igen 1.2.2. feladat Írja ki a képernyőre a 2 szám közül a legnagyobb értékét: Kerem az elso szamot: 5 Kerem a masodik szamot: 15 A legnagyobb szam: 15 1.2.3. feladat Írja ki a képernyőre a 3 szám közül a legnagyobb értékét: 13
14 2. Változók, operátorok Kerem az elso szamot: 5 Kerem a masodik szamot: 15 Kerem a harmadik szamot: 10 A legnagyobb szam: 15 1.2.4. feladat Írja ki a képernyőre a 3 szám közül a legkisebb értékét: Kerem az elso szamot: 5 Kerem a masodik szamot: 15 Kerem a harmadik szamot: 10 A legkisebb szam: 5 1.2.5. feladat Írja ki a képernyőre a két legnagyobb szám értékét: Kerem az elso szamot: 25 Kerem a masodik szamot: 15 Kerem a harmadik szamot: 30 A ket legnagyobb szam: 25, 30 1.2.6. feladat Írja ki a képernyőre a legkisebb és legnagyobb szám összegét: Kerem az elso szamot: 25 Kerem a masodik szamot: 15 Kerem a harmadik szamot: 30 Az osszeg: 45 1.2.7. feladat Írja ki, hogy az első szám negatív-e: Kerem az elso szamot: 25 A szam nem negativ Kerem az elso szamot: 0 A szam nem negativ Kerem az elso szamot: -5 A szam negativ 1.2.8. feladat Írja ki, hogy az első szám negatív-e, majd növelje meg az első szám értékét a kiíratás után, most a növelés ellenőrzésére használhat egy második printf hívást is: Kerem az elso szamot: 25 A szam nem negativ Az elso szam erteke az elozo kiiratas utan: 26 Kerem az elso szamot: 0 A szam nem negativ Az elso szam erteke az elozo kiiratas utan: 1
15 Kerem az elso szamot: -5 A szam negativ Az elso szam erteke az elozo kiiratas utan: -4 1.2.9. feladat Írja ki a képernyőre, hogy igaz-e az, hogy az első szám kettővel nagyobb, mint a második: Kerem az elso szamot: 7 Kerem a masodik szamot: 5 Igen, az elso 2-vel nagyobb, mint a masodik Kerem az elso szamot: 7 Kerem a masodik szamot: 6 Nem, az elso nem 2-vel nagyobb, mint a masodik 1.2.10. feladat Írja ki a képernyőre, hogy igaz-e az, hogy az első szám kettővel nagyobb, mint a második, vagy a harmadik 3-al kisebb, mint az első: Kerem az elso szamot: 7 Kerem a masodik szamot: 5 Kerem a harmadik szamot: 6 A harom szam megfelel a feltetelnek Kerem az elso szamot: 7 Kerem a masodik szamot: 6 Kerem a harmadik szamot: 4 A harom szam megfelel a feltetelnek Kerem az elso szamot: 7 Kerem a masodik szamot: 6 Kerem a harmadik szamot: 5 A harom szam nem felel meg a feltetelnek 1.2.11. feladat Írja ki a képernyőre, hogy igaz-e az, hogy az első szám a másodiknál nagyobb, és a harmadiknál kisebb: 1.2.12. feladat Írja ki a képernyőre, hogy igaz-e az, hogy az első és a második szám különbsége 5-nél nagyobb: 1.2.13. feladat Írja ki a képernyőre, hogy igaz-e az, hogy az első és a második szám különbsége 5-nél nagyobb, vagy 5-el egyenlő: 1.2.14. feladat Írja ki a képernyőre, hogy igaz-e az, hogy az első szám osztható a másodikkal, de a harmadikkal nem:
16 2. Változók, operátorok 1.2.15. feladat Írja ki a képernyőre, hogy igaz-e az, hogy az első szám osztható a másodikkal, és a harmadikkal osztva a maradék 4 lesz: 1.2.16. feladat Írja ki a képernyőre, hogy igaz-e az, hogy az első szám osztható a másodikkal, és a harmadikkal osztva a maradék nagyobb-e mint 5, és a három szám összege 50 és 100 között van-e: 1.2.17. feladat Írja ki a képernyőre, hogy igaz-e az, hogy ha az első számot bitenként balra 2-vel, majd a másodikat jobbra 3-al eltoljuk, és a két számot összeadjuk, akkor az eredmény osztható-e a harmadik számmal: 1.2.18. feladat Írja ki a 3 szám közül a legkisebb szám értékét a képernyőre, majd a kiírás után nőjön egyel a változó értéke: 1.2.19. feladat Írja ki a képernyőre, hogy igaz-e az, hogy a ch1 karakter az angol ABC kisbetűi közül valamelyik: 1.2.20. feladat Írja ki a képernyőre, hogy igaz-e az, hogy a ch1 karakter számjegy-e: 1.2.21. feladat Írja ki a képernyőre, hogy igaz-e az, hogy a ch1 karakter szerepelhet-e egy lebegőpontos szám kiírása közben (tehát számjegyen kívül lehet., -, +, e vagy E karakter is): 1.2.22. feladat Ha a ch1 karakter az angol ABC kisbetűi közül valamelyik, akkor írassa ki a képernyőre a nagybetűs változatát, egyébként pedig az eredeti betűt: 1.2.23. feladat Ha a ch1 karakter az angol ABC nagybetűi közül valamelyik, akkor írassa ki a képernyőre a kisbetűs változatát, ha a ch1 kisbetű, akkor a nagybetűs megfelelőjét írja ki
17 1.2.24. feladat Bővítse ki az előző programot úgy, hogy ha a ch1 nem tartozik az angol ABC betűi közé, akkor írjon ki hibaüzenetet: 1.2.25. feladat Írassa ki az első szám ellentetjét: 1.2.26. feladat Írassa ki az első és második szám összegének ellentetjét: 1.2.27. feladat Írassa ki, hogy igaz-e az, hogy az első két szám négyzetösszege nagyobb-e mint a harmadik szám: 1.2.28. feladat Írja ki, hogy a beolvasott ch1 változó 5. bitjének mi az értéke (a bitek sorszámozását 0-ról kezdjük): Gepeljen be egy karaktert: A Az 5. bit erteke: 0 Gepeljen be egy karaktert: a Az 5. bit erteke: 1 1.2.29. feladat Bővítse ki az előző programot úgy, hogy a ch1 változó összes bitjét kiírja a képernyőre: Gepeljen be egy karaktert: A A bitminta: 01000001 Gepeljen be egy karaktert: a A bitminta: 01100001 1.2.30. feladat Invertálja a ch1 változó bitjeit: Gepeljen be egy karaktert: A A bitminta invertalas elott: 01000001 A bitminta invertalas utan: 010111110 Gepeljen be egy karaktert: m A bitminta invertalas elott: 01101101 A bitminta invertalas utan: 010010010 1.2.31. feladat Állítsa be a ch1 változó 4. bitjet 1-re: Gepeljen be egy karaktert: A A bitminta a modositas elott: 01000001 A bitminta a modositas utan: 001010001
18 2. Változók, operátorok 1.2.32. feladat Állítsa be a ch1 változó 6. bitjet 0-ra: Gepeljen be egy karaktert: A A bitminta a modositas elott: 01000001 A bitminta a modositas utan: 000000001 1.2.33. feladat Állítsa be a ch1 változó 2. 5 és 6. bitjét 1-re: Gepeljen be egy karaktert: A A bitminta a modositas elott: 01000001 A bitminta a modositas utan: 001100101 1.2.34. feladat Állítsa be a ch1 változó 0., 1. és 3. bitjét 0-ra: Gepeljen be egy karaktert: m A bitminta a modositas elott: 01101101 A bitminta a modositas utan: 001100100 1.2.35. feladat A ch1 változó minden bitjét tolja el balra 1-el, és a legkisebb helyiértékű bitje legyen 0: Gepeljen be egy karaktert: m A bitminta a modositas elott: 01101101 A bitminta a modositas utan: 011011010 1.2.36. feladat A ch1 változó minden bitjét tolja el balra 1-el, és a legkisebb helyiértekű bitje legyen 1: Gepeljen be egy karaktert: m A bitminta a modositas elott: 01101101 A bitminta a modositas utan: 011011011 1.2.37. feladat Állapítsa meg, hogy a ch1 és ch2 változónak vannak-e olyan azonos helyiértékű bitpárjai, amelyek értékei rendre megegyeznek: Gepelje be az elso karaktert: m Gepelje be a masodik karaktert: a Az elso karakter bitmintaja: 0001101101 A masodik karakter bitmintaja: 01000001 Vannak egyezo bitek 1.2.38. feladat Írassa ki, hogy hány bitet foglal el egy int típusú változó az adott architektúrán: 1.2.39. feladat Írassa ki, hogy a short vagy az int típusú változó foglal-e több bájtot:
19 1.2.40. feladat Előfordulhat-e az az ANSI C szabvány szerint, hogy a float, double és long double típusú változók mérete azonos? 1.2.41. feladat Ekvivalens-e egymással a következő két kifejezés? 1 x = y + 1 2 x = x y + 1 1.2.42. feladat Mi lesz az értéke a következő kifejezésnek, és miért? 1 4 < 5 < 3 1.2.43. feladat Mi lesz az értéke az a, b, és c változóknak az alábbi kódrészlet végrehajtása után, és miért? 1 int a = 2 ; 2 int b = 0 ; 3 int c = 1; 4 a b++ && c ; 1.2.44. feladat Mi lesz az értéke az a, b, és c változóknak az alábbi kódrészlet végrehajtása után, és miért? 1 int a = 1; 2 int b = 0 ; 3 int c = 1; 4 a++ b++ && c ; 1.2.45. feladat Mi lesz az értéke az a, b, és c változóknak az alábbi kódrészlet végrehajtása után, és miért? 1 int a = 1; 2 int b = 0 ; 3 int c = 1; 4 ++a && b++ && c ; 1.2.46. feladat Lehet-e abból probléma, ha egy unsigned int típusú változót konvertálunk signed long-ra, ha igen, milyen probléma, és miért? 1.2.47. feladat Lehet-e abból probléma, ha egy double típusú változót konvertálunk float-ra, ha igen, milyen probléma, és miért? 1.2.48. feladat Lehet-e abból probléma, ha egy long int típusú változót konvertálunk double-ra, ha igen, milyen probléma, és miért? 1.2.49. feladat Lehet-e abból probléma, ha egy double típusú változót konvertálunk long int-re, ha igen, milyen probléma, és miért?
20 2. Változók, operátorok
3. fejezet Vezérlési szerkezetek 3.1. Programozási tételek 3.1.1. Csere Van két változónk, (A és B), és azok értékét szeretnénk felcserélni. Az egyik lehetséges módszer az, hogy használunk egy segédváltozót. Ebbe elmentjük az A változó értékét: SEGED = A Mivel A értékét így elmentettük, felülírhatjuk B értékével: A = B Majd B értékét felülírjuk A eredeti értékével, amit most a SEGED-ben tárolunk: B = SEGED 3.1.2. Lineáris keresés 3.1.3. Eldöntés 3.1.4. Megszámlálás 3.1.5. Minimum kiválasztás 3.1.6. Rendezés 3.2. Feladatok A következő feladatokat az alábbi forráskódot kiegészítve oldja meg. A példa kimenetekben az első bekért szám az i1, a második az i2 és a harmadik pedig az i3 változó. Bizonyos feladatokat úgy is meg lehetne oldani, hogy egy képlettel kiszámítjuk az eredményt (például egy intervallumon belül az egész számok összege), ám most gyakorlás céljából tekintsünk el ezektől a képletektől, és ezek nélkül oldjuk meg a feladatokat. Minden algoritmusnál gondoljuk végig a szélsőséges eseteket is! 21
22 3. Vezérlési szerkezetek 1 #include <s t d i o. h> 2 3 int main ( ) { 4 5 int i1, i2, i 3 ; 6 p r i n t f ( Gepeljen be 3 szamot : ) ; 7 s c a n f ( %d %d %d, &i1, &i2, &i 3 ) ; 8 9 // Ide i r j a a megoldast! 10 11 return 0 ; 12 } 1.3.1. feladat Rajzoljon ki a képernyőre egy i1 sorból és i2 oszlopból álló * karakterekkel kitöltött téglalapot: Gepeljen be 2 szamot: 1 1 * Gepeljen be 2 szamot: 3 4 **** **** **** 1.3.2. feladat Rajzoljon ki a képernyőre egy i1 sorból és i2 oszlopból álló * karakterekkel határolt téglalapot: Gepeljen be 2 szamot: 1 1 * Gepeljen be 2 szamot: 2 4 **** **** Gepeljen be 2 szamot: 3 4 **** **** **** Gepeljen be 2 szamot: 5 6 ****** ****** ****** ****** ****** 1.3.3. feladat Rajzoljon ki a képernyőre egy i1 karakternyi magas derékszögű háromszöget:
3.2. FELADATOK 23 Gepeljen be 1 szamot: 1 * Gepeljen be 1 szamot: 2 * ** Gepeljen be 1 szamot: 3 * ** *** 1.3.4. feladat Rajzoljon ki a képernyőre egy i1 karakter szélességű és magasságú X-et: Gepeljen be 1 szamot: 1 * Gepeljen be 1 szamot: 2 ** ** Gepeljen be 1 szamot: 3 * * ** * * Gepeljen be 1 szamot: 4 **** *** *** **** Gepeljen be 1 szamot: 5 ***** **** *** **** ***** 1.3.5. feladat Adja össze a számokat i1-től i2-ig: Gepeljen be 2 szamot: 10 20 Az osszeg: 165 1.3.6. feladat Adjon össze minden i1. számot i2-től i3-ig: Gepeljen be 3 szamot: 2 10 20 Az osszeg: 90
24 3. Vezérlési szerkezetek 1.3.7. feladat Számolja ki i1 faktoriálisát! Egy n szám faktoriálisa az egész számok szorzata 1-től n-ig, továbbá a 0 faktoriálisa 1: Gepeljen be 1 szamot: 0 0 faktorialisa: 1 Gepeljen be 1 szamot: 1 1 faktorialisa: 1 Gepeljen be 1 szamot: 2 2 faktorialisa: 2 Gepeljen be 1 szamot: 3 3 faktorialisa: 6 Gepeljen be 1 szamot: 4 4 faktorialisa: 24 1.3.8. feladat Írassa ki képernyőre a Fibonacci-sorozat első i1 elemét. A Fibonacci sorozat i. elemét jelölje F i, ahol i 0. Az első két elem értéke: F 0 = 0, F 1 = 1. Ha i 2, akkor F i = F i 1 + F i 2. Gepeljen be 1 szamot: 10 Az elso 10 Fibonacci szam: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 1.3.9. feladat Vizsgálja meg, hogy az int típus legfeljebb mekkora N szám faktoriálisának tárolására alkalmas: 00 faktorialisa: 1 01 faktorialisa: 1 02 faktorialisa: 2 03 faktorialisa: 6 04 faktorialisa: 24 05 faktorialisa: 120 06 faktorialisa: 720 07 faktorialisa: 5040 08 faktorialisa: 40320 09 faktorialisa: 362880 10 faktorialisa: 3628800 11 faktorialisa: 39916800 12 faktorialisa: 479001600 13 faktorialisa: 6227020800 ez mar nagyobb, mint 2147483647 A legnagyobb ertek, amelynek faktorialisat egy int-ben tarolni tudjuk: 12 1.3.10. feladat Írassa ki egy mértani sorozat első i1 elemét, ha az első elem i2, és a szorzó i3 :
3.2. FELADATOK 25 Gepeljen be 3 szamot: 10 2 3 2 6 18 54 162 486 1458 4374 13122 39366 1.3.11. feladat Számolja ki az i1 i2-edik hatványát, de csak akkor, ha i2 nem negatív : Gepeljen be 2 szamot: 0 0 0ˆ0 = nem ertelmezheto Gepeljen be 2 szamot: 4 0 4ˆ0 = 1 Gepeljen be 2 szamot: 0 5 0ˆ5 = 0 Gepeljen be 2 szamot: 1 5 1ˆ5 = 1 Gepeljen be 2 szamot: 2 5 2ˆ5 = 32 Gepeljen be 2 szamot: 3 5 3ˆ5 = 243 Gepeljen be 2 szamot: 4 5 4ˆ5 = 1024 1.3.12. feladat Számolja ki az i1 i2-edik hatványát és kezelje azt az esetet is, amikor i2 negatív: Gepeljen be 2 szamot: 0-4 Hiba, ervenytelen adatok! Gepeljen be 2 szamot: 1-4 1ˆ-4 = 1 Gepeljen be 2 szamot: 2-4 2ˆ-4 = 0.0625 Gepeljen be 2 szamot: 3-4 3ˆ-4 = 0.0123457 Gepeljen be 2 szamot: 4-4 4ˆ-4 = 0.00390625 Gepeljen be 2 szamot: 5-4 5ˆ-4 = 0.0016 1.3.13. feladat Írja ki a képernyőre i1 osztóit :
26 3. Vezérlési szerkezetek Gepeljen be 1 szamot: 1 1 Gepeljen be 1 szamot: 2 1 2 Gepeljen be 1 szamot: 10 1 2 5 10 Gepeljen be 1 szamot: 17 1 17 Gepeljen be 1 szamot: 100 1 2 4 5 10 20 25 50 100 1.3.14. feladat Határozza meg, hogy i1 prímszám-e: Gepeljen be 1 szamot: 1 A(z) 1 nem primszam Gepeljen be 1 szamot: 2 A(z) 2 primszam Gepeljen be 1 szamot: 3 A(z) 3 primszam Gepeljen be 1 szamot: 4 A(z) 4 nem primszam Gepeljen be 1 szamot: 11223 A(z) 11223 nem primszam Gepeljen be 1 szamot: 79609 A(z) 79609 primszam 1.3.15. feladat Határozza meg az i1 után következő első prímszám értékét: Gepeljen be 1 szamot: 1 A(z) 1 utani elso primszam: 2 Gepeljen be 1 szamot: 3 A(z) 3 utani elso primszam: 5 Gepeljen be 1 szamot: 100 A(z) 100 utani elso primszam: 101 Gepeljen be 1 szamot: 1232 A(z) 1232 utani elso primszam: 1237
3.2. FELADATOK 27 1.3.16. feladat Határozza meg, hogy i1 négyzetszám-e: Gepeljen be 1 szamot: 1 A(z) 1 negyzetszam Gepeljen be 1 szamot: 2 A(z) 2 nem negyzetszam Gepeljen be 1 szamot: 4 A(z) 4 negyzetszam Gepeljen be 1 szamot: 10 A(z) 10 nem negyzetszam Gepeljen be 1 szamot: 49 A(z) 49 negyzetszam Gepeljen be 1 szamot: 32244 A(z) 32244 nem negyzetszam Gepeljen be 1 szamot: 28558336 A(z) 28558336 negyzetszam 1.3.17. feladat Számolja meg, hogy i1 előtt i1-t is vizsgálva) mennyi négyzetszám van: Gepeljen be 1 szamot: 1 A(z) 1 elott 1 negyzetszam van Gepeljen be 1 szamot: 100 A(z) 100 elott 10 negyzetszam van Gepeljen be 1 szamot: 212341 A(z) 212341 elott 460 negyzetszam van 1.3.18. feladat Számolja meg, hogy i1 és i2 között ( i1-t és i2-t is vizsgálva) mennyi négyzetszám van: Gepeljen be 2 szamot: 1 1 A [1, 1] intervallumban 1 negyzetszam van Gepeljen be 2 szamot: 1 10 A [1, 10] intervallumban 3 negyzetszam van Gepeljen be 2 szamot: 1 100 A [1, 100] intervallumban 10 negyzetszam van Gepeljen be 2 szamot: 232 3242 A [232, 3242] intervallumban 41 negyzetszam van
28 3. Vezérlési szerkezetek 1.3.19. feladat Olvasson be a billentyűzetről számokat 0 végjelig (tehát ha a beolvasott szám 0, akkor vége a beolvasásnak), és szamolja meg, hogy a 0-t kivéve mennyi számot olvasott be: Kerek egy szamot: 4 Kerek egy szamot: 2 Kerek egy szamot: 8 Kerek egy szamot: 5 Kerek egy szamot: 7 Kerek egy szamot: 0 5 szamot olvastam be 1.3.20. feladat Olvasson be a billentyűzetről számokat 0 végjelig, és a végjelen kívül határozza meg a legnagyobb beolvasott elemet: Kerek egy szamot: 4 Kerek egy szamot: 2 Kerek egy szamot: 8 Kerek egy szamot: 7 Kerek egy szamot: 0 A legnagyobb beolvasott szam: 8 Kerek egy szamot: -5 Kerek egy szamot: -7 Kerek egy szamot: 0 A legnagyobb beolvasott szam: -5 1.3.21. feladat Olvasson be a billentyűzetről számokat 0 végjelig, és a végjelen kívül határozza meg a legkisebb beolvasott elemet: Kerek egy szamot: 4 Kerek egy szamot: 2 Kerek egy szamot: 8 Kerek egy szamot: 7 Kerek egy szamot: 0 A legkisebb beolvasott szam: 2 1.3.22. feladat Olvasson be a billentyűzetről számokat 0 végjelig, és számolja meg, hogy mennyi páros számot olvasott be: Kerek egy szamot: 4 Kerek egy szamot: 2 Kerek egy szamot: 8 Kerek egy szamot: 7 Kerek egy szamot: 0 3 paros szamot olvastam be 1.3.23. feladat Olvasson be a billentyűzetről számokat 0 végjelig, és számolja ki a beolvasott számok átlagát, a végjelet ne vegye figyelembe:
3.2. FELADATOK 29 Kerek egy szamot: 4 Kerek egy szamot: 2 Kerek egy szamot: 8 Kerek egy szamot: 7 Kerek egy szamot: 0 A szamok atlaga: 5.25 1.3.24. feladat Egy dolgozat ponthatárai a következők: 0-12 : elégtelen 13-18 : elégséges 19-27 : közepes 28-31 : jó 32-39 : jeles A program írja ki, hogy i1 pontszám esetén milyen jegy adható az adott dolgozatra: Gepeljen be 1 szamot: 1 Az erdemjegy: elegtelen Gepeljen be 1 szamot: 12 Az erdemjegy: elegtelen Gepeljen be 1 szamot: 20 Az erdemjegy: elegseges Gepeljen be 1 szamot: 32 Az erdemjegy: jeles 1.3.25. feladat Switch - case segítségével határozza meg, hogy az i1. hónap i2. napjáig hány nap telt el az évben, ha nem szökőévben vagyunk.: Kerem a honapot: 5 Kerem a napot: 20 Az eltelt napok szama: 140 1.3.26. feladat Switch - case segítségével határozza meg, hogy az i1 évben a i2. hónap i3. napjáig hány nap telt el az évben, de most vegye figyelembe azt is, ha szökőévben vagyunk: Kerem az evet: 1993 Kerem a honapot: 5 Kerem a napot: 20 Az eltelt napok szama: 140 Kerem az evet: 2000 Kerem a honapot: 5
30 3. Vezérlési szerkezetek Kerem a napot: 20 Az eltelt napok szama: 141 1.3.27. feladat Valósítson meg egy egyszerű menüt! A program jelenítsen meg 4 választási lehetőséget, amik közül 1 és 4 közötti számok beírásával lehessen választani, és a választásnak megfelelően írjon ki egy üzenetet: Elso menupont: 1 Masodik menupont: 2 Harmadik menupont: 3 Negyedik menupont: 4 Valasszon a fenti menupontok kozul: 2 Ugyintezonk ebredeseig kerjuk varjon turelemmel 1.3.28. feladat Bővítse ki az előző programot úgy, hogy a menüpont választás után kérdezze meg a felhasználót, hogy szeretne-e újra választani, ha igen, akkor jelenjen meg újra a menü, egyébként lepjen ki: Elso menupont: 1 Masodik menupont: 2 Harmadik menupont: 3 Negyedik menupont: 4 Valasszon a fenti menupontok kozul: 1 Sajnaljuk, de ugyintezonknek jelenleg nincs kedve az On problemajaval foglalkozni Kivan masik menupontot kivalasztani (i/n)? i Elso menupont: 1 Masodik menupont: 2 Harmadik menupont: 3 Negyedik menupont: 4 Valasszon a fenti menupontok kozul: 3 Jelenleg fontosabb dolgunk is van, mint Onnel foglalkozni Kivan masik menupontot kivalasztani (i/n)? n Forduljon hozzank maskor is bizalommal! 1.3.29. feladat Módosítsa az előző programot úgy, hogy minden eddigi menüpontból térjen vissza a menübe, és legyen egy kilépés menüpont is : Elso menupont: 1 Masodik menupont: 2 Harmadik menupont: 3 Negyedik menupont: 4 Kilepes: 5 Valasszon a fenti menupontok kozul: 4 Probalta kikapcsolni, bekapcsolni?
3.2. FELADATOK 31 Elso menupont: 1 Masodik menupont: 2 Harmadik menupont: 3 Negyedik menupont: 4 Kilepes: 5 Valasszon a fenti menupontok kozul: 5 Forduljon hozzank maskor is bizalommal! 1.3.30. feladat Fejlessze tovább az előző programot egyszerű számológép programmá: lehessen választani a négy alapművelet közül, és végezze el a kiválasztott műveletet két bekért szám között. Amennyiben osztás esetén az osztó nulla, akkor jelenítsen meg egy hibaüzenetet, majd addig kérje be az osztót, amíg a felhasználó nullától különböző értéket nem ír be: Osszeadas: 1 Kivonasz: 2 Szorzas: 3 Osztas: 4 Kilepes: 5 Valasszon egy menupontot: 2 Kerem a szamokat: 5 3 5-3 = 2 Osszeadas: 1 Kivonasz: 2 Szorzas: 3 Osztas: 4 Kilepes: 5 Valasszon egy menupontot: 4 Kerem a szamokat: 5 0 Uriember nem oszt 0-val, kerek masik osztot: 0 Uriember nem oszt 0-val, kerek masik osztot: 2 5 / 2 = 2.5 Osszeadas: 1 Kivonasz: 2 Szorzas: 3 Osztas: 4 Kilepes: 5 Valasszon egy menupontot: 5 Viszlat 1.3.31. feladat Töltsön fel egy 10 elemű int tömböt számokkal, a számokat billentyűzetről olvassa be: Kerem a(z) 1. szamot: 5 Kerem a(z) 2. szamot: 2..
32 3. Vezérlési szerkezetek. Kerem a(z) 10. szamot: 8 1.3.32. feladat Írassa ki a fenti tömb elemeit: A beolvasott tomb: 5 20 6 7 2 3 63 5 6 12 1.3.33. feladat Határozza meg a tömb legnagyobb és legkisebb elemét: A tomb legnagyobb eleme: 63 A tomb legkisebb eleme: 2 1.3.34. feladat Cserélje meg a tömb első és második elemét: Csere elott: 5 20 6 7 2 3 63 5 6 12 Csere utan: 20 5 6 7 2 3 63 5 6 12 1.3.35. feladat Cserélje meg a tömb első és a legkisebb elemét: Csere elott: 5 20 6 7 2 3 63 5 6 12 Csere utan: 2 20 6 7 5 3 63 5 6 12 1.3.36. feladat Az előző programot bővítse ki úgy, hogy rendezze növekvő sorrendbe a tömböt: Csere elott: 5 20 6 7 2 3 63 5 6 12 Legkisebb elem: 2, pozicioja: 5 1. es 5. elem csereje utan: 2 20 6 7 5 3 63 5 6 12 Kovetkezo legkisebb elem: 3, pozicioja: 6 2. es 6. elem csereje utan: 2 3 6 7 5 20 63 5 6 12 Kovetkezo legkisebb elem: 5, pozicioja: 5 3. es 5. elem csereje utan: 2 3 5 7 6 20 63 5 6 12 Kovetkezo legkisebb elem: 5, pozicioja: 7 4. es 7. elem csereje utan: 2 3 5 5 6 20 63 7 6 12 Kovetkezo legkisebb elem: 6, pozicioja: 5 5. es 5. elem csereje utan: 2 3 5 5 6 20 63 7 6 12 Kovetkezo legkisebb elem: 6, pozicioja: 9 6. es 9. elem csereje utan:
3.2. FELADATOK 33 2 3 5 5 6 6 63 7 20 12 Kovetkezo legkisebb elem: 7, pozicioja: 8 7. es 8. elem csereje utan: 2 3 5 5 6 6 7 63 20 12 Kovetkezo legkisebb elem: 12, pozicioja: 10 8. es 10. elem csereje utan: 2 3 5 5 6 6 7 12 20 63 Kovetkezo legkisebb elem: 20, pozicioja: 9 9. es 9. elem csereje utan: 2 3 5 5 6 6 7 12 20 63 1.3.37. feladat Módosítsa az előző programot úgy, hogy csökkenő sorrendbe rendezzen! 1.3.38. feladat Egy másik tömbbe másolja át az előző feladatokban használt tömbből a páros számokat. A számok sorrendje tetszőleges lehet: Az elso tomb: 5 20 6 7 2 3 63 5 6 12 A masodik tomb: 20 6 2 6 12 1.3.39. feladat Határozza meg egy string hosszát (saját ciklussal, és ne az strlen-el!), segítség: a string karaktertömb \0 -val van lezárva. A string: "ez egy szoveg" Hossza: 13 1.3.40. feladat Vizsgálja meg, hogy egy string palindrom-e (azaz elölről olvasva ugyanaz-e mint visszafelé), például.: gorog, keretkarakterek: String: "gorog" Ez palindrom String: "keretkarakterek" Ez palindrom String: "alma" Ez nem palindrom 1.3.41. feladat Írjon programot, amely egy tömb elemeinek sorrendjét megfordítja: A tomb megforditas elott: 5 20 6 7 2 3 63 5 6 12 A tomb megforditas utan: 12 6 5 63 3 2 7 6 20 5 1.3.42. feladat Írjon programot, amely egy tömb elemeit a tömbön belül egyel előrébb tolja, és az eredeti első elemet az utolsó helyre illeszti be:
34 3. Vezérlési szerkezetek A tomb az eltolas elott: 5 20 6 7 2 3 63 5 6 12 A tomb az eltolas utan: 20 6 7 2 3 63 5 6 12 5 1.3.43. feladat Írjon programot, amely eldönti, hogy egy adott érték benne van-e egy tömbben: A tomb: 5 20 6 7 2 3 63 5 6 12 Gepeljen be 1 szamot: 2 A(z) 2 benne van a tombben Gepeljen be 1 szamot: 4 A(z) 4 nincs benne a tombben 1.3.44. feladat Gondolja végig, hogy az előző feladatban hány lépésre van szükség a legjobb esetben a legrosszabb esetben átlagosan 1.3.45. feladat Írjon olyan algoritmust, amely egy rendezett tömbben keres egy adott értéket, kihasználva a tömb rendezettségét. 1.3.46. feladat Az előző algoritmusban hány lépésre van szükség a legjobb esetben a legrosszabb esetben 1.3.47. feladat Írjon programot, amely két azonos elemszámú tömbről eldönti, hogy az azonos indexű elemeik mind megegyeznek-e: Az egyik tomb: 5 20 6 7 2 3 63 5 6 12 A masik tomb: 5 20 6 7 2 3 63 5 6 12 A ket tomb megegyezik Az egyik tomb: 4 20 7 6 2 3 61 5 6 12 A masik tomb: 5 20 6 7 2 3 63 5 6 12 A ket tomb nem egyezik meg Az egyik tomb: 4 20 7 6 2 3 61 5 6 12
3.2. FELADATOK 35 A masik tomb: 5 20 6 7 2 3 63 5 6 A ket tomb nem egyezik meg 1.3.48. feladat Írjon programot, amely két azonos elemszámú tömb esetén megszámolja, hogy mennyi azonos indexű elemük egyezik meg: Az egyik tomb: 4 20 7 6 2 3 61 5 6 12 A masik tomb: 5 20 6 7 2 3 63 5 6 12 6 elem egyezik meg 1.3.49. feladat Írjon programot, amely eldönti, hogy egy adott A és B tömb eseten az A tömb elemei mind benne vannak-e B tömbben úgy, hogy az elemek sorrendje bármilyen lehet a tömbökön belül. Az ismétlődő elemek azonosnak tekinthetők: A tomb: 4 20 7 6 2 3 61 5 6 12 B tomb: 2 3 8 3 A tomb elemei nincsenek benne mind a B-ben B tomb elemei mind benne vannak az A-ban 1.3.50. feladat Írjon programot, amely kiszámolja egy tömb elemeinek átlagát, szórását, a legnagyobb és legkisebb elem különbségét: A tomb elemei: 4 20 7 6 2 3 61 5 6 12 Atlag: 12.6 Szoras: 16.88905 Legnagyobb es legkisebb elem kulonbsege: 59 1.3.51. feladat Írjon programot, amely meghatározza egy tömb leggyakoribb elemeit: A tomb elemei: 4 20 7 6 2 3 61 5 6 12 A tomb leggyakoribb elemei: 6 A tomb elemei: 4 20 7 6 2 3 61 5 6 2 A tomb leggyakoribb elemei: 2 6
36 3. Vezérlési szerkezetek
4. fejezet Függvények 4.1. Függvényhívások Az alábbiakban ismertetjük, hogy a C programok függvényhívásai milyen mechanizmus szerint játszódnak le. Ennek ismerete azért szükséges, hogy értsük azt, hogy a függvények paraméterei, lokális változói hová kerülnek, hogy kezeli azokat a program. Továbbá, ezen információk birtokában bizonyos végzetes hibák elkerülésére is tudatosan felkészülhetünk. Kezdetben vizsgáljuk meg az alábbi programot: 1 #include <s t d i o. h> 2 3 void fv ( ) { 4 p r i n t f ( fv \n ) ; 5 } 6 7 int main ( ) { 8 p r i n t f ( main\n ) ; 9 fv ( ) ; 10 return 0 ; 11 } A program a main függvény első utasításával indul (8-as sor). Amint elérkezik az fv() sorhoz, a vezérlés átugrik az fv függvény első sorára (4- es sor). Miután az fv függvény utolsó utasítása is végrehajtódott, a vezérlés visszalép a main függvénybe, mégpedig oda, ahol annak a futása megszakadt (9-es sor). A kérdés az, hogy a program honnan tudja, hogy az fv függvény befejezése után a main függvénybe kell visszalépni, mégpedig a kód 9. sorára? Először arra gondolhatunk, hogy a C fordító biztos olyan gépi kódot fordított a forráskódból, hogy a vezérlés az fv utolsó sora után mindig a main függvény megfelelő sorába ugorjon. Ám tekintsük meg a következő programot: 37
38 4. Függvények 1 #include <s t d i o. h> 2 3 void fv1 ( ) { 4 p r i n t f ( fv1 \n ) ; 5 } 6 7 void fv2 ( ) { 8 p r i n t f ( fv2 \n ) ; 9 fv1 ( ) ; 10 p r i n t f ( fv1 hivas utan, de az fv2 ben\n ) ; 11 } 12 13 int main ( ) { 14 p r i n t f ( main\n ) ; 15 fv2 ( ) ; 16 p r i n t f ( fv2 hivas utan, de a main ben\n ) ; 17 fv1 ( ) ; 18 p r i n t f ( fv1 hivas utan, de a main ben\n ) ; 19 return 0 ; 20 } Ennek a programnak a kimenete a következő: main fv2 fv1 fv1 hivas utan, de az fv2-ben fv2 hivas utan, de a main-ben fv1 fv1 hivas utan, de a main-ben Tehát először meghívjuk az fv2 függvényt, az pedig meghívja az fv1-et. Az fv1 végrehajtása után a program újra az fv2-ben folytatódik, mégpedig a forráskód 10. sorában. Viszont az fv1-et külön meghívjuk a main-ből is, ekkor viszont az fv1 lefutása után már a forráskód 18. sorában folytatódik a végrehajtás. Nem igaz tehát, hogy a fordító beégeti, hogy egy függvény végrehajtása után hol kell folytatódnia a vezérlésnek. Tehát valami módon meg kell jegyezni, hogy egy függvényhívás végrehajtása után hol kell folytatódnia a programnak. Erre használhatunk egy listát, amire minden függvényhívás előtt feljegyezzük, hogy ha végrehajtottuk a függvényt, akkor hol kell folytatódnia a programnak. Erre a listára írjuk fel a forráskód megfelelő sorainak a számát! Lássuk, hogy működik ez az előző program esetében: Kezdetben a vezérlés a kód 14. során áll. Miután ezt végrehajtottuk, rátérünk a következő utasításra, ami egy függvényhívás (tulajdonképpen az előző sor is az volt, de erre még visszatérünk). A 15. sor szerint el kell indítani az fv2 függvényt. Ezen a ponton tudjuk, hogy ha ez a függvény lefutott, akkor a 16. sorban kell folytatni a programot. Ezért feljegyezzük a 16. sort:
4.1. FÜGGVÉNYHÍVÁSOK 39 16. sor Elindítjuk hát az fv2 függvényt, ráugrunk a 8. sorra. Ezt végrehajtjuk, majd következik a 9. sor, ahol meghívjuk az fv1 függvényt. Itt tudjuk, hogy az fv1 végrehajtása után a kód 10. sorában kell folytatni a végrehajtást, ezért ezt is felírjuk a listánkra: 10. sor 16. sor Átugrunk a kód 4. sorára, végrehajtjuk, majd ezzel befejeztük az fv1 függvényt. Ekkor megnézzük, hogy melyik a legutolsó sorszám a listánkon. Jelen esetben ez a 10. sor, ezért ide ugrunk, majd a legutóbbi bejegyzést töröljük a listáról: 16. sor Miután végeztünk a 10. sorral is, befejezzük az fv2 végrehajtását, ezért újra megnézzük, hogy melyik a legutolsó sorszám a listán. Ez a 16. sor, tehát ide ugrunk, és ezt a bejegyzést is töröljük a listáról: A 16. sor után jön a 17. ami egy újabb függvényhívás, itt most az fv1-et kell elindítani. Tudjuk, hogy miután végeztünk ezzel a függvénnyel, a kód 18. sorában kell majd folytatni a programot, ezért ezt a sorszámot felírjuk a listára:
40 4. Függvények 18. sor Így, miután az fv1 lefutott, megnézzük a lista legutolsó bejegyzését, ez a 18. sor. Ugrunk a 18. sorra, majd töröljük a listát. A C programokban (és szinte minden más nyelven írt programokban is) használnak ilyen listát a függvényhívások vezérlésére. Az ilyen listákat szakszóval veremnek, vagy angolul stack-nek hívjuk. A továbbiakban a verem szót fogjuk használni. A verem bizonyos elemeket, jelen esetben számokat tárol. A verem teteje mindig az a pozíció, ahová a legutolsó elemet beszúrtuk, és új elem hozzáadásakor csak a verem tetejére pakolhatunk. Azaz, amit utoljára beszúrtunk, azt vehetjük ki elsőnek (last in, first out, azaz LIFO elv). Azt az értéket, ami jelzi, hogy az aktuális függvény végrehajtása után melyik utasításon kell folytatni a programot, visszatérési címnek nevezzük. A cím szó onnan ered, hogy a program utasításai annak végrehajtásakor a memóriában találhatóak, így minden utasítás más és más memória címen helyezkedik el, a verembe pedig ilyen címeket szúrunk be. A verem azonban nem csak visszatérési címek tárolására alkalmas. Tekintsük az alábbi programot: 1 #include <s t d i o. h> 2 3 void fv ( int p1, int p2 ) { 4 int l = 0 ; 5 l = p1 + p2 ; 6 p1 = 1 0 ; 7 p r i n t f ( %d\n, l ) ; 8 } 9 10 int main ( ) { 11 int a = 2, b = 5 ; 12 fv ( a, b ) ; 13 return 0 ; 14 } Ez a program tartalmaz változókat is. A main függvényben vannak az a, b, az fv-ben pedig a p1, p2 és l változók. A main függvényből nem láthatjuk az fv-ben lévő változókat, mivel ezek lokális változók: Ha a main-ben hivatkoznánk a p1-re, akkor a fordító hibajelzés után leállna. Hasonlóan, az fv-ből sem láthatóak a main változói. Amennyiben a main-ben létrehozunk egy p1 nevű változót, az semmilyen zavart nem fog okozni az fv működésében, mivel itt kettő, egymástól teljesen elkülönülő p1 változó létezne a programban. Ez azért hasznos, mert egy nagyobb programban, ahol akár több ezer függvény is lehet, nem kell arra ügyelni, hogy mikor melyik függvényben milyen változó neveket használunk. Ellenkező esetben nagyobb programok fejlesztése hamar gyötrelmes tortúrává válna.
4.1. FÜGGVÉNYHÍVÁSOK 41 Ezek a lokális változók szintén a veremben helyezkednek el. A következőben bemutatjuk, hogy hogyan fut le a fenti program, mégpedig úgy, hogy a verem tartalmának változását is nyomon követjük. Mint minden C program, ez is a main függvénnyel kezdődik. Itt létrejön az a és b változó, így azokat belerakjuk a verembe: b = 5 a = 2 A következő lépésben meghívjuk az fv függvényt. Előtte azonban jegyezzük fel, hogy annak lefutása után a 13. sorban kell folytatni a végrehajtást, ezért ezt jegyezzük fel a veremben: 13. sor b = 5 a = 2 Az fv függvénynek vannak paraméterei is: Az a és b értékét átadjuk az fv-nek, hogy azokat felhasználhassa a futása során. A paraméterek értékeit szintén a verembe szúrjuk be, először a b, majd az a értékét: 2 5 13. sor b = 5 a = 2 Ezek után a vezérlés átugrik az fv függvényre. A függvény tudja, hogy neki 2 paramétere van, és ismeri azok típusait is. Azt is tudja, hogy ha neki 2 paramétere van, akkor azok a verem tetején találhatóak meg, ezért a p1-et és a p2-t megfelelteti a verem tetején lévő értékeknek: p1 = 2 p2 = 5 13. sor b = 5 a = 2
42 4. Függvények A következő lépés a függvény végrehajtása. Az első utasítás szerint létre kell hozni még egy lokális változót, az l-t, tehát ezt is beszúrjuk a verembe: l = 0 p1 = 2 p2 = 5 13. sor b = 5 a = 2 Az 5. sor értelmében az l értékét megváltoztatjuk, tehát a verem első sorában tárolt érték megváltozik: l = 7 p1 = 2 p2 = 5 13. sor b = 5 a = 2 A 6. sor hatására a p1 értékét változtatjuk meg: l = 7 p1 = 10 p2 = 5 13. sor b = 5 a = 2 Itt jól látszik, hogy a p1 és a változók semmilyen kapcsolatban nem állnak egymással, a eredeti értéke változatlan marad. A 7. sor elvégzése után az fv-t befejezzük, a függvény lokális változóira a továbbiakban nincs szükség, ezért azok megsemmisülnek: 13. sor b = 5 a = 2 Mivel a függvény végrehajtását befejezzük, ezért vissza kell térni a main függvénybe, ezért kiolvassuk a veremből, hogy hányadik kódsornál kell folytatni a programot. Ez a 13. sor, tehát ide ugrunk, és a visszatérési címet töröljük a veremből:
4.2. REKURZIÓ 43 b = 5 a = 2 Természetesen a fenti programban a printf is egy függvény, tehát annak meghívásakor a fenti mechanizmus játszódik le, tehát a verembe újabb visszatérési cím és újabb lokális változók kerülnek, ám a printf lefutása után ezek törlődnek is a veremből úgy, ahogy az fv esetében azt láttuk. Ám a verem használatának köszönhetően ez egyáltalán nem fogja megzavarni a programunk működését, hiszen így a printf úgy fut le, hogy utána a vermen nem látunk változást. A fenti forráskód 12. sorában látható függvény paramétereket aktuális paramétereknek, míg a 3. sorban lévő paraméter listát formális paramétereknek hívjuk. A formális paraméterek a példaprogram 12. sorában kapták meg konkrét értékeiket az aktuális paraméterektől. Kicsit mélyebben Aki járatos a verem működésében és az assembly programozásban, most bizonyára azt mondja, hogy a verem működésének fenti ismertetése pontatlan, nem minden ilyen sorrendben zajlik le. Ez teljesen igaz, a fenti leírásban azért nem követtük a valóságot teljes szigorúsággal, hogy az ismertetett működési mechanizmust könnyebben bemutathassuk, és az Olvasó könnyebben megértse a lényeget. Az alábbiakban a teljesség kedvéért leírjuk a fenti mechanizmus valódi működését a 32 bites Intel processzorok esetében, majd utána kitérünk arra, hogy a 64 bites processzorok működése mennyiben tér el ettől. TODO: ezt a részt befejezni... 4.2. Rekurzió 4.3. Feladatok
44 4. Függvények
5. fejezet Mutatók A következő feladatokat úgy oldja meg, hogy az alábbi programot egészítse ki: 1 #include <s t d i o. h> 2 #include <s t d l i b. h> 3 4 int main ( ) { 5 int a = 1, b = 2, c = 3 ; 6 7 return 0 ; 8 } 1.5.1. feladat Írassa ki az a, b és c változók címeit: Az a cime: 0xbfc56a08 A b cime: 0xbfc56a04 A c cime: 0xbfc56a00 1.5.2. feladat Tárolja el az a változó címét egy külön pa nevű változóban: A pa erteke: 0xbfc56a08 1.5.3. feladat Változtassa meg az a változó értékét a pa változón keresztül: Az a erteke a valtoztatas elott: 1 Az a erteke a valtoztatas utan: 10 1.5.4. feladat Tárolja el a pa címét is egy ppa nevű változóban: A ppa erteke, azaz pa cime: 0xbfc569fc 45
46 5. Mutatók 1.5.5. feladat Változtassa meg az a változó értékét a ppa változón keresztül: Az a erteke a valtoztatas elott: 10 Az a erteke a valtoztatas utan: 100 1.5.6. feladat A ppa-n keresztül állítsa át a pa változót úgy, hogy b-re mutasson: A A pa erteke a valtoztatas elott: 0xbfc56a08 A pa erteke a valtoztatas utan: 0xbfc56a04 A b cime: 0xbfc56a04 1.5.7. feladat A ppa-n keresztül változtassa meg b értékét: A b erteke a valtoztatas elott: 2 A b erteke a valtoztatas utan: 200 1.5.8. feladat Foglaljon le dinamikusan egy 10 elemű int tömböt! 1.5.9. feladat Szabadítsa fel az előbb lefoglalt tömböt! 1.5.10. feladat Lefoglalás után töltse fel a tömböt értékekkel! 1.5.11. feladat A lefoglalást, felszabadítást és feltöltést tegye külön függvénybe, de úgy, hogy a függvények visszatérési típusa void legyen! 1.5.12. feladat Rendezze a lefoglalt és feltöltött tömb elemeit növekvő sorrendbe! 1.5.13. feladat Írjon függvényt, amely az előbbi tömbből kigyűjti a páros számokat egy másik dinamikus tömbbe. Csak akkora legyen az új tömb, amennyi páros szám van az elsőben! 1.5.14. feladat Foglaljon le két dinamikus tömböt, töltse fel őket, majd hozzon létre egy harmadik dinamikus tömböt, és az tartalmazza a két előző tömb elemeit! Csak akkora legyen a harmadik tömb, amekkora szükséges! 1.5.15. feladat Az előző programot írja át úgy, hogy a harmadik tömb egyszer tartalmazzon minden elemet, és továbbra is akkora legyen a tömb, amennyi elem kerül bele! 1.5.16. feladat Az előző programot bővítse ki úgy, hogy az elemek rendezve kerüljenek a harmadik tömbbe! 1.5.17. feladat Írjon programot, amely n db dinamikus tömböt tárol, az első tömb 2, a második 4, azaz az i. tömb 2*i darab elemet tartalmazzon! Töltse is fel a tömböket!
47 1.5.18. feladat Az előző programot módosítsa úgy, hogy a lefoglalás, feltöltés és felszabadítás külön void visszatérési típusú függvényekkel történjen! 1.5.19. feladat Írjon programot, amely dinamikusan létrehoz egy n*m-es mátrixot, föltölti értékekkel, kiírja és felszabadítja. 1.5.20. feladat Az előző programot módosítsa úgy, hogy a lefoglalás, feltöltés és felszabadítás külön void visszatérési típusú függvényekkel történjen! 1.5.21. feladat Írjon programot, amely létrehoz kettő n méretű vektort, és összeadja őket, az eredmény egy újabb n méretű vektorba kerül. 1.5.22. feladat Írjon programot, amely létrehoz kettő n méretű vektort, és skalárisan összeszorozza őket. 1.5.23. feladat Írjon programot, amely létrehoz egy n*m-es dinamikus mátrixot, és egy m elemű oszlopvektort, feltölti őket, majd összeszorozza a mátrixot és a vektort. Az eredményt egy külön dinamikus vektorba írja, majd az eredményt jelenítse meg a képernyőn. 1.5.24. feladat Írjon programot, amely egy n*m és egy m*k méretű dinamikus mátrixot hoz létre, feltölti őket értékekkel, majd összeszorozza a két mátrixot. Az eredmény egy új, dinamikusan létrehozott mátrixba kerüljön. 1.5.25. feladat Írjon programot, amely egy n*n-es mátrixot hoz létre dinamikusan, majd létrehoz ebből egy (n-1)*(n-1)-es mátrixot, amely ugyanaz, mint az eredeti mátrix, de az i. sor és j. oszlop nélkül. Az i és j értékét billentyűzetről kérje be a program 1.5.26. feladat Írjon programot, amely egy dinamikusan létrehozott n*m-es mátrix transzponáltját hozza létre, az eredmény mátrix is dinamikusan legyen létrehozva. 1.5.27. feladat Írjon programot, amely 2 n*m-es, dinamikusan létrehozott mátrix összegeit számolja ki, az eredmény mátrix is dinamikusan legyen létrehozva. 1.5.28. feladat Írjon függvényt, amely egy 2*2-es mátrix determinánsát számolja ki. 1.5.29. feladat Írjon programot, amely kiszámolja egy dinamikusan létrehozott n*n-es mátrix adjungált mátrixát (a feladathoz érdemes felhasználni az előző feladatok megoldásait), az eredmény egy ujabb dinamikus mátrixba kerüljön. 1.5.30. feladat Írjon programot, amely, ha lehetséges, kiszámolja egy dinamikusan létrehozott n*n-es mátrix inverzét, és az eredmény egy újabb dinamikus mátrixba kerüljön. A program ezek után ellenőrizze le a számolás helyességét, azaz vizsgálja meg, hogy az eredeti és az inverz szorzata valóban egységmátrixot ad-e.
48 5. Mutatók 1.5.31. feladat Írjon programot, létrehoz egy 3 dimenziós, feltölti értékekkel, majd felszabadítja. 1.5.32. feladat Az előző programot módosítsa úgy, hogy a lefoglalás, feltöltés és felszabadítás külön void visszatérési típusú függvényekkel történjen! 1.5.33. feladat Az előző programot bővítse ki úgy, hogy a program keresse meg a legkisebb elemét, és írassa ki annak indexét. Amennyiben ez az elem többször fordul elő, akkor elég csak az elsőt megkeresni. 1.5.34. feladat Az előző programot bővítse ki úgy, hogy a program keresse meg a legkisebb elemet, és számolja meg, hogy mennyi ilyen elem van, és ezt írassa ki a képernyőre. 1.5.35. feladat Bővítse ki az előző programot úgy, hogy a legkisebb elemek indexeit gyűjtse ki egy 3*n méretű dinamikus tömbbe, ahol n a legkisebb elemek mennyisége. *1.5.36. feladat Írjon programot, amely dinamikusan egy tetszőleges dimenzió számú tömböt hoz létre, feltölti értékekkel, megjeleníti a képernyőn, majd felszabadítja. A program olvassa be billentyűzetről a dimenziók számát, majd a dimenziók méreteit. Az alábbi feladatok megoldásához ne használja a string.h header fájlt! 1.5.37. feladat Írjon programot, amely dinamikusan létrehoz, majd feltölt két stringet, kiírja, majd felszabadítja őket. 1.5.38. feladat Az előző programot bővítse ki úgy, hogy az egyik stringről készítsen másolatot, a másolat szintén egy dinamikusan létrehozott karaktertömb legyen. 1.5.39. feladat Az előző programot bővítse ki úgy, hogy a két stringet összefűzi, az eredményt egy harmadik, dinamikusan lefoglalt stringbe teszi. 1.5.40. feladat Írjon függvényt, amely két dinamikusan létrehozott stringről megállapítja, hogy egyenlőek-e. 1.5.41. feladat Írjon függvényt, amely két dinamikusan létrehozott stringről megállapítja, hogy melyik van előrébb az ABC-ben, a stringek csak az angol ABC kisbetűit tartalmazzák. 1.5.42. feladat Írjon függvényt, amely két dinamikusan létrehozott stringről megállapítja, hogy melyik van előrébb az ABC-ben, a stringek csak az angol ABC kis- és nagybetűit tartalmazzák, az egyes betűk kis és nagybetűs változatai azonosnak tekinthetőek, azaz az alma szó egyenrangú az AlMa szóval. 1.5.43. feladat Írjon függvényt, amely kap egy stringet, és egy i egész számot. A függvény megkeresi az i. szót a kapott stringben, lefoglal egy új dinamikus karaktertömböt, és abba kiírja a kert szót, majd visszatér az új stringgel. Ha nem létezik az i. szó, akkor a függvény NULL-al tér vissza.