Programozás alapjai C nyelv 4. gyakorlat Szeberényi Imre BME IIT <szebi@iit.bme.hu> Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -1- Mit tudunk már? Típus fogalma char, int, float, double változók deklarációja operátorok (aritmetikai, relációs, logikai, bitenkénti, léptető, értékadó, feltételes) kifejezés, utasítás, összetett utasítás vezérlési szerkezetek, ciklusok (if, while, do-while, for) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -2- Feltételes operátor (?:) kifejezés1? kifejezés2 : kifejezés3 Sorrend!! i kifejezés2 kifejezés1 n kifejezés3 Példák: a = a > b? a : b y = x == 3? x - 2 : z - 8 Olyan if, aminek értéke van. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -3-
Legnagyobb elem keresése Feladat: Fájl végéig, vagy amíg tudunk, olvassunk be számokat, határozzuk meg a legnagyobbat és írjuk ki, hogy hányadikként olvastuk be. Algoritmus emlékeztető: Mérleg Mindig a vizsgált elemekből válasszunk a hasonlításhoz elsőt! Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -4- Legnagyobb elem keresése(2) Vázlat: kezdeti beállítások /db = 0/ while olvas(x) db = db + 1 if db == 1 OR max < x max = x; dbmax = db kiír(max, dbmax) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -5- Legnagyobb elem keresése (3) #include <stdio.h> int main() { int x, max, dbmax, db = 0; while (scanf( %d,&x) == 1){ db++; if (db == 1 max < x){ max = x; dbmax = db; Kezdeti érték printf( Max.e. sorsz.: %d\n, dbmax); return 0; Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -6- ++ db = db + 1; vagy db += 1;
++ és -- operátor ++ inkrementáló (növelés eggyel) -- dekrementáló (csökkentés eggyel) Prefix ++i --i és postfix i++ i-- forma kifejezés (i = 5) kif. értéke i++ 5 6 i-- 5 4 ++i 6 6 --i 4 4 i értéke A különbség oka: a fő hatás és a mellékhatás bekövetkezésének különböző sorrendje. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -7- Prefix forma: ++ és -- operátor (2) int j, i = 2; j = ++i; 1. Mellékhatás: i értékét 1-gyel megnöveljük 2. Fő hatás: kiértékeljük az operandust: i-t, ami most 3, ez lesz a ++i kifejezés értéke 3. j-be a kiértékelt jobbérték kifejezés értékét, a 3-at másoljuk (értékadó operátor mellékhatása) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -8- Postfix forma: ++ és -- operátor (3) int j, i = 2; j = i++; 1. Fő hatás: kiértékeljük az operandust: i-t, ami most 2, ez lesz az i++ kifejezés értéke 2. Mellékhatás: i értékét 1-gyel megnöveljük 3. j-be a kiértékelt jobbérték kifejezés értékét, a 2-t másoljuk (értékadó operátor mellékhatása) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -9-
++ és -- operátor (4) Mikor melyik formát használjuk? A leggyakrabban csak az inkrementálás vagy dekrementálás miatt használjuk, a kiértékelés eredményét el is dobjuk - lásd a példát: db++; Itt tehát írhattuk volna azt is, hogy ++db; Ha összetett kifejezés része, nem mindegy! Ez egyébként illetlenség, mert nem átlátható a programkód működése. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -10- ++ és -- operátor (5) Gyakori fordulat a for ciklusban: Pl. a számjegyek kiíratása: char ch; for (ch = 0 ; /* inicializálás */ ch <= 9 ; /* feltétel vizsg.*/ printf( %c,ch++)) /* léptetés */ ; /* üres a ciklusmag, mert mindent elvégeztünk */ Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -11- Percedencia és asszociativitás Operátor Asszociativitás Sorrend () [] ->. balról jobbra! ~ ++ -- - (típus) * & sizeof jobbról balra * / balról jobbra + - balról jobbra << >> balról jobbra < < = > >= balról jobbra ==!= balról jobbra & balról jobbra ^ balról jobbra balról jobbra && balról jobbra balról jobbra?: jobbról balra = += -= *= /= &= = ^= stb. jobbról balra, balról jobbra Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -12-
Kiértékelés sorrendje sorrend!= asszociativitás A legtöbb magas szintű nyelv, így a C sem határozza meg a kiértékelés sorrendjét. Kivételek: && b értéke nem meghatározható!?:, Példa: a = b + b + (b = c); Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -13- Operátorok - összefoglalás (1) Amit az operátorokról tudni kell: Operandusok száma egy, pl.: + - sizeof & kettő, pl.: % / && & három? : Operandusok típusa - lásd a / műveletet Az eredmény típusa és értéke lásd a / műveletet lásd a logikai operátorokat Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -14- Operátorok - összefoglalás (2) Amit az operátorokról tudni kell: Precedencia Asszociativitás Kiértékelési sorrend Fő hatás, mellékhatás és ezek bekövetkezésének sorrendje lásd a ++ -- operátorkat Egyéb: pl. a kiértékelés leáll, ha triviális az eredmény Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -15-
Típuskonverziók egészek konverziója int = char vagy long = int értékadás - mindig OK char = int short = int int = long -OK, ha belefér signed = unsigned vagy unsigned = signed VIGYÁZNI! - előjelbit egész lebegőpontos konverziók int = double - OK, ha belefér, csonkolás double = int - mindig megy Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -16- Típuskonverziók (2) lebegőpontos konverzió double = float - mindig OK float = double - OK, ha belefér aritmetikai konverziók egészeknél: a legnagyobb ábrázolású egészre kiterjesztjük az operandusokat, az eredmény a legnagyobb értelmezésű operandus típusával fog megegyezni valósaknál: a műveleteket mindig double-ban végezzük Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -17- Típuskonverziók (3) Használjuk az explicit típusmódosító operátort; ez a C++ esetén majd igen hasznos lesz. Pl.: int a = 1, b = 2; double x; x = (double)(a); /* 1.0 lesz */ x = (double)(a)/(double)(b) /* 0.5 */ Általában: (új_típus)(régi_típusú_kifejezés) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -18-
Kalkulátor Feladat: Készítsünk egy egyszerű számológépet, ami beolvas 2 valós számot és egy műveleti jelet (+ - * /), és elvégzi a megfelelő műveletet. Vázlat (adatok): op1, op2 - valós operandusok muv - karakter e - valós eredmény Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -19- Kalkulátor (2) Vázlat (algoritmus): beolvas(op1, muv, op2) if muv == + e = op1 + op2 else if muv == -.... Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -20- Kalkulátor (3) #include <stdio.h> int main() { float op1, op2, e; muv char; Szóközök jelentősége scanf( %f %c %f, &op1, &muv, &op2); if (muv == + ) e = op1 + op2; else (if muv == - ) e = op1 - op2; else (if muv == * ) e = op1 * op2; else (if muv == / ) e = op1 / op2; else printf( mit_akarsz?\n ); printf( %f %c %f = %e\n ), op1, op2, e); return(0); Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -21-
if (kifejezés) utasítás else if (kifejezés) utasítás else utasítás Többszörös döntés Az else... if szerkezet gyakori, melynek egy speciális esete, amikor az elágazások konstans feltétel alapján történnek. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -22- A switch utasítás: A switch utasítás switch (kifejezés) { case konstans_kifejezés1: utasítások1 case konstans_kifejezés2: utasítások2... ut1 default: utasítások_n a kifejezés értékétől függően lép be, majd továbbfolyik ut2 ut3 ut4 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -23- Kalkulátor switch utasítással #include <stdio.h> int main() { float op1, op2, e; muv char; hogy ne folyjon tovább scanf( %f %c %f, &op1, &muv, &op2); switch (muv){ case + : e = op1 + op2; break; case - : e = op1 - op2; break; case * : e = op1 * op2; break; case / : e = op1 / op2; break; default: printf( mit_akarsz?\n ); printf( %f %c %f = %e\n ), op1, op2, e); return 0; Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -24-
A break és a continue break - azonnal kilép a ciklusból ill. switch-ből. continue - a következő iterációs lépéstől folytatja. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -25- int i; A break és a continue (2) for (i = 0; i++ < 10;){ if ((i & 1) = = 0) continue; printf( %d\n, i); ++ precedencia miatt Mit csinál ez a kódrészlet? Miért ilyen furcsa a for feje? Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -26- A break és a continue (2) Alakítsuk át continue-mentesre! int i; for (i = 0; i++ < 10;) if ((i & 1)!= 0) printf( %d\n, i); vagy for (i = 0; i++ < 10;) if (i%2) printf( %d\n ), i); Van, akinek continue nélkül követhetőbb a kód! Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -27-
Kötetlen formátum (WhereAmI) main(l,a,n,d)char**a;{ for(d=atoi(a[1])/10*80- atoi(a[2])/5-596;n="@nka\ CLCCGZAAQBEAADAFaISADJABBA^\ SNLGAQABDAXIMBAACTBATAHDBAN\ ZcEMMCCCCAAhEIJFAEAAABAfHJE\ TBdFLDAANEfDNBPHdBcBBBEA_AL\ H E L L O, W O R L D! " [l++-3];)for(;n-->64;) putchar(!d+++33^ l&1); Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -28- WhereAmI 47 19!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -29-