Programozás alapjai C nyelv 4. gyakorlat Szeberényi Imre BME IIT <szebi@iit.bme.hu> 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,, összetett vezérlési szerkezetek, ciklusok (if, while, do-while, for) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -1- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -2- Feltételes operátor (?:) Legnagyobb elem keresése kifejezés1? kifejezés2 : kifejezés3 i kifejezés1 Sorrend!! kifejezés2 n kifejezés3 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. Példák: a = a > b? a : b y = x == 3? x - 2 : z - 8 Olyan if, aminek értéke van. 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.. -3- 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) 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) ++ é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.. -9- 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 */ 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.. -11- 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); 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.. -13- 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 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.. -19- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.10.10.. -20- float op1, op2, e; muv char; Kalkulátor (3) 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) else if (kifejezés) else 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 : A switch switch (kifejezés) case konstans_kifejezés1: ok1 case konstans_kifejezés2: ok2... ut1 default: ok_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 sal 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. 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.. -25- 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-