Informatika2-2013/Gyakorlat04
(→2. Kisebbek kiírása) |
(→Függvények) |
||
(egy szerkesztő 8 közbeeső változata nincs mutatva) | |||
34. sor: | 34. sor: | ||
double atlag(double a, int b){ | double atlag(double a, int b){ | ||
double x; | double x; | ||
− | x = a | + | x = (a + b) / 2; |
return x; | return x; | ||
</c> | </c> | ||
93. sor: | 93. sor: | ||
A main-ben ne felejtsétek el letesztelni a függvényeteket! | A main-ben ne felejtsétek el letesztelni a függvényeteket! | ||
+ | |||
== Pointerek == | == Pointerek == | ||
+ | |||
+ | * Próbáljátok ki az alábbi kódot: | ||
+ | |||
+ | <c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | void atir(int a){ | ||
+ | a = 5; | ||
+ | } | ||
+ | |||
+ | int main(void){ | ||
+ | int x = 8; | ||
+ | printf("eredeti: %d\n", x); | ||
+ | |||
+ | atir(x); | ||
+ | printf("atir utan: %d\n", x); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </c> | ||
+ | |||
+ | * Miért nem változott meg az értéke ''x''-nek? | ||
+ | |||
+ | * Válasz: nem az ''x'' mint változó lett átadva a függvénynek, hanem csak az értéke. Így amikor a függvény megváltoztatja 5-re, valójában csak egy lokális változó értéke változik 5-re, nem a main-ben szereplõ ''x''-é. | ||
+ | |||
+ | * Tekinthetjük ezt pozitívumnak, valamilyen szintû biztonságot adhat, de van amikor szükségünk van rá, hogy már létezõ változóink értékét egy függvény meg tudja változtatni, pl: scanf. | ||
+ | |||
+ | * Mit tudunk hát tenni? Ahelyett, hogy egy változó értékét adnánk át egy függvénynek, adjuk át a memóriában található helyét. Ha erre a helyre tudunk írni, és tudunk belõle olvasni, akkor minden meg van oldva. | ||
+ | |||
+ | * Így jönnek a képbe a pointerek. Amikor a scanf-nél & jelet teszünk a változók elé, valójában lekérjük a pointerüket (a memóriában található helyüket) és azt adjuk át a scanf-nek. | ||
+ | |||
+ | * Visszafelé alakítani is tudunk (pointerbõl kiolvasni az ott tárolt értéket) a *-al. | ||
+ | |||
+ | * Példák: | ||
+ | |||
+ | <c> | ||
+ | int *p; // Létrehozunk egy int pointert p névvel | ||
+ | int a = 5; | ||
+ | |||
+ | p = &a; // Az a változó pointerét eltároljuk p-ben | ||
+ | scanf("%d", p); // Így például az a változóba olvasnánk be | ||
+ | |||
+ | printf("%d", *p); // Ezzel pedig az a értékét írnánk ki | ||
+ | |||
+ | *p = 15; // Pointeren keresztül értéket is átírhatunk | ||
+ | printf("%d", a); // Így ez mostmár 15-öt adna ki | ||
+ | </c> | ||
+ | |||
+ | * Példa egy függvényre ami megcseréli két változó értékét: | ||
+ | |||
+ | <c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | void swap(int *a, int *b){ | ||
+ | int temp; | ||
+ | temp = *a; | ||
+ | *a = *b; | ||
+ | *b = temp; | ||
+ | } | ||
+ | |||
+ | int main(void){ | ||
+ | int x = 8; | ||
+ | int y = 15; | ||
+ | |||
+ | printf("x: %d, y: %d\n", x, y); | ||
+ | |||
+ | swap(&x, &y); | ||
+ | printf("x: %d, y: %d\n", x, y); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </c> | ||
+ | |||
+ | * Zárszóként az elmélethez még annyit tennék hozzá (ez késõbbi gyakokon remélhetõleg részletesebben megjelenik), hogy a tömbök valójában pointerek. A t[0] egyenértékû a *t-vel és a t[1] egyenértékû a *(t + 1)-el (utóbbi a t pointertõl 1 adat méretû távolságra levõ pointert adja). | ||
+ | |||
+ | |||
+ | == Feladatok 2 == | ||
+ | |||
+ | === 3. Hatványozó pointerekkel === | ||
+ | |||
+ | Írd át a hatványozó függvényt, hogy pointerekkel kapja meg az alapot és kitevõt! (És természetesen továbbra is jól számoljon.) | ||
+ | |||
+ | |||
+ | === 4. Hatványozó pointerekkel 2 === | ||
+ | |||
+ | Most oldd meg, hogy a kiszámolt értéket ne visszaadja a függvény, hanem egy 3. paraméterként pointerrel adott int-be másolja. | ||
+ | |||
+ | |||
+ | === 5. Tömb min és max === | ||
+ | |||
+ | Írj függvényt, ami megkeresi egy adott double tömb minimumát és maximumát is, és pointerek segítségével adja vissza. | ||
+ | |||
+ | Bemenet: double tömb, double min pointer, double max pointer | ||
+ | |||
+ | Használhatjátok a korábbi double tömböt: | ||
+ | |||
+ | <c> | ||
+ | double tomb[10] = { 2.5, 7.6, 1.2, -8.9, 4.6, -4.8, 12.4, 1.1, 3.5, -6.7 }; | ||
+ | </c> | ||
+ | |||
+ | Érdemes még meggondolni, hogy amikor függvényekben dolgozunk tömbökkel, akkor hasznos lehet átadni a tömbök méretét a függvénynek, hogy általánosabb függvényt írhassunk. |
A lap jelenlegi, 2013. március 5., 12:10-kori változata
Tartalomjegyzék |
Ismétlés
- Típusok, ezek megjelenítése és beolvasása.
- Nem hétköznapi vezérlési szerkezetek, break, continue.
- Tömbök létrehozása:
int t[30];
- Tömb elemnek értékadás:
t[6] = 54;
- Természetesen változókat is lehet használni a tömb indexénél (ami 0-tól n-1-ig megy, ahol n a tömb mérete):
int i; for(i = 0; i < 30; i++){ t[i] = 0; }
Függvények
- A következõképpen definiálhatunk egy függvényt:
v_ért fv_név(p_típus1 p_név1, p_típus2 p_név2){ /* */ return érték; }
- Ahol v_ért a visszatérési érték típusa, fv_név a függvény neve (ezzel tudjuk majd meghívni), p_típus1 az elsõ paraméter típusa, p_név1 az elsõ paraméter neve, stb. A függvénynek mindenképpen olyan típusú adatot kell visszaadnia, mint a visszatérési értéke.
- Egy függvény visszatérési értéke lehet void, ekkor nem kell visszaadnia értéket, valamint nem feltétlen kell, hogy legyen paramétere, ekkor a zárójelek közé írhatunk void-ot, vagy hagyhatjuk üresen.
- Példa egy függvényre:
double atlag(double a, int b){ double x; x = (a + b) / 2; return x;
- Ez a függvény az elsõként beadott double típusú számnak és a másodikként adott int-nek az átlagát adja vissza. Egy hívásra példa:
int g = 5; double er; er = atlag(5.4, g);
- Amint már korábban is láttuk függvényhívásokban használhatunk változókat, de konstansokat is.
- Az elõzõ függvényt írhattuk volna ilyen egyszerûbb alakban is:
double atlag(double a, int b){ return a / b;
- Függvényhívást használhatunk egy függvény argumentumaként is (hisz valójában egy érték) pl:
printf("%lf", atlag(3.2, 6));
Feladatok 1
1. Hatványozó függvény
Írjatok függvényt, ami hatványoz. Bemenete két int a és n, visszatérési értéke pedig az a^n (a az n-ediken).
Használjátok a következõ main-t hozzá (a megírandó függvényt az include és a main közé írjátok):
#include <stdio.h> int main(void){ int x; int y; scanf("%d %d", &x, &y); printf("%d\n", /* Ide jon a fuggvenyetek hivasa x es y-al */); return 0; }
2. Intervallumba esõk kiírása
Írjatok függvényt, ami bemenetként kap egy double tömböt és két int-et és kiírja printf-el a tömb azon elemeit amik beleesnek az adott int-ek által meghatározott intervallumba.
Függvényeknek tömböt a következõ módon (is) átadhattok (az elsõ paraméter a tömb):
void fv(int t[], int v){...}
A main függvényetek megírásában használjátok a következõ tömböt az egyszerûség kedvéért (így lehet egyszerre megadni egy tömb elemeit, a []-be nem is kell feltétlen beleírni az elemszámot):
double tomb[10] = { 2.5, 7.6, 1.2, -8.9, 4.6, -4.8, 12.4, 1.1, 3.5, -6.7 };
A main-ben ne felejtsétek el letesztelni a függvényeteket!
Pointerek
- Próbáljátok ki az alábbi kódot:
#include <stdio.h> void atir(int a){ a = 5; } int main(void){ int x = 8; printf("eredeti: %d\n", x); atir(x); printf("atir utan: %d\n", x); return 0; }
- Miért nem változott meg az értéke x-nek?
- Válasz: nem az x mint változó lett átadva a függvénynek, hanem csak az értéke. Így amikor a függvény megváltoztatja 5-re, valójában csak egy lokális változó értéke változik 5-re, nem a main-ben szereplõ x-é.
- Tekinthetjük ezt pozitívumnak, valamilyen szintû biztonságot adhat, de van amikor szükségünk van rá, hogy már létezõ változóink értékét egy függvény meg tudja változtatni, pl: scanf.
- Mit tudunk hát tenni? Ahelyett, hogy egy változó értékét adnánk át egy függvénynek, adjuk át a memóriában található helyét. Ha erre a helyre tudunk írni, és tudunk belõle olvasni, akkor minden meg van oldva.
- Így jönnek a képbe a pointerek. Amikor a scanf-nél & jelet teszünk a változók elé, valójában lekérjük a pointerüket (a memóriában található helyüket) és azt adjuk át a scanf-nek.
- Visszafelé alakítani is tudunk (pointerbõl kiolvasni az ott tárolt értéket) a *-al.
- Példák:
int *p; // Létrehozunk egy int pointert p névvel int a = 5; p = &a; // Az a változó pointerét eltároljuk p-ben scanf("%d", p); // Így például az a változóba olvasnánk be printf("%d", *p); // Ezzel pedig az a értékét írnánk ki *p = 15; // Pointeren keresztül értéket is átírhatunk printf("%d", a); // Így ez mostmár 15-öt adna ki
- Példa egy függvényre ami megcseréli két változó értékét:
#include <stdio.h> void swap(int *a, int *b){ int temp; temp = *a; *a = *b; *b = temp; } int main(void){ int x = 8; int y = 15; printf("x: %d, y: %d\n", x, y); swap(&x, &y); printf("x: %d, y: %d\n", x, y); return 0; }
- Zárszóként az elmélethez még annyit tennék hozzá (ez késõbbi gyakokon remélhetõleg részletesebben megjelenik), hogy a tömbök valójában pointerek. A t[0] egyenértékû a *t-vel és a t[1] egyenértékû a *(t + 1)-el (utóbbi a t pointertõl 1 adat méretû távolságra levõ pointert adja).
Feladatok 2
3. Hatványozó pointerekkel
Írd át a hatványozó függvényt, hogy pointerekkel kapja meg az alapot és kitevõt! (És természetesen továbbra is jól számoljon.)
4. Hatványozó pointerekkel 2
Most oldd meg, hogy a kiszámolt értéket ne visszaadja a függvény, hanem egy 3. paraméterként pointerrel adott int-be másolja.
5. Tömb min és max
Írj függvényt, ami megkeresi egy adott double tömb minimumát és maximumát is, és pointerek segítségével adja vissza.
Bemenet: double tömb, double min pointer, double max pointer
Használhatjátok a korábbi double tömböt:
double tomb[10] = { 2.5, 7.6, 1.2, -8.9, 4.6, -4.8, 12.4, 1.1, 3.5, -6.7 };
Érdemes még meggondolni, hogy amikor függvényekben dolgozunk tömbökkel, akkor hasznos lehet átadni a tömbök méretét a függvénynek, hogy általánosabb függvényt írhassunk.