1. kártya
Állítsd precedencia szerint sorrendbe! Mondanom sem kell: könyv, jegyzet, bármi használható közben, mint a vizsgán, de itt gyorsan jöjjenek a válaszok! Természetesen az operátorok jelentését is tudni kell.
-> // struktúra tagra való hivatkozás
<< // bit eltolása balra
>= // nagyobb vagy egyenlő
+= // változó növelése pl. a=a+b így meg a+=b
-= // változó csökkentése pl. a=a-b így meg a-=b
. // struktúra tagra való hivatkozás
& // bitenkénti és művelet
* // szorzás
&& // logikai és művelet (feltételekben)
*= // változó szorzása pl. a=a*b így meg a*=b
Mi a különbség az if-ek fejében a két kifejezés között (ha van)
if(b & 0x80 == 0) …
if((b & 0x80) == 0) …
Kiértékelési sorrend precedencia miatt más lesz így az eredmény is.
Első feltételben megvizsgálja, hogy 0x80 egyenlő-e 0-val majd b és az eredmény között bitenkénti és-t végez.
Másodikban b és 0x80 között bitenkénti és-t hajt végre majd megvizsgálja, hogy ez egyenlő-e 0-val.
2. kártya
Alábbi kód kapcsán: mit mond a C a + operátor operandusainak kiértékelési sorrendjéről?
#include <stdio.h>
int novel_egyel( int *a )
{
return ++ * a;
}
int csokkent_egyel( int *a )
{
return -- * a;
}
int main(void)
{
int a =0;
printf("%d\n" , novel_egyel(&a) + csokkent_egyel(&a) );
a =0;
printf("%d\n" , csokkent_egyel(&a) + novel_egyel(&a) );
/*
Kimenet:
1
-1
Nincs helyes kiértékelési sorrend. A kiértékelési sorrend az adott környezet függvénye.
*/
}
3. kártya
#include <stdio.h>
int
main(void)
{
int blokkban = 0; /** 1. deklaráció**/
{
int blokkban = 100; /** ne zavarjon meg a név ez nem ugyanaz a változó hiába ugyan olyan névvel hivatkozunk rá! **/
printf("%d\n", blokkban);
{
int blokkban = 10000;
printf("%d\n", blokkban);
blokkban = blokkban + 1;
printf("%d\n", blokkban);
}
printf("%d\n", blokkban);
}
printf("%d\n", blokkban);
return 0;
}
/*
1.Mit ír ki a program?
Kimenet:
100
10000
10001
100
0
Megjegyzés: A program a blokkok , globális és lokális változók működését próbálja reprezentálni! Lényegében arról szól amit meghívunk egy blokkban egy változót az a blokk határáig érvényes(kivéve ha globálisnak deklaráljuk azaz minden blokkban látható vagy az előző blokkban deklaráltuk és ebben nem ekkor használhatjuk) vagyis a következő blokkban ugyanilyen néven meghívhatunk egy változót akár más típusunak is deklarálhatjuk! A programban látjuk a legkülső blokkban a változó értéke 100 és ez nem változik attól hogy a 2 belső blokkban ugyanilyen néven más értékkel rendelkezett egy változó...*/
4. kártya
#include <stdio.h>
int
main(void)
{
int blokkban = 0;
{
printf("%d\n", blokkban);
{
int blokkban = 1000;
printf("%d\n", blokkban);
blokkban = blokkban + 1;
printf("%d\n", blokkban);
}
printf("%d\n", blokkban);
}
printf("%d\n", blokkban);
return 0;
}
/*
Mit ír ki a program?
0
1000
1001
0
0
Megjegyzés: Ugyan az a szisztéma! Kivéve hogy a 2 blokknyitásnál nem deklarálja a blokkban változót és így a main-ben lévő értékkel rendelkezik a változó! Lényegében a main-ben deklarált blokk változó globális a 2-ra nézve ( használja az értékét ).*/
5. kártya
// Mi a működésbeli különbség az „eredeti”, az „1. módosítás” és a „2. módosítás” között?
char * string_masolo_man_pl_alapjan (char *dest, const char *src, int n)
{
int i;
char *p = dest;
/*
// eredeti
for(i = 0; i < n && src[i] != '\0'; i++)
dest[i] = src[i];
*/
/*
// 1. modositas
for(i = 0; i < n && src[i]; i++)
dest[i] = src[i];
*/
// 2. modositas, char *p felvetele, p[i]='\0' és return p;
for(i = 0; i < n && (*dest++ = *src++); i++)
// return dest;
return p;
}
/*
Mindhárom ugyan azt csinálja csak más megvalósításban.
eredeti:
másolja a karaktereket a dest tömbbe a src tömbből addig amíg i kisebb n és src[i] nem egyenlő \0 ( string végét jelző karakter C-ben )
1. modositas:
másolja a karaktereket a dest tömbbe a src tömbből addig amíg i kisebb n és src[i] nem null(a) (mivel c-be ami különböző nullától igaz, és csak a string vége jel a null)
2. modositas:
addig megy míg i kisebb mint n és amíg az átadott karakter nem sor vége jel, *dest++ = *src++ annyit tesz, hogy átmásolja a karaktert majd növeli a mutatott karakter helyét emiatt a következőre lép mindig, *p ezért kellet bevezetni mert mindig a karaktertömbünk elejére fog mutatni.
*/
6. kártya
#include <stdio.h>
extern int hivasok_szama;
int
fuggveny (int formalis /*lokalis valtozo, automatikus valtozo */ )
{
/*lokalis valtozo, automatikus valtozo*/
int lokalis = 2;
/* statikus belso */
static int hivasok_szama2;
printf ("hivasok szama: %d %d\n", ++hivasok_szama, ++hivasok_szama2);
return lokalis * formalis;
}
int hivasok_szama = 0;
int
main ()
{
/*lokalis valtozo, automatikus valtozo*/
int lokalis, aktualis = 2;
lokalis = fuggveny (aktualis);
aktualis = fuggveny (aktualis);
return 0;
}
/*
Kimenet:
hivasok szama: 1 1
hivasok szama: 2 2
hivasok_szama változó értéke hozzáférhető az egész programban, bármely függvény módosíthatja az értékét, program futásáig őrzi tartalmát.
hivasok_szama2 egy statikus változó mely annyit tesz, hogy nem függ a függvény meghívásától mert értéke megmarad minden függvényhíváskor, viszont csak a fuggvényen belül férünk hozzá a prgram más részeiből nem tudjuk az értékét változtatni.
*/
7. kártya
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int kulso = 0;
static int statikus_kulso = 0;
void
valtozok (void)
{
int belso = 0;
static int statikus_belso = 0;
int gyermekem_pid;
int statusz;
if ((gyermekem_pid = fork ()) == 0)
{
printf ("GY: %d %d %d %d\n", ++kulso, ++statikus_kulso, ++belso,
++statikus_belso);
exit (0);
}
else if (gyermekem_pid > 0)
{
wait (&statusz);
}
else
{
exit (-1);
}
printf ("SZ: %d %d %d %d \n", kulso, statikus_kulso, belso, statikus_belso);
}
int
main (void)
{
valtozok ();
valtozok ();
return 0;
}
/*
Kimenet:
GY: 1 1 1 1
SZ: 0 0 0 0
GY: 1 1 1 1
SZ: 0 0 0 0
Miért is?:D
A gyerek örökli a szülő értékeit ( 0 0 0 0 ) de ezt meg is növeli és így lesz a GY(erek) 1 1 1 1, de a szülő továbbra is 0 0 0 0 mivel az ő értékeit nem változtatjuk.
Második valtozok függvényhívás is ugyan ez lesz az eredménye, hogy a szülő 0 0 0 0 míg a gyerek 1 1 1 1 növelsé miatt.
*/