Kihagyás

4. előadás

Operátorok

#include <stdio.h>

int main()
{
    int i = 1;
    printf("i == %d, ++i == %d\n", i, ++i);
    return 0;
}
i == 2, ++i == 2
vagy
i == 2, ++i == 1

RENDSZERFÜGGŐ!!!

Visszautalás az operátorokra

Megjegyzések

Nem kiértékelt operátorok

Egyes operátorok futási időben nincsenek kiértékelve. Fordítási időben felhasználható információt szolgáltatnak.

Például: sizeof

size_t int_size = sizeof(printf("%d", 42));

Nem ír ki semmit, de az int_size-ba belekerül a printf visszatérési értékének mérete (int).

Bináris és/vagy precedenciája

A bitwise operátorok precedenciája a relációs operátorokénál gyengébb

Tehát, flag & 0xff == 0 -> flag & (0xff == 0)

Nem magától értetődő

~~Érdemes~~ Szükséges zárójelezni: (flag & 0xff) == 0

Értékadás vs. egyenlőségvizsgálat

int x = 10
if (x = 0)

Nem összehasonlítás, hanem értékadás történik.

x-nek új értéke lesz.

Érdemes a konstants jobbra írni, így hibát jelez a hiányos szintaktika.12L

if (0 = x){printf("hmm?");}
error: expression is not assignable

ITT A YODA!!!

Értékadás operátor és a másolás szemantikája

int a,b
a = 3 + (b = 5); //a = 8, b = 5
double a,c;
int b;
a = b = c = 3.14; // a = (b = (c = 3.14))
/*
c == (double)3.14;
b == (int)3;
a == (double)3;
*/

A láncolt értékadás alap esetben jobbról illeszt!

A csonkolás után kap az a értéket


Értékadás példa összetett típusra

#include <stdio.h>

struct X
{
  int    i;
  double d;
  int   *ptr;
};
void f()
{
  int      zz = 1;
  struct X aa;
  struct X bb;

  aa.i   = 1;
  aa.d   = 3.14;
  aa.ptr = &zz;

  // Mély másolás történik
  // Kivéve a pointeren, ott sekély másolás
  bb = aa;  /* 1==bb.i és 3.14==bb.d és *aa.ptr==*bb.ptr */
  ++*aa.ptr; /* 2==zz  és 2==*aa.ptr  és  2==*bb.ptr !!! */  
}

Sekély másolás

Amennyiben összetett típuson történik értékadás, akkor az összetett típus az új érték mutatóját veszi át, így később ha az érték változik, az mind a két helyen változik.

Konverziók

Kifejezések kiértékelése

#include <stdio.h>

int main()
{
    int i = 1;
    printf("i == %d, ++i == %d\n", i, ++i);
    return 0;
}
  • gcc: i = 2, ++i = 2
  • clang: i == 1, ++i == 2

Szekvencia pontok

Az utasítások eleje és vége szekvencia pont. További operátorok, amelyek szekvencia pontként viselkednek:

  • a rövidzáras logikai operátorok ( && és || )
  • a feltételes (terciális) operátor kiértékelése ( ? : )
  • a vessző operátor ( , )
  • függvényhívások

Amikor egy függvényt meghívunk: kiértékelődik az összes paramétere (ezt még azélőtt, hogy a törzse lefutna)

if( i++ == 10  t[i] == 42 ) //Mindenképp balról jobbra fut le -> a `t[i]` már az új i értéket használja

Függvénymeghíváskor a paraméterek kiértékelésének egymás közötti sorrendje nem meghatározott. (undefined behaviour)

Üres utasítás

;

Ennyi. Csak egy pontosvessző.

if (x < 10){
  ;
}

Összetett utasítás

Blokk utasítás, több utasítást foglal össze

...
else{
  printf("asd\n");
  printf("asd2\n");
}

Elágazás

if (expression) statement;

if (expression) statement1; else statement2;

if (expression)
{
  statement1;
}
else statement2;

Switch (szelekciós utasítás)

switch (value)
{
  case value1: statement1; break;
  case value2: statement2; break;
  case value3: /* fallthrough */
  default: 
}

fallthrough: itt direkt nincs break, defaultra ugrik

case-eknek egyedieknek kell lennie

ne hagyd ki a default címkét

While ciklus

  • Az egyik legalapvetőbb ciklus.
  • Elöl tesztelős ciklus:
    • Először a ciklusfeltételt ellenőrzi és addig hajtja végre a ciklusmagot, ameddig a feltétel igaz.
    • Ennél a ciklusnál nekünk kell ondoskodni arról, hogy a feltétel valamikor hamissá váljon.
while (expression)
  {
    statement
  }

Do-While ciklus

  • Hátultesztelő ciklus
  • ciklusmagot egyszer mindenképp végrehajtjuk, utána ellenőrizzük a feltételt
  • Inkább ne használjuk
do {
  statement
}while(expression)

For-ciklus

3 rész:

  1. inicializálás - kezdeti értékbeállításra szolgál
  2. ciklusmag végrehajtása előtt értékelődik ki. Akkor folytatódik a ciklus, ha igaz
  3. inkrementálás - mindig kiértékelődik a ciklusmag után

break: a ciklus után ugrik a futtatás continue: a ciklus a következő értékre ugrik

for (declaration, expression, incrementation) {
  statement
  break
}
//break jumps here