Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

dr Póder Margit f. docens Rendszer- és Szoftvertechnológia Tanszék

Hasonló előadás


Az előadások a következő témára: "dr Póder Margit f. docens Rendszer- és Szoftvertechnológia Tanszék"— Előadás másolata:

1 dr Póder Margit f. docens Rendszer- és Szoftvertechnológia Tanszék
Programozás I dr Póder Margit f. docens Rendszer- és Szoftvertechnológia Tanszék

2 1.6. Operátorok és kifejezések
Aritmetikai kifejezések: egyetlen operandusból vagy az operandusok és műveleti jelek (operátorok) kombinációjából épülnek fel. Az operandusok a C nyelv azon elemei, melyeken az operátorok fejtik ki hatásukat. Az operandusok száma szerint vannak egyoperandusú és kétoperandusú operátorok. egyoperandusú (unary) operátorok esetén a kifejezés általános alakja: op operandus (prefix alak) vagy operandus op (postfix alak) Példák: -a ++a &a a++ - kétoperandusú operátorok esetén a kifejezés általános alakja: operandus1 op operandus Példák: a + b a * b a < b a+ = b

3 1.6.1. Elsődleges operátorok
(), [ ], ->, . Ezekkel az operátorokkal a későbbiekben ismerkedünk meg, hozzájuk speciális C nyelvi szerkezetek kapcsolódnak, mint például a függvény hívás, tömb indexelés, struktúratagra való hivatkozás.

4 1.6.2. Aritmetikai operátorok
Ide tartoznak: mínusz (-), összeadás (+), kivonás (-), szorzás (*), osztás (/), maradék (%) A mínusz (-) egyoperandusú operátor, segítségével a mögötte álló operandus értéke ellentétes előjelűre változtatható. A maradék képzés operátora csak egész típusú operandusokra alkalmazható, a többi aritmetikai művelet operandusai egész és lebegőpontos típusú operandusokra is alkalmazhatóak. Az osztás egész típusú operátorok esetén egész osztást jelöl: a 17 / 5 kifejezés értéke (a hányados) 3 a 17 % 5 kifejezés értéke (a maradék) 2

5 1.6.3. Összehasonlító és logikai operátorok
A C nyelvben nincs logikai típus, azonban vannak olyan utasításai, amelyekben feltételeket kell definiálnunk. A feltételek tetszőleges kifejezések lehetnek. A C++ az igazat bármely nem nulla értékként, a hamisat pedig 0-ként ábrázolja. A relációs kifejezés általános alakja: kifejezés1 relációs operátor kifejezés2 A relációs kifejezés értéke integer típusú és értéke 1, ha a reláció igaz, 0 ha a reláció nem igaz.

6 Összehasonlító (relációs) operátorok:
Operátor Példa (relációs kifejezés) Jelentés < a < b a kisebb, mint b <= a <= b a kisebb vagy egyenlő mint b > a > b a nagyobb, mint b >= a >= b a nagyobb vagy egyenlő mintb == a == b a egyenlő (e) b-vel != a != b a nem egyenlő b-vel

7 Logikai operátorok a C-ben: negáció(
Logikai operátorok a C-ben: negáció(!), konjunkció(&&), diszjunkció (||) A művelet eredménye int típusú,0 vagy 1 értékű. A C-ben nincs logikai változó, NINCS logikai IGAZ illetve HAMIS Az operandusok egész típusúak. A logikai operátorok működését ún. igazságtáblával írjuk le.

8 Negáció (logikai tagadás) a C-ben
Műveleti jel : ! Egyoperandusos operátor Igazságtábla: a !a Nem 0 1

9 Konjunkció (logikai ÉS) a C-ben
Kétoperandusú operátor, műveleti jel: && Igazságtábla: kif1 kif2 kif1&&kif2 Nem 0 1

10 Diszjunkció (logikai VAGY) a C-ben
Kétoperandusú operátor, műveleti jel: || Igazságtábla: kif1 kif2 kif1||kif2 Nem 0 1

11 1.6.4. Léptető operátorok: increment (++), decrement (--)
Mindkét operátor használható prefixes (pl. ++a, --a), illetve postfixes (pl. a++, a--) alakban:

12 Bitműveletek Bitenkénti műveleteket a C-ben char, short, int és long típusú adatokon végezhetünk. Bitenkénti logikai műveletek: Operátor Művelet ~ 1-es komplemens & bitenkénti ÉS | bitenkénti VAGY ^ bitenkénti kizáró vagy Igazságtábla : ld. jegyzet ! Bitenkénti logikai műveletek segítik a számítógép hardver elemeinek programozását. Maszkolás: bitek beállítása, illetve törlése.

13 ax = 2001 (0x07D1) maszk = 0x0006 ax | maszk = 0x07D7
Bitek 1-be állítása A maszk 1-et tartalmaz mindazon bitpozíciókban, ahol a beállítást el kell végezni. A beállítást ezután a bitenkénti VAGY művelettel lehet elvégezni. A maszkot 16-os számrendszerbeli konstansként kell felírni, mivel a C-ben nem lehet kettes számrendszerben megadni konstansokat. Figyeljük meg a bitek szintjén a művelet elvégzését:. ax = (0x07D1) maszk = 0x0006 ax | maszk = 0x07D7 Ld.: mintapélda !

14 ax = 2007 (0x07D7) maszk = 0xFFF9 ax & maszk = 0x07D1
Bitek törlése Bitek törlése esetén a maszkban azokba a pozíciókba, ahol a törlendő bitek állnak, 0-t teszünk, a többi helyre 1-et. A bitek törlése ezután a bitenkénti ÉS művelet segítségével történhet. Az előbbi példát alapul véve, töröljük az ax éppen beállított 1. és 2. bitjét ! Figyeljük meg a bitek szintjén a művelet elvégzését. A maszk az előbbi példában használtnak épp az ellentettje. ax = (0x07D7) maszk = 0xFFF9 ax & maszk = 0x07D1 xx

15 A kizáró vagy művelet használata
A kizáró VAGY művelet érdekes tulajdonsága, hogy ugyanazt a maszkot kétszer egymás után használva visszakapjuk az eredeti értéket. Így ez a művelet jól felhasználható titkosításra, bitek ki-be kapcsolására.

16 Biteltoló (shift) műveletek: eltolás balra (<<) és jobbra (>>)
A művelet általános alakja: operandus1 shift operátor operandus2 A művelet során a baloldali operandus bitjei annyiszor lépnek balra (jobbra), amennyi a jobboldali operandus értéke. A felszabaduló bitpozíciókba nullák kerülnek, míg a kilépő bitek elvesznek. Példa: int a = 3; // a << 2; //

17 Értékadó operátorok Az értékadás egy olyan kifejezés, amely a baloldali operandus által kijelölt objektumnak adja a jobboldalon megadott kifejezés értékét, amely érték egyben az értékadó kifejezés értéke is. Nézzük az alábbi példát (a integer típusú változó) a = (2 + 5) * 10; A jobboldali kifejezés értéke 70, így a értéke 70 lesz. Az értékadó operátorok kiértékelése jobbról balra haladva történik, emiatt a C nyelvben használható a többszörös értékadás, melynek során több változó veszi fel ugyanazt az értéket: a = b = c = 15;

18 Értékadó operátorok Ha az értékadó operátor két oldalán nem azonos típusok állnak, akkor először megtörténik a jobboldalon álló kifejezés kiértékelése, majd az eredmény átalakul a baloldal típusának megfelelően. Az alábbi példában a float típusú a változó értéke 2 lesz és nem 2.5: float a; a = 5 / 2; Az 5 egészet elosztva a 2 egésszel az eredmény az egész típusú 2 lesz és ezt kapja értékül az a.

19 Értékadó operátorok Az értékadásnak gyakran használt formája, amikor egy változó értékét módosítjuk, majd a kapott új értéket ugyanabban a változóban tároljuk, pl.: a = a + 5; Az ilyen kifejezések tömörebb formában is felírhatók: a += 5; Általános formában: a kif1 = kif1 op kif2 alakú kifejezések felírhatók a kif1 op = kif formában is (összetett értékadás). Az összetett értékadás használata általában gyorsabb kódot eredményez.

20 Feladat: a *= b + 1; Melyik alábbi kifejezés azonos ezzel ?
1. a = a * (b + 1); 2. a = a * b + 1;

21 Pointer operátorok A C nyelvben kiemelt szerepe van egy olyan speciális változónak, amely más objektumok címét tárolja, ez a mutató (pointer): Amikor deklaráljuk a mutatót, meg kell adnunk a nevét, és azt, hogy milyen típusú változóra fog mutatni. A C nyelvben két speciális egyoperandusú művelet van, melyeket a mutatókkal kapcsolatosan használunk. A "címe" (&) művelet eredménye az operandusként megadott memóriaobjektum címe: int a, *pa; pa = &a; A másik mutató operátor (*) az indirekt hivatkozás elvégzéséhez szükséges: *pa = *pa + 5; A *pa kifejezés a pa pointer által mutatott objektumot jelenti, a fenti példában az a változót.

22 Pointer aritmetika A mutató léptetése a szomszédos elemre többféle módon is elvégezhető: int *p, *q, j; p = p + 1; p += 1; p++; ++p; Az előző elemre visszalépésre szintén többféle lehetőség van: p = p - 1; p -= 1; p--; --p;

23 A sizeof operátor A C nyelv tartalmaz egy - a fordítás idején kiértékelésre kerülő - egyoperandusú operátort, amely megadja egy tetszőleges objektum (az operandus) méretét. A sizeof objektum vagy a sizeof (típusnév) alakú kifejezések értéke az az egész szám, amely megadja az operandusként megadott objektum, vagy típus byte-ban kifejezett méretét. A sizeof operátor előjel nélküli egész típusú értéket szolgáltat. Az objektum tetszőleges egyszerű változó, illetve a későbbiekben ismertetendő tömb vagy struktúra lehet.

24 1.6.2. mintapélda: a sizeof operátor használata
#include <stdio.h> void main (void) { //A sizeof operátor int meret; float z; meret = sizeof z; printf ("\nA z változó %d bytot foglal a memóriában",meret); printf ("\nA char típus : %d byte",sizeof (char)); printf ("\nAz int típus : %d byte",sizeof (int)); printf ("\nA float típus: %d byte",sizeof (float)); }

25 A vessző operátor A vessző operátor felhasználásával egyetlen kifejezésben több - akár egymástól független - kifejezés is elhelyezhető. A vessző operátort tartalmazó kifejezés kiértékelése balról jobbra haladva kerül kiértékelésre. A kifejezés értéke és típusa megegyezik a jobboldali operandus értékével és típusával. Példa: a = (b=5, b + 3); Először a b változó kap értéket (5), majd a zárójelezett kifejezés értéke 5 + 3, azaz 8 lesz. Végül az a változó értékadással megkapja a 8 értéket. Figyelem ! Azok a vesszők, amelyeket a deklarációkban a változónevek, illetve függvényhíváskor az argumentumok elkülönítésére használunk, nem a vessző operátorok. Ezért ezekben az esetekben nem garantált a balról - jobbra haladó kiértékelés sem.

26 A feltételes operátor A feltételes operátornak (?:) három operandusa van: kif1 ? kif2 : kif3 A feltételes kifejezésben először kif1 kifejezés értéke kerül kiértékelésre. Ha ennek értéke nem nulla (igaz), akkor kif2 értéke adja a feltételes kifejezés értékét, ellenkező esetben pedig a kettőspont után álló kif3 lesz a feltételes kifejezés értéke. A kettőspont két oldalán álló kifejezések közül tehát mindig csak az egyik értékelődik ki.

27 A feltételes operátor, példa
max = a > b ? a : b; A kifejezés az alábbi formában is felírható: a > b ? (max = a) : (max = b)

28 1.6.11. Precedencia és asszociativitás
Az elsőbbségi (precedencia) szabályok meghatározzák a kifejezésekben szereplő műveletek kiértékelési sorrendjét. A sorrend zárójelezéssel módosítható. Asszociativitásnak nevezzük az azonos precedenciájú operátorokat tartalmazó kifejezésekben a kiértékelés irányát. Ld táblázat !

29 1.6.11. Precedencia és asszociativitás
Megnevezés Operátor Asszociativitás Elsődleges operátorok () [] > balról jobbra Egyoperandusú operátorok ! ~ & * sizeof jobbról balra Aritmetikai operátorok / % + - Biteltoló műveletek << >> Relációs operátorok < <= > >= == != Bitműveletek Logikai műveletek && || Feltételes operátor ?: Értékadó operátorok = += -= … Vessző operátor ,

30 Mellékhatások Bizonyos műveletek - többszörös értékadás, léptetés, függvényhívás - feldolgozása során a kifejezés értékének meghatározása mellett bizonyos változók értéke is megváltozhat. Ezt a jelenséget nevezzük mellékhatásnak (side effect). A következő példában a pow függvény értéke attól függ, hogy az n léptetése megtörténik-e a függvény meghívása előtt, vagy sem. mintapélda: mellékhatások #include <stdio.h> #include <math.h> void main (void) { //mellékhatások int n = 2; printf ("\nn=%d, a hatványérték: %lf", ++n, pow (2, n)); }

31 Rövidzár kiértékelés Bizonyos műveleteknél nem kell a teljes kifejezést kiértékelni ahhoz, hogy egyértelműen megkapjuk a kifejezés értékét. Ezt a kiértékelési módot rövidzár (short-circiut) kiértékelésnek nevezzük. Logikai konjunkció esetén: kif1 && kif2 Ha a baloldali kifejezés értéke 0… . Hasonlóképpen a logikai diszjunkció esetén: kif1 || kif2 kiértékelésekor, ha kif1 értéke 1, akkor a diszjunkció értéke is 1 a kif2 értékétől függetlenül, tehát kif2 figyelmen kívül marad.

32 Típuskonverziók A kifejezések kiértékelése során előfordulhat, hogy egy kétoperandusú operátor különböző típusú operandusokkal rendelkezik. Ahhoz, hogy a művelet elvégezhető legyen, a fordítónak azonos típusúra kell átalakítania a két operandust, vagyis típuskonverziót kell végrehajtania. A típuskonverziók egy része automatikusan megy végbe a C nyelv definíciójában rögzített szabályok alapján, ezeket implicit vagy automatikus konverzióknak nevezzük. Típus konverziót a programozó is előírhat a típuskonverziós operátor (cast) alkalmazásával. Ez az egyoperandusú operátor a konvertálandó kifejezés előtt zárójelek között tartalmazza a megfelelő típusnevet: (típusnév) kifejezés Ebben az esetben a típusnév megjelenik a konverziós előírásban, ezért itt explicit típuskonverzióról beszélünk.

33 Típuskonverziók, példa
float v1, v2; int a=11; v1=a/2; v2=a/2.; float x1, x2; int a=11, b=2; x1= a/b; x2= (float) a / b;

34 Az automatikus típuskonverzió szabályai:
Lebegőpontos típusok konverziója: A lebegőpontos típus egész jellegű típussá konvertálása a törtrész eldobásával megy végbe. Ha az eredmény nem fér el a megadott egész típusban, akkor annak értéke határozatlan lesz. Ha a float típus double vagy long double típusra, illetve a double típus long double típusra konvertálódik, az objektum értéke változatlan marad. Valamely lebegőpontos típus kisebb lebegőpontos típusra konvertálható. Ha a konvertált érték nem ábrázolható a kijelölt típussal, az eredmény határozatlan lesz. Ha az érték csak kisebb pontossággal ábrázolható a kijelölt típussal, akkor kerekítés történik.

35 Az automatikus típuskonverzió szabályai:
Egész jellegű típusok konverziója A char, a short int , a felsorolt típus és a bitmezők minden olyan esetben alkalmazhatók, ahol az int típus használható. Ezek a típusok automatikusan int típussá konvertálódnak. Ha az int típus nem alkalmas a tárolásukra, akkor unsigned int lesz a konverzió céltípusa. Ez a konverziós szabály az "egész konverzió" nevet viseli. Értékmegőrző konverziónak is szokás nevezni, mivel a fenti konverzió érték- és előjelhelyes eredményt ad. Az egész típus minden esetben átalakítható lebegőpontos típussá. Ha a lebegőpontos típus pontossága nem elegendő az egész érték valamennyi számjegyének tárolására, akkor kerekítés történik.

36 A szokásos aritmetikai konverziók
A kétoperandusú műveletek többsége az operandusait és az eredményt a "legnagyobb" közös típusúra konvertálja. Az átalakítás során használt szabályok a "szokásos aritmetikai konverziók" nevet viselik. A konverziós szabályok az alábbiak: Ha valamelyik operandus long double típusú, akkor a másik operandus is long double típusúvá konvertálódik. Ha valamelyik operandus double típusú, akkor a másik operandus is double típusúvá konvertálódik. Ha valamelyik operandus float típusú, akkor a másik operandus is float típusúvá konvertálódik. Ha valamelyik operandus unsigned long int típusú, akkor a másik operandus is unsigned long int típusúvá konvertálódik. Ha valamelyik operandus long int típusú, akkor a másik operandus is long int típusúvá konvertálódik. Ha valamelyik operandus unsigned int típusú, akkor a másik operandus is unsigned int típusúvá konvertálódik. Ha az egyik operandus long int típusú és a másik operandus típusa unsigned int, akkor a másik operandus csak akkor konvertálódik long int típusúvá, ha az képes az unsigned int érték tárolására. Ellenkező esetben mindkét operandus unsigned long int típusú lesz. Ha a fenti szabályok egyike sem került alkalmazásra, akkor mindkét operandus int típusú.

37 Ellenőrző kérdések Ismertesse az operátor, az operandus és a kifejezés fogalmak kapcsolatát ! Milyen szabályok érvényesülnek a kifejezések kiértékelésekor ? Mit mond ki a precedenciaszabály ? Mikor alkalmazza a fordító az asszociativitás szabályt. Sorolja fel és csoportosítsa az aritmetikai operátorokat ! Sorolja fel és csoportosítsa a logikai és relációs operátorokat ! Írja fel a konjunkció igazságtábláját ! Milyen típusú lesz a művelet eredménye ? Írja fel a diszjunkció igazságtábláját. Milyen típusú lesz a művelet eredménye ? Mire használjuk a léptető operátorokat ? Ismertesse a C nyelv bitműveleteit ! Írja fel a bitenkénti logikai műveletek igazságtábláját ! Hogyan történhet egy byte meghatározott bitjeinek 1-be állítása ? Mi teszi lehetővé a többszörös értékadás használatát ? Milyen műveletek végezhetők mutató típusú változókon ? Hány operandusa van a feltételes operátornak ? Hogyan kérdezhető le egy változó, illetve egy típus mérete ? Kifejezések kiértékelésénél mit jelent az asszociativitás ? Mit nevezünk mellékhatásnak a műveletek feldolgozás kapcsán ? Mit értünk rövidzár kiértékelésen ? Mondjon rá egy konkrét példát ! Mikor kell a fordítónak típuskonverziót végrehajtania ? Írjon fel egy konkrét példát, amikor az implicit típuskonverzió információ-vesztéssel jár ! Mi történik az automatikus típuskonverzió során, ha lebegőpontos típus egész jellegű típussá konvertálódik, float típus double vagy long double típussá konvertálódik, egész típus konvertálódik float típussá.

38 Feladat Mi jelenik meg a képernyőn az alábbi program-részlet lefutása után: float eredmeny; int a=15, b=4; eredmeny = a/b; printf (”\nAz eredmény: %.2f ”,eredmeny);

39 Feladat megoldása Mi jelenik meg a képernyőn az alábbi program-részlet lefutása után: float eredmeny; int a=15, b=4; eredmeny = a/b; printf (”\nAz eredmény: %.2f”.eredmeny); Az eredmény: 3.00

40


Letölteni ppt "dr Póder Margit f. docens Rendszer- és Szoftvertechnológia Tanszék"

Hasonló előadás


Google Hirdetések