Kifejezések

 

 

 

 

term  következők valamelyike lehet :

·         név (függvény/adat/felsorolás)

·         egész konstans

·         lebegőpontos konstans

·         karakter konstans

·         string konstans

·         sizeof(deklaráció)

·         (kifejezés)

 

pl.:        a++ * (2+c) + *p

 

Fogalmak (subcontexts)

 

Jobbérték (rvalue): a kifejezés értékének az elérésekor fordul elő. Teszt esetén is jobb érték kifejezést használunk.

Bal érték (lvalue): hozzáférés az adathoz tárolás céljából.

Függvény kijelölés (function designator): függvény címének a kiszámításakor, vagy függvény hívásakor használjuk.

Mellékhatás (side-effect): a kiértékelés után valamely változó értéke megváltozik. (pld, a=b; i++;)

 

void f(int);

int x;

f(x=3);

f függvény kijelölés

3 és x=3 jobb érték kifejezés

f(x=3) mellékhatás

 

Példa hibákra:

            0=a; /* invalid lvalue */

     if( f(x) ) {....}; /* f() not rvalue ! */

 

Precedencia :

 

a*b+2*(c+d)

kiszámítási fával ábrázolva:

 

Csoportosítás (Nem tévesztendő össze a kiértékelés sorrendjével!):

a+b+c+d

==>

((a+b)+c)+d

a=b=c=d

<==

a=(b=(c=d))

 

Példák a kiértékelés sorrendjének definiálatlanságára:

a)

y=*p++;

1. tmp=p;  p+=1;  y=*tmp;

2. y=*p;   p+=1;

 

b)

     a=++b+2*b;

 

 

1.  b +=1;

tmp =2*b;

tmp+=b;

a=tmp;

 

2.  tmp=b;

tmp=2*b;

b+=1;

tmp +=b;

a=tmp;

 

 

c)    i=++i + 2;

     f()+g()

printf(“%d %d %d”, i++, i++, i++);

 

Sequence point (ezen a ponton befejeződött egy kifejezés kiértékelése):

·        utasítások között

·        logikai vagy és és kapcsolatban

·        függvényhíváskor (a függvény kódjának végrehajtása előtt kiértékelődnek az argumentumok)

·        , kifejezést elválasztó operátor esetén

·        feltételes operátornál z?a:b

 

Típuskonverziók (type conversions)

 

A következő esetek lehetnek:

·        egész előléptetés (promoting)

·        kiegyenlítés (balancing)

·        hozzárendelés (assigning)

·        konverzió, kasztolás (type casting)

 

Promoting

Kivéve, ha a sizeof operátor operandusa, az egész (rvalue) kifejezés a következő típusok egyike lesz (az értéknek megfelelően a leírt sorrendben):

·        int

·        unsigned int

·        long

·        unsigned long

 

Balancing

Kétoperandusú (infix) operátorok esetében, ha a két operandus aritmetikai, akkor "kiegyenlítődnek" a típusok a következő szabályok szerint:

1.  Hacsak a két operandus nem unsigned int és long, a kiegyenlített (balanced) típus a két operandus előléptetett (promoted) típusa, amelyik később fordul elő a következő sorrendben: int, unsigned int, long, unsigned long, float, double, long double

2.  Hacsak a két operandus nem unsigned int és long, és a long típus tárolni képes az unsigned int típus minden értékét, a kiegyenlített (balanced) típus long lesz

3.  Minden más esetben a a kiegyenlített (balanced) típus unsigned long

 

Assigning

Hozzárendelő (értékadó) operátor esetében, ha nincs típusegyezés, megtörténik a megfelelő típuskonverzió az érték tárolása előtt.

 

Type casting

A típusmódosító (type) operátorral végrehajtódik az előírt típuskonverzió.