Programozás alapjai C nyelv 7. gyakorlat Szeberényi Imre BME IIT
<
[email protected]>
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
-1-
2005.11.05.
-2-
Függvények • C program egymás mellé rendelt függvényekből áll. • A függvény (alprogram) jó absztrakciós eszköz a programok tervezésénél.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
Függvények(2) • Függvények által használt / előállított adatokat a függvény interfészén keresztül adjuk át. • A C nyelvben csak érték szerinti paraméterátadás van.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
-3-
1
LNKO függvény Feladat: • Írjunk függvényt két egész szám legnagyobb közös osztójának kiszámítására • Be: 2 db egész • Ki: 1 db egész • Algoritmus: euklideszi algoritmus
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
-4-
2005.11.05.
-5-
LNKO függvény (2) Függvény deklaráció v. prototípus: int lnko(int x, int y);
Algoritmus: while x != y nagyobb számból kivonjuk a kisebbet
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
LNKO függvény (3) Függvény definíció: int lnko(int x, int y) { while (x != y) if (x > y) x -= y; else y -= x; return(x); } Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
-6-
2
LNKO fájl végéig Feladat: Fájl végéig, olvassunk be számpárokat, és határozzuk meg a legnagyobb közös osztójukat! Vázlat: Külön tesztelhető, újból felhasználható while olvas(x, y) kiír lnko(x, y) Funkcionális dekompozíció Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
-7-
LNKO fájl végéig (2) #include <stdio.h> int lnko(x, y);
Feltételezzük, hogy az input sorozat helyes (csak számpárokat tartalmaz)
int main() { int x, y; while (scanf(”%d %d”,&x, &y) != EOF) printf(”LNKO(%d,%d)=%d\n”, x, y, lnko(x, y)); return(0); } Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
-8-
C program szerkezete újból • Egymás mellé rendelt ún. külső objektumokból (függvény és változó) áll. – Külső - nem függvény belsejében – Belső - függvények belsejében
• A függvények paramétereken, függvényértékeken, vagy külső adatokon keresztül kommunikálhatnak egymással.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
-9-
3
C program szerkezete újból (2) int alma;
Külső objektum
Paraméter
int lnko(int x, int y) { Lokális változó int i = 3; while (x != y) if (x > y) x -= y; else y -= x; alma = 23; return x; }
Mi az objektumok érvényessége? (alma, x, i, y, lnko, main)
main() Függvényérték Akt. paraméter { int x = 8, i = 24; printf(”%d %d\n”, alma, lnko(x, i)); }
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 10 -
Érvényességi tartomány • Lexikális érvényességi tartomány.
(Programszöveg azon része, ahol az azonosító ismert és tulajdonságai meghatározottak.) – külső: a fordítási egység végéig – blokk: a blokk végéig – különböző névterek vannak (függvények, typedef, cimkék, felsorolások, struktúrák stb.)
• Külső csatolású objektumok érvényességi tartománya. (A fordítási egységek közötti kapcsolatot határozza meg.)
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 11 -
Lexikális érvényességi tartomány int alma;
Ford. egységben
Blokkban
int lnko(int x, int y) Nem ua. a változó! { int i = 3; while (x != y) if (x > y) x -= y; else y -= x; i = alma; return x; } Ua. a változó! main() { int x = 8, i = 24; printf(”%d %d\n”, alma, lnko(x, i)); }
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 12 -
4
C program szerkezete újból (3) • Különböző fordítási egységek lehetnek. • Az egyes fordítási egységek közötti kapcsolatot interfész definíciók teremtik meg, melyeket ún. header állományokban szokás megadni. (Nem kötelező, de...)
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 13 -
C program szerkezete újból (4) #include ”rendez.h” main () { ... Kiir(t, n); void Kiir(int a[],int n); #include ”rendez.h” void Kiir(int a[],int n) { ... Programozás alapjai I. (C nyelv, gyakorlat)
beszurte.c (főprogram, rendező és kiíró függvények használata) rendez.h (interfész definíciók, konstansok) rendez.c (rendező és kiíró függvények megvalósítása)
© BME-IIT Sz.I.
2005.11.05.
- 14 -
Függvényparaméterek Definíció ill. felhasználás szintjén – formális pl: int Kiir(int a[], int n); – aktuális pl: Kiir(t, 23); void Kiir(int a[], int n) { int i; for (i = 0; i < n; i++) printf("%5d", a[i]); n = 0; }
A formális paraméterre úgy hivatkozhatunk, mint egy változóra. Átadhatjuk egy másik függvénynek aktuális paraméterként.
Meg is változtathatjuk Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 15 -
5
Függvényparaméterek (2) • Információátadás szintjén – érték (csak befelé) – változó (be és ki)
• C nyelvben csak értékparaméter van. Mégis hogyan működik a BeszuroBinker vagy pl. a scanf ?
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 16 -
Értékparaméter • A paraméterek nem változhatnak meg, mivel azok értéke adódik át. • Azok eredeti tartalma az eredeti helyen megmarad. • A függvény csak a függvényértéken keresztül tud a külvilágnak eredményt szolgáltatni. (Ez sokszor kevés.)
érték
változó v. konstans
fv.érték
függvény
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 17 -
Változóparaméter
cím
változó
fv.érték
függvény
• A paraméter címe adódik át, így annak tartalma felhasználható, de • meg is változtatható. • A magas szintű nyelvek elfedik ezt a trükköt. Sem az aktuális paraméterek átadásakor, sem a formális paraméterekre való hivatkozáskor nem kell jelölni. • Csupán a paraméter jellegét (változó) kell megadni a definíciókor.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 18 -
6
Változóparaméter a C-ben void KozKi(int a[], int n) { • C nyelvben a tömb int i, j, x; for (i = 1; i < n; i++){ k = i; x = a[i]; for (j = i+1; j<= n; j++) if (a[j] < x) { • k = j; x = a[j]; } a[k] = a[i]; a[i] = x; } }
átadásától eltekintve jelölni kell a cím átadását és használatát (az indirekciót). Ebben a formában a tömb átadása változóparaméter átadásának fogható fel.
A tömb címe adódik át és nem maga a tömb!
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 19 -
Változóparaméter helyett cím int add(int a, int b, int *ab2) { *ab2 = a * a + b * b; return (a + b); Címet várunk } main() { int x, y;
}
Indirekció Változó címét adjuk át
y = add(2, 3, &x); y = add(2, 3, x);
Programozás alapjai I. (C nyelv, gyakorlat)
Változó értékét adjuk át, ami egy integer!!
© BME-IIT Sz.I.
2005.11.05.
- 20 -
Változóparaméter helyett cím (2) void KozKi(int *a, int n) { int i, j, x; for (i = 1; i < n; i++){ k = i; x = a[i]; for (j = i+1; j<= n; j++) if (a[j] < x) { k = j; x = a[j]; } a[k] = a[i]; a[i] = x; } } Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
Címet várunk Ez is indirekció
2005.11.05.
- 21 -
7
Összetartozó adatok tárolása • A tömbök segítségével azonos típusú adatokat tudunk kezelni. Ezek többnyire nem tartoznak össze. • Gyakran előfordul, hogy az adatok összetartozása a fontos, és ezért együtt szeretnénk kezelni azokat. Ezek lehetnek – azonos típusúak pl: pontok koordinátai, komplex számok stb – eltérő típusúak pl: személyi adatok, számlák adatai stb. Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 22 -
Struktúra Összetartozó adatok tárolására alkalmas összetett adattípus. struktúra_spec: struct struct_tip_azonopc { dekl_lista } struct { float re, im; } k1, k2, k3[12]; struct hallgato { char nev[40]; int tk; float odij; } h1, h2, h3[10]; Programozás alapjai I. (C nyelv, gyakorlat)
k1.re = 1.3; k3[0]= k2; k3[1].im = 0; struct hallgato h4; h1.tk = 8; h2.nev[0] == ’A’; h3[1] = h4; © BME-IIT Sz.I.
2005.11.05.
- 23 -
Struktúra (2) • Értékkészlet - tagok értékkészletéből • Konstansok - tagok konstansaiból • Művelethalmaz – értékadás – szelekció (hivatkozás egy str. tagra) – átadhatjuk fv. paraméterként – hivatkozhatunk a címére – más művelete nincs !!!
• Lehet struct típusú függvény! Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 24 -
8
Változók kezdeti értéke • Külső és statikus változók garantáltan nulla kezdeti értéket kapnak, ha nincs explicit inicializálás. • Explicit inicializálás hiányában az automatikus és regiszter típusú változók kezdeti értéke meghatározatlan.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 25 -
Változók kezdeti értéke (2) • A változók a definíciójukkal együtt inicializálhatók. (int i = 23) – Külső és statikus változóknak csak konstans kezdeti érték adható és csak egyszer kapnak értéket a program kezdete előtt. – Automatikus és regiszter változók nem csak konstans értékkel inicializálhatók. (int j = a)
• Struktúra ill. tömb jellegű változók ún. agregátummal inicializálhatók. ( {} ) Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 26 -
Változók kezdeti értéke (3) • Összetett adatszerkezetek esetén ún. adatelemkijelölőket lehet használni a megfelelő elem kiválasztásához. Pl: struct komplex_str { Borland C float re, im; nem ismeri ! } kt[100] = { [12].im = 8.2, [23] = {3., 2.1 } }; struct komplex_str k = { .im = 8.1 };
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 27 -
9
Rendezzük sorba: 9, 2, 5, 3, -12 • Beszúró – rendezett halmazt bővítjük
• Közvetlen csere – buborék
• Közvetlen kiválasztás – legkisebbet v. legnagyobbat kiválasztjuk a maradékból
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 28 -
Beszúró rendezés A már rendezett halmazba beszúrjuk a következő elemet: for i = 2 to n a[i] beszúrása az a[1]…a[i-1] halmazba
i=2
9
2
5
3
-12
1.
2.
3.
4.
5.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 29 -
Beszúró rendezés A már rendezett halmazba beszúrjuk a következő elemet: for i = 2 to n a[i] beszúrása az a[1]…a[i-1] halmazba
i=3
2
9
5
3
-12
1.
2.
3.
4.
5.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 30 -
10
Beszúró rendezés A már rendezett halmazba beszúrjuk a következő elemet: for i = 2 to n a[i] beszúrása az a[1]…a[i-1] halmazba
i=4
2
5
9
3
-12
1.
2.
3.
4.
5.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 31 -
Beszúró rendezés A már rendezett halmazba beszúrjuk a következő elemet: for i = 2 to n a[i] beszúrása az a[1]…a[i-1] halmazba
i=5
2
3
5
9
-12
1.
2.
3.
4.
5.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 32 -
Beszúró rendezés A már rendezett halmazba beszúrjuk a következő elemet: for i = 2 to n a[i] beszúrása az a[1]…a[i-1] halmazba
-12
2
3
5
9
1.
2.
3.
4.
5.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 33 -
11
Beszúró rendezés for (i = 2; i <= n; i++) { x = a[i]; j = i-1; while (j > 0 && a[j] > x) { a[j+1] = a[j]; j--; } 2 5 a[j+1] = x; } 1. 2.
kiértékelés sorrendje
9
3
-12
3.
4.
5.
A 0. elemet nem használjuk, ezért eggyel több elemet kell foglalnunk! C sajátosság, hogy az index mindig 0-tól megy!!! Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 34 -
Beszúró r. strázsa elemmel for (i = 2; i <= n; i++) { a[0] = a[i]; j = i-1; while (a[j] > a[0]) { a[j+1] = a[j]; j--; } a[j+1] = a[0]; }
Programozás alapjai I. (C nyelv, gyakorlat)
feltétel egyszerűsödött
-12 2 5 3
-12 9 2
9 5 3 2
9 5 3
0.
1.
2.
3.
© BME-IIT Sz.I.
3 9 5
-12 9
4.
5.
2005.11.05.
- 35 -
Beszúró r. strázsa elemmel (2) for (i = 2; i <= n; i++) { for (a[0] = a[i], j = i-1; a[j] > a[0]; j--) a[j+1] = a[j]; a[j+1] = a[0]; }
vessző operátor
logikailag a ciklushoz tartozik a kezdeti beállítás
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 36 -
12
Beszúró r. bináris kereséssel for (i = 2; i <= n; i++) { x = a[i]; l = 1; r = i-1; while (l <= r) { m = (l+r) / 2; if (x < a[m]) r = m-1; else l = m+1; } for (j = i-1; j >= l; j--) a[j+1] = a[j]; a[l] = x; 2 3 } 1. Programozás alapjai I. (C nyelv, gyakorlat)
már rendezett
5
2.
3.
© BME-IIT Sz.I.
9
-12
4.
5.
2005.11.05.
- 37 -
Beszúró r. bináris kereséssel (2) for (i = 1; i < n; i++) { x = a[i]; l = 0; r = i-1; while (l <= r) { m = (l+r) / 2; if (x < a[m]) r = m-1; else l = m+1; } for (j = i-1; j >= l; j--) a[j+1] = a[j]; a[l] = x; } Programozás alapjai I. (C nyelv, gyakorlat)
A 0. elemet is használjuk!
© BME-IIT Sz.I.
2005.11.05.
- 38 -
Közvetlen kiválasztás for i = 1 to n-1 k = legkisebb_elem_indexe(i,n) a[k] cseréje a[i]-vel
i=1 k=5
9
2
5
3
-12
1.
2.
3.
4.
5.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 39 -
13
Közvetlen kiválasztás for i = 1 to n-1 k = legkisebb_elem_indexe(i,n) a[k] cseréje a[i]-vel
i=2 k=2
-12
2
5
3
9
1.
2.
3.
4.
5.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 40 -
Közvetlen kiválasztás for i = 1 to n-1 k = legkisebb_elem_indexe(i,n) a[k] cseréje a[i]-vel
i=3 k=4
-12
2
5
3
9
1.
2.
3.
4.
5.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 41 -
Közvetlen kiválasztás for i = 1 to n-1 k = legkisebb_elem_indexe(i,n) a[k] cseréje a[i]-vel
i=4 k=4
-12
2
3
5
9
1.
2.
3.
4.
5.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 42 -
14
Közvetlen kiválasztás for i = 1 to n-1 k = legkisebb_elem_indexe(i,n) a[k] cseréje a[i]-vel
-12
2
3
5
9
1.
2.
3.
4.
5.
Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
2005.11.05.
- 43 -
Közvetlen kiválasztás for (i = 1; i <= n-1; i++) { k = i; x = a[i]; for (j = i+1; j <= n; j++) if (a[j] < x) { k = j; x = a[j]; } a[k] = a[i]; a[i] = x; } i=3 k=4
Programozás alapjai I. (C nyelv, gyakorlat)
-12
2
5
3
9
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 44 -
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
i=2 j=5
Programozás alapjai I. (C nyelv, gyakorlat)
9
2
5
3
-12
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 45 -
15
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
i=2 j=4
Programozás alapjai I. (C nyelv, gyakorlat)
9
2
5
-12
3
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 46 -
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
i=2 j=3
Programozás alapjai I. (C nyelv, gyakorlat)
9
2
-12
5
3
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 47 -
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
i=2 j=2
Programozás alapjai I. (C nyelv, gyakorlat)
9
-12
2
5
3
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 48 -
16
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
i=3 j=5
Programozás alapjai I. (C nyelv, gyakorlat)
-12
9
2
5
3
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 49 -
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
i=3 j=4
Programozás alapjai I. (C nyelv, gyakorlat)
-12
9
2
3
5
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 50 -
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
i=3 j=3
Programozás alapjai I. (C nyelv, gyakorlat)
-12
9
2
3
5
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 51 -
17
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
i=4 j=5
Programozás alapjai I. (C nyelv, gyakorlat)
-12
2
9
3
5
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 52 -
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
i=4 j=4
Programozás alapjai I. (C nyelv, gyakorlat)
-12
2
9
3
5
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 53 -
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
i=5 j=5
Programozás alapjai I. (C nyelv, gyakorlat)
-12
2
3
9
5
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 54 -
18
Közvetlen csere (buborék) for i = 2 to n for j = n downto i if a[j-1] > a[j] a[j-1] a[j]
Programozás alapjai I. (C nyelv, gyakorlat)
-12
2
3
5
9
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 55 -
Közvetlen csere (buborék) for (i = 2; i <= n; i++) for (j = n; j >= i; j--) if (a[j-1] > a[j]) { x = a[j-1]; a[j-1] = a[j]; a[j] = x } i=2 j=3
Programozás alapjai I. (C nyelv, gyakorlat)
9
2
-12
5
3
1.
2.
3.
4.
5.
© BME-IIT Sz.I.
2005.11.05.
- 56 -
Közvetlen csere (javított) i = 2; do { cserelt = 0; for (j = n; j >= i; j--) if (a[j-1] > a[j]) { x = a[j-1]; a[j-1] = a[j]; a[j] = x cserelt = 1; } i = i + 1; while (i <= n) && cserelt; Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
logikai változó!
2005.11.05.
- 57 -
19
Közvetlen csere (javított) (2) i = 1; do { cserelt = 0; for (j = n-1; j >= i; j--) if (a[j-1] > a[j]) { x = a[j-1]; a[j-1] = a[j]; a[j] = x cserelt = 1; } i = i + 1; while (i < n) && cserelt; Programozás alapjai I. (C nyelv, gyakorlat)
© BME-IIT Sz.I.
A 0. elemet is használjuk!
2005.11.05.
- 58 -
20