Porkoláb Zoltán - C programozás 2017.10.09. előadás jegyzet
4. előadás: Operátorok, kifejezések, kifejezések kiértékelése, precedenciák
X = A*B/C*D
Y = A+B*C
--> C-ben operátorok, Fortranban ezek utasítások (nem kell ;)
Az azonos precedenciájú műveletek sorrendje?? (Fortranban nem gondoltak rá)
--> ma ált. balról jobbra (pl. Java)
pl.:
! * ++ *p
//ezt így zárójelezem: (assziciativitási szabály)
!(*(++(*p)))
Különféle operátorok:
1. precedenciaosztály:
// index: [] pl. t[i] --> 2 param.
// record (struct): pl. r.m
struct hallgato //ez egyféle hallgato típusú változó
{
char neptun[6];
char nev[20];
int kor;
};
struct hallgato Bela, Dezso;
(Bela.neptun[0] ...)
//pointerrel
(*ptr).kor //kell a (), mert a * alacsonyabb precedenciájú
ptr->kor //rövidítés
// függvényhívás ()
sin(.5)
[],(),* szerencsére (köszi Ritchie) kifejezés, nem pedig spec utasítás
// postfix
i--
i++
//i értéke nem változik, pl.
int i=1;
int k=i++; //itt k=2, i=1 marad
2. osztály:
//negáció: 0 --> 1; nem0 --> 0
!a
//bitenkénti negálás (op.rendsz): 0 --> -1; -1 --> 0; más nem 0 --> más nem 0
~a
//prefix
++i
--i
//pl.
int i = 1;
int k = ++i; //itt k==2 & i==2
//i=i++ veszélyes lehet, újabb függvényhívásnál más értékkel számol--> nem olyan átlátható
C: hardware-közeli elemek elérése
pl. pointer: címre vonatkozó hivatkozás
&a //címoperátor (itt van az a)
*p //dereferencia (ezen a helyen az "a" van)
3. osztály:
a*b //szorzás
a/b //osztás
a%b //modulo
4. osztály:
a+b
a-b
5. osztály:
a<>b
//shift operátor: lineáris eltolás, 2^b-nel szoroz
pl. 5<<2 binárisan: 000...0101 -> 0...010100 (felül elvesznek bitek, elveszhet az előjel v. értékes jegy)
5<<-2 undefined, helyette 5>>2: -> 0...000001
6. osztály:
ab
a<=b a>=b
7. osztály:
a==b a!=b
8. osztály:
&
9. osztály:
^ //bitenkénti XOR
10. osztály:
| //-> 0-t VAGY 1-t ad
11. osztály:
&& //logikai ÉS
12. osztály:
|| //logikai vagy
13. osztály:
a ? b : c
14. osztály:
a = (b = c) //értékadás: ez is kifejezés!
a+=b
a-=b
a%=b
15. osztály:
a, b //vessző
________________________
pl. tudni szeretném h mi van X utolsó bájtjában:
x&0xff == 12
Ritchie: hiba volt az ==-t feljebb rakni
Itt: először xff==12 értékelődik ki -> 0/hamis
x&0 -> mindig hamis
mindig zárójel kell: (x&0xff)==12
logikai ÉS/VAGY: rövidzáras műveletek (shortcut), pl.:
am < 19;
a!=b || b!=c //Pascal: mindkét oldalt kiértékelné
a ? b : c
pl.
# define MAX(a,b) ((a)>(b)?(a):(b))
z=MAX(3*x,f());
--> lehetne if-else párral (néha így egyszerűbb)
értékadás:
a=b //ennek a akifejezésnek az értéke: "a" új értéke
//ez is értelmes:
c = (a=b) + 3
*p=b //pl. C++-ban nagy haszon
int ch;
while ((ch=getchar()) != EOF) { //az stdio.h-ban egy macro
/* code */
}
BALÉRTÉK:
ami értékadás bal oldalán állhat (írható tárterületet def.)
összes többi: jobbérték
pl. sin()
a = b = c //megfelelő sorrend
a+=b //rövid és a-t csak egyszer értékeli ki
vs.: a = a+b
_______________________________________
Ennyi lenne szemantika szempontjából.
DE: futási idő!
int f() {
printf("f");
return 2;
}
int g() {
printf("g");
return 1;
}
int h() {
printf("h");
return 0;
}
int main() {
printf("%d\n", f()==g()==h() );
}
//2==1 -> hamis/0
//-> 0==0 -> igaz
//ez kiírja az egyet, meg előtte még 3 betűt --> Milyen sorrendben? A fordítótól függ (optimális ford.).
________________________
tipikus hiba:
int t[10];
int i=0;
while (i<10) {
t[i] = i++;
}
BAJ: i++-t kiértékelem -> elején 0, végén 9, DE: nem tudhatom h a t[i] hányadik elem
while (i<10) {
t[i] = i;
i++;
}
--> ezzel nincs baj, mivel {; && || ,} szekvenciapont -> azelőtti biztosan kiértékelődik, mielőtt továbblép
_______________________________________
Összefoglalva:
1. precedencia
2. asszociativitás
3. balérték
4. fordítási sorrend (-> nem tudom meghatározni)