Programozsi Nyelvek C Gyakorlat Gyak 02 Trk Mrk

  • Slides: 176
Download presentation
Programozási Nyelvek (C++) Gyakorlat Gyak 02. Török Márk tmark@caesar. elte. hu D-2. 620 1

Programozási Nyelvek (C++) Gyakorlat Gyak 02. Török Márk tmark@caesar. elte. hu D-2. 620 1

Tartalom • • • Erősen típusos nyelvek fogalma Vezérlési szerkezetek Mutatók és dereferálás Függvények

Tartalom • • • Erősen típusos nyelvek fogalma Vezérlési szerkezetek Mutatók és dereferálás Függvények bevezetése Paraméterátadás Kódelemzés

Típusozás • Erősen és gyengén típusos nyelvek • Statikus és dinamikus típusrendszerek

Típusozás • Erősen és gyengén típusos nyelvek • Statikus és dinamikus típusrendszerek

Típusozás • Típus: névvel azonosított halmaz, melyen műveleteket értelmezünk. – értékhalmaz – típusműveletek

Típusozás • Típus: névvel azonosított halmaz, melyen műveleteket értelmezünk. – értékhalmaz – típusműveletek

Erősen típusos nyelv • Különböző típusú értékek hogyan adhatóak egymásnak értékül. • Valójában nincs

Erősen típusos nyelv • Különböző típusú értékek hogyan adhatóak egymásnak értékül. • Valójában nincs egzakt meghatározás rá. • Forrás: Ada for the C++ or Java Developer, Quentin Ochem, Technical Papers, Ada. Core • Nincs implicit típuskonverzió • Operandusok azonos típusúak – Primitív művelet esetén – A standard műveletekre értjük, a túlterhelés más!

Erősen típusos nyelv (Ada) procedure Strong_Typing is Alpha : Integer : = 1 ;

Erősen típusos nyelv (Ada) procedure Strong_Typing is Alpha : Integer : = 1 ; Beta : Integer : = 10 ; Result : Float; begin Result : = Float ( Alpha ) / Float ( Beta ) ; -- 0. 1 end Strong;

Gyengén típusos nyelv • Implicit típuskonverzió – Bővítő automatikus – Szűkítő típuskényszerítéssel • Hibás

Gyengén típusos nyelv • Implicit típuskonverzió – Bővítő automatikus – Szűkítő típuskényszerítéssel • Hibás végeredmény – Konverzió néha kerekít

Gyengén típusos nyelv (C++) void weak. Typing ( void ) { int alpha =

Gyengén típusos nyelv (C++) void weak. Typing ( void ) { int alpha = 1 ; int beta = 10 ; float result; result = alpha / beta; // 0 }

Gyengén típusos nyelv (Java) void weak. Typing () { int alpha = 1 ;

Gyengén típusos nyelv (Java) void weak. Typing () { int alpha = 1 ; int beta = 10 ; float result; result = alpha / beta; // 0 }

Statikus típusrendszer • Statikus típusrendszerű nyelv – Minden változódeklarációkor meg kell adni az adott

Statikus típusrendszer • Statikus típusrendszerű nyelv – Minden változódeklarációkor meg kell adni az adott változó típusát. – Azaz fordítási időben minden változóról, minden függvény paraméteréről, illetve minden függvény (művelet) visszatérési értékéről kell tudni, hogy milyen típusú. – Def szerint: a típus meghatározza, hogy milyen műveleteket végezhetek el rajta.

Dinamikus típusrendszer • Értelmezett (interpretált) nyelvek • Automatikus memóriakezelés – Trükközni mindig lehet •

Dinamikus típusrendszer • Értelmezett (interpretált) nyelvek • Automatikus memóriakezelés – Trükközni mindig lehet • Deklaráció típus nélkül – Az inicializáláskor dől el, hogy milyen a típusa a változónak • Függvények esetén – Nincs visszatérési típus deklarálva – Paraméterátadás: Duck-typing

Alap típusok és módosítók • Típusok: int, float, double, char, (bool már csak C++-ben)

Alap típusok és módosítók • Típusok: int, float, double, char, (bool már csak C++-ben) Modifiers: short, long, signed, unsigned • int: – – – short int: -32, 768 -> +32, 767 (16 bit) unsigned short int: 0 -> +65, 535 (16 bit) unsigned int: 0 -> +4, 294, 967, 295 (32 bit) int: -2, 147, 483, 648 -> +2, 147, 483, 647 (32 bit) long int: -2, 147, 483, 648 -> +2, 147, 483, 647 (32 bit) • char: – – signed char : -128 -> +127 unsigned char: 0 -> +255 • float: 32 bit • double: – – double : 96 bit long double : 64 bit

Erőssen (? ) típusos nyelv (Na, mégegyszer) • Házi feladat: Hogy is van ez?

Erőssen (? ) típusos nyelv (Na, mégegyszer) • Házi feladat: Hogy is van ez? #include <stdio. h> int main() { short s = 10; short int si = 1; printf ("s : %ft, si : %fn", sizeof(s), sizeof(si)); }

Típusos nyelv #include <stdio. h> int main() { short s = 10; short int

Típusos nyelv #include <stdio. h> int main() { short s = 10; short int si = 1; printf ("s : %dt, si : %dn", sizeof(s), sizeof(si)); }

Erőssen (? ) típusos nyelv • Házi feladat: Hogy is van ez? #include <stdio.

Erőssen (? ) típusos nyelv • Házi feladat: Hogy is van ez? #include <stdio. h> int main() { short s = 10; short int si = 1; printf ("s : %ft, si : %fn", sizeof(s), sizeof(si)); } A float leveszi a memóriából azt a részt, ami neki kell, így viszont az intnek egy része kimarad!

C++ típusrendszere • C++-ben a leggyakoribb alaptípusok: – Egész számok típusa: int, short int,

C++ típusrendszere • C++-ben a leggyakoribb alaptípusok: – Egész számok típusa: int, short int, long int – Lebegopontos számok típusa: float, double, long double – Logikai típus: bool • C-ben int volt a bool megfelelője! – Karakter típus: char – Karakterlánc típus: string • Ez C-ben char*

C++ típusrendszere • C++11 újdonságai – auto • fordítás idejű típuskikövetkeztetés – register •

C++ típusrendszere • C++11 újdonságai – auto • fordítás idejű típuskikövetkeztetés – register • Regiszterekbe rakja az értékét a változónak a memória helyett, gyorsabb elérést biztosít – dectype

Statikus típusrendszer (C++-ben) int main() { auto i; return 0; } error: declaration of

Statikus típusrendszer (C++-ben) int main() { auto i; return 0; } error: declaration of ‘auto i’ has no initializer

Statikus típusrendszer (C++-ben) int main() { auto i; i = 12; return 0; }

Statikus típusrendszer (C++-ben) int main() { auto i; i = 12; return 0; } error: declaration of ‘auto i’ has no initializer

Statikus típusrendszer (C++-ben) int main() { auto i = 12; return 0; }

Statikus típusrendszer (C++-ben) int main() { auto i = 12; return 0; }

Statikus típusrendszer (C++-ben) #include <iostream> #include <typeinfo> int main() { auto i = 12;

Statikus típusrendszer (C++-ben) #include <iostream> #include <typeinfo> int main() { auto i = 12; std: : cout << typeid(i). name(); // i return 0; }

Statikus típusrendszer (C++-ben) #include <iostream> #include <typeinfo> class Clazz; int main() { auto i

Statikus típusrendszer (C++-ben) #include <iostream> #include <typeinfo> class Clazz; int main() { auto i = new Clazz(); std: : cout << typeid(i). name(); return 0; } error: unable to deduce ’auto’ from ’<expression error>’

Statikus típusrendszer (C++-ben) #include <iostream> #include <typeinfo> class Clazz { }; int main() {

Statikus típusrendszer (C++-ben) #include <iostream> #include <typeinfo> class Clazz { }; int main() { auto i = new Clazz(); std: : cout << typeid(i). name(); // Pl. Clazz return 0; }

Statikus típusrendszer (C++-ben) • Függvény visszatérési értékének típusa és a függvény paramétere nem lehet

Statikus típusrendszer (C++-ben) • Függvény visszatérési értékének típusa és a függvény paramétere nem lehet auto típusú!

Statikus típusrendszer (C++-ben) int main() { register int i = 12; return 0; }

Statikus típusrendszer (C++-ben) int main() { register int i = 12; return 0; }

Statikus típusrendszer (C++-ben) #include <iostream> #include <typeinfo> int main() { int i = 12;

Statikus típusrendszer (C++-ben) #include <iostream> #include <typeinfo> int main() { int i = 12; decltype(i) j = ’c’; std: : cout << typeid(j). name(); // i return 0; }

Statikus típusrendszer (C++-ben) • Más, statikus típusrendszerű nyelvek (C/C++): • Java, C# • Ada

Statikus típusrendszer (C++-ben) • Más, statikus típusrendszerű nyelvek (C/C++): • Java, C# • Ada (Erősen típusos! Láttuk!) • Dinamikus típusrendszerű nyelvek: • Python, Ruby, Perl • Lua • Java. Script (Elképesztő gyenge lábakon álló típusrendszer)

Deklaráció és értékadás • Deklaráció: – típusnév változónév 1; – típusnév változónév 1, változónév

Deklaráció és értékadás • Deklaráció: – típusnév változónév 1; – típusnév változónév 1, változónév 2, …; • Értékadás: – változónév = érték; – típusnév változónév = érték; • Kezdeti érték: – undefined, ha nincs inicializáció.

Deklaráció és értékadás int main() { int i; i = 0; int k; }

Deklaráció és értékadás int main() { int i; i = 0; int k; }

Deklaráció és értékadás int main() { int i = 0; int k; }

Deklaráció és értékadás int main() { int i = 0; int k; }

Deklaráció és értékadás • C-ben: #include <stdio. h> int main() { int i, j,

Deklaráció és értékadás • C-ben: #include <stdio. h> int main() { int i, j, k = 0; printf("%d | %d", i, j, k); return 0; }

Deklaráció és értékadás • C-ben: – Fordítás: gcc dek 01. c -o dek 01

Deklaráció és értékadás • C-ben: – Fordítás: gcc dek 01. c -o dek 01 –Wall – Fordítás eredménye: dek 01. c: In function ‘main’: dek 01. c: 5: warning: ‘i’ is used uninitialized in this function dek 01. c: 5: warning: ‘j’ is used uninitialized in this function • Már gondolhatjuk az előrejelzésből: Nem sikerült, amit szeretnénk! – Output: 2826228 | 134513739 | 0 • Nem tudunk egy lépésben deklarálni és értékül adni? • Vagy mégis? !? !

Deklaráció és értékadás • C-ben: #include <stdio. h> int main() { int i =

Deklaráció és értékadás • C-ben: #include <stdio. h> int main() { int i = j = k = 0; printf("%d | %d", i, j, k); return 0; }

Deklaráció és értékadás • C-ben: – Fordítás: gcc dek 01. c -o dek 01

Deklaráció és értékadás • C-ben: – Fordítás: gcc dek 01. c -o dek 01 –Wall – Fordítás eredménye: dek 01. c: In function ‘main’: dek 01. c: 5: error: ‘j’ undeclared (first use in this function) dek 01. c: 5: error: (Each undeclared identifier is reported only once dek 01. c: 5: error: for each function it appears in. ) dek 01. c: 5: error: ‘k’ undeclared (first use in this function) • Error! • Más út?

Deklaráció és értékadás • C-ben: #include <stdio. h> int main() { int i, j,

Deklaráció és értékadás • C-ben: #include <stdio. h> int main() { int i, j, k; i = j = k = 0; printf("%d | %d", i, j, k); return 0; }

Deklaráció és értékadás • C-ben: – Fordítás: gcc dek 01. c -o dek 01

Deklaráció és értékadás • C-ben: – Fordítás: gcc dek 01. c -o dek 01 –Wall – Fordítás eredménye: Nincs hiba, sem warning! • Siker! – Output: 0|0|0 • Nem tudunk egy lépésben deklarálni és értékül adni? Nem tudunk egy lépésben deklarálni és értékül adni! • Házi feladat: És ha egy lépésben deklarálunk, és ott adunk értéket külön az elemeknek?

Deklaráció és értékadás • Hogy megy ez C++-ben? #include <iostream> int main() { int

Deklaráció és értékadás • Hogy megy ez C++-ben? #include <iostream> int main() { int i, j, k = 0; std: : cout << "|" << i << "|" << j << "|" << k; } • Szokásos történet!

Deklaráció és értékadás • Hogy néz ez ki másik nyelveken? Nézzük meg Adában! with

Deklaráció és értékadás • Hogy néz ez ki másik nyelveken? Nézzük meg Adában! with ada. text_io; procedure dek 01 inada is i, j, k : integer : = 0; begin ada. text_io. put_line( Integer'Image(i) & Integer'Image(j) & Integer'Image(k)); end dek 01 inada;

Deklaráció és értékadás • Az output: $ gnatmake dek 01 inada. adb … $.

Deklaráció és értékadás • Az output: $ gnatmake dek 01 inada. adb … $. /dek 01 inada 000 • Siker! Adában meg lehet csinálni!

Üres utasítás • A jó öreg skip! • ; int main() { ; ;

Üres utasítás • A jó öreg skip! • ; int main() { ; ; ; // három üres utasítás return 0; }

Vezérlési szerkezetek • Elágazás: – – – Feltétel vizsgálata Ez lehet egész, logikai vagy

Vezérlési szerkezetek • Elágazás: – – – Feltétel vizsgálata Ez lehet egész, logikai vagy object Ha nem if, akkor else. Ez opcionális Ha nem if, akkor else if. Ez is opcionális. else if után jöhet több else if után jöhet a végén else, opcionálisan.

Vezérlési szerkezetek • Elágazás (C): #include <stdio. h> int main() { int i =

Vezérlési szerkezetek • Elágazás (C): #include <stdio. h> int main() { int i = 10; if ( i < 15 ) // log kif! { //. . . } return 0; }

Vezérlési szerkezetek • Elágazás (C): #include <stdio. h> int main() { int i =

Vezérlési szerkezetek • Elágazás (C): #include <stdio. h> int main() { int i = 10; if ( i < 15 ) // log kif! { //. . . } else { //. . . } return 0; }

Vezérlési szerkezetek • Elágazás (C): #include <stdio. h> int main() { int i =

Vezérlési szerkezetek • Elágazás (C): #include <stdio. h> int main() { int i = 10; if ( i < 15 ) // log kif! { //. . . } else if ( i > -1 ) { // … } else { //. . . } return 0; }

Vezérlési szerkezetek • Elágazás(C++): #include <iostream> int main() { bool b = true; if

Vezérlési szerkezetek • Elágazás(C++): #include <iostream> int main() { bool b = true; if ( b ) // log kif! { //. . . } }

Vezérlési szerkezetek • Elágazás(C++): #include <iostream> int main() { bool b = false; if

Vezérlési szerkezetek • Elágazás(C++): #include <iostream> int main() { bool b = false; if ( b == true ) // log kif! { //. . . } // else … }

Vezérlési szerkezetek • Elágazás(C): – Ha egy elágazás feltételvizsgálatában nullától különböző számot adunk meg,

Vezérlési szerkezetek • Elágazás(C): – Ha egy elágazás feltételvizsgálatában nullától különböző számot adunk meg, akkor az megfelel az igaz kiértékelésnek. – float, int, double, short, … #include <stdio. h> int main() { int i = 10; if ( i ) // nem log kif, de jó! { //. . . } // else … }

Vezérlési szerkezetek • Elágazás(C): – Ha egy elágazás feltételvizsgálatában nulla (0) számot adunk meg,

Vezérlési szerkezetek • Elágazás(C): – Ha egy elágazás feltételvizsgálatában nulla (0) számot adunk meg, akkor az megfelel a hamis kiértékelésnek. #include <stdio. h> int main() { int i = 0; if ( i ) // nem log kif, de jó! { //. . . } // else … }

Vezérlési szerkezetek • Elágazás(C++): – Ha nem NULL egy object, akkor true. – Ha

Vezérlési szerkezetek • Elágazás(C++): – Ha nem NULL egy object, akkor true. – Ha NULL egy object, akkor false. #include <iostream> int main() { Kutya k = new Kutya(); // Később megnézzük, mi ez a Kutya! if ( k ) // nem log kif, de jó! { //. . . } // else … }

Vezérlési szerkezetek • Elágazás(C++): – Ha nem NULL egy object, akkor true. – Ha

Vezérlési szerkezetek • Elágazás(C++): – Ha nem NULL egy object, akkor true. – Ha NULL egy object, akkor false. #include <iostream> int main() { Kutya k = NULL; // Később megnézzük, mi ez a Kutya! if ( k ) // nem log kif, de jó! { //. . . } // else … }

Vezérlési szerkezetek • Elágazás(C++): – Nézzük a bugos részt! Mitől döglik a légy? Meg

Vezérlési szerkezetek • Elágazás(C++): – Nézzük a bugos részt! Mitől döglik a légy? Meg a program? – A feltétel kiértékelése : logikai, szám, object – Értékadás is lehet benne! – Oka: • A feltételben szereplő kiértékelés eredményét később is szeretnénk felhasználni. • Kevesebb erőforrást használunk! • Egyszer értékeljük ki a függvényt, később is használjuk az eredményét

Vezérlési szerkezetek • Elágazás(C++): – Nézzük a bugos részt! Mitől döglik a légy? Meg

Vezérlési szerkezetek • Elágazás(C++): – Nézzük a bugos részt! Mitől döglik a légy? Meg a program? – Akkor is előfordul, ha nem szeretnénk! (Gépelési hiba!) – Míg az első kiértékelés false, a második már true! #include <iostream> => Helyett => #include <iostream> int main() { bool b = false; if ( b == true )//log kif { std: : cout << ”bent”; } // else … } int main() { bool b = false; if ( b = true )// log kif { std: : cout << ”bent”; } // else … }

Vezérlési szerkezetek • Elágazás(C++): – Nézzük a bugos részt! Mitől döglik a légy? Meg

Vezérlési szerkezetek • Elágazás(C++): – Nézzük a bugos részt! Mitől döglik a légy? Meg a program! – Akkor is előfordul, ha nem szeretnénk! (Gépelési hiba!) – Míg az első kiértékelés false, a második már true! #include <iostream> => Helyett => #include <iostream> int main() { int i = 10; if (i == 0) // log kif! { std: : cout << ”bent”; } // else … } int main() { int i = 10; if ( i = 0 ) // log kif! { std: : cout << ”bent”; } // else … }

Vezérlési szerkezetek • Elágazás más nyelveken: – Vannak nyelvek, melyek erősebb megszorításokat tesznek az

Vezérlési szerkezetek • Elágazás más nyelveken: – Vannak nyelvek, melyek erősebb megszorításokat tesznek az if-ben történő értékadásra! – Nézzük ezt Java-ban. – Szuper! Logikaira ugyanolyan veszélyes! public class Main { public static void main() { boolean l = false; if(l = true) { System. out. println("1"); } else { System. out. println("2"); } } }

Vezérlési szerkezetek • Elágazás más nyelveken: – Vannak nyelvek, melyek erősebb megszorításokat tesznek az

Vezérlési szerkezetek • Elágazás más nyelveken: – Vannak nyelvek, melyek erősebb megszorításokat tesznek az if-ben történő értékadásra! – Nézzük ezt Java-ban. – Szuper! int-re már nem megy! Fordítási hiba! public class Main { public static void main() { int i = 10; if( i = 0 ) { System. out. println("1"); } else { System. out. println("2"); } } }

Vezérlési szerkezetek • Elágazás más nyelveken: – Vannak nyelvek, melyek erősebb megszorításokat tesznek az

Vezérlési szerkezetek • Elágazás más nyelveken: – Vannak nyelvek, melyek erősebb megszorításokat tesznek az if-ben történő értékadásra! – Nézzük ezt Ada-ban. – Fordítási hiba! procedure Elag 01 inada is b : Boolean : = true; begin if b : = false then null; end if; end Elag 01 inada;

Vezérlési szerkezetek • ternary operator (? : ) • (condition) ? (if_true) : (if_false)

Vezérlési szerkezetek • ternary operator (? : ) • (condition) ? (if_true) : (if_false) (x == y) ? a : b // GNU C : a = x ? : y; // megegyezik: a = x ? x : y;

Vezérlési szerkezetek • Más nyelvekben: – Java, C# hasonló – C#-ban: ? ? Operator

Vezérlési szerkezetek • Más nyelvekben: – Java, C# hasonló – C#-ban: ? ? Operator int? x = null; // y = x, ha x nem null, ha viszont az, akkor y = -1. int y = x ? ? -1; – javascript, ruby, …: obj = obj || {} obj ||= {};

Vezérlési szerkezetek • switch: – Nem logikai vizsgálat, hanem illesztés / összehasonlítás • switch:

Vezérlési szerkezetek • switch: – Nem logikai vizsgálat, hanem illesztés / összehasonlítás • switch: integer-expression (int alapú vagy arra konvertálható értékek) – case kiértékelőág. • • • Utasítások végrehajtása egyenlőség vizsgálat után Egy érték egyszer fordulhat elő Több utasítás esetén blokk: { … } Utasításmentes case ág is lehet. Továbbfolyás lehetséges Továbbfolyás megakadályozása: break; – default ág: • Ami nem illeszkedik, az ide jön! • Nem kötelező a switch végén lennie!

Vezérlési szerkezetek • switch: #include <iostream> int main() { int i = 1; switch(

Vezérlési szerkezetek • switch: #include <iostream> int main() { int i = 1; switch( i ) { case 0: std: : cout << 0; break; case 1: std: : cout << 1; break; case 4: std: : cout << 4; break; case 5: std: : cout << 5; default : std: : cout << "def"; } }

Vezérlési szerkezetek • switch: #include <iostream> int main() { int i = 1; switch(

Vezérlési szerkezetek • switch: #include <iostream> int main() { int i = 1; switch( i ) { case 0: { std: : cout << 0; std: : cout << 1; std: : cout << 4; }; break; case 5: std: : cout << 5; default : std: : cout << "def"; } }

Vezérlési szerkezetek • switch: Továbbfolyás #include <iostream> int main() { int i = 1;

Vezérlési szerkezetek • switch: Továbbfolyás #include <iostream> int main() { int i = 1; switch( i ) { case 0: std: : cout << 0; case 1: std: : cout << 1; case 4: std: : cout << 4; break; case 5: std: : cout << 5; default : std: : cout << "def"; } }

Vezérlési szerkezetek • switch: Házi feladat: Mi az eredmény ha: – i = 1;

Vezérlési szerkezetek • switch: Házi feladat: Mi az eredmény ha: – i = 1; – i = 6; esetén? #include <iostream> int main() { int i = 1; switch( i ) { case 1: std: : cout << 1; default : std: : cout << "def"; case 4: std: : cout << 4; break; case 5: std: : cout << 5; } }

Vezérlési szerkezetek • Ciklus: Előltesztelős #include <iostream> int main() { int i = 0;

Vezérlési szerkezetek • Ciklus: Előltesztelős #include <iostream> int main() { int i = 0; while (i < 10) { i += 1; } }

Vezérlési szerkezetek • Ciklus: Hátultesztelős #include <iostream> int main() { int i = 0;

Vezérlési szerkezetek • Ciklus: Hátultesztelős #include <iostream> int main() { int i = 0; do { // … } while (i < 10); }

Vezérlési szerkezetek • Ciklus: Számlálós #include <iostream> int main() { for(int i = 0;

Vezérlési szerkezetek • Ciklus: Számlálós #include <iostream> int main() { for(int i = 0; i < 10; i += 1) { // … } }

Vezérlési szerkezetek • Ciklus: Számlálós #include <iostream> int f(int); int main() { for(int i

Vezérlési szerkezetek • Ciklus: Számlálós #include <iostream> int f(int); int main() { for(int i = 0, j = 0; i + j < 10; i = f(j), j += 1) { // … } }

Vezérlési szerkezetek • Ciklus: Végtelen ciklusok #include <iostream> int main() { for(; ; )

Vezérlési szerkezetek • Ciklus: Végtelen ciklusok #include <iostream> int main() { for(; ; ) { // … } } int main() { while ( true ) { // … } }

Vezérlési szerkezetek • Ciklus: Feltétlen vezérlést átadó utasítások #include <iostream> int main() { int

Vezérlési szerkezetek • Ciklus: Feltétlen vezérlést átadó utasítások #include <iostream> int main() { int i = 1; while ( i < 10 ) { i += 1; std: : cout << i << std: : endl; if ( i != 5 ) { break; } } std: : cout << "kint vagyok" << std: : endl; }

Vezérlési szerkezetek • Ciklus: Feltétlen vezérlést átadó utasítások #include <iostream> int main() { int

Vezérlési szerkezetek • Ciklus: Feltétlen vezérlést átadó utasítások #include <iostream> int main() { int i = 1; while ( i < 10 ) { i += 1; if ( i < 5 ) { std: : cout << i << std: : endl; continue; } std: : cout << "kesobb jon!" << std: : endl; } }

Vezérlési szerkezetek • break; • continue; • labels

Vezérlési szerkezetek • break; • continue; • labels

Vezérlési szerkezetek • Összefoglaló: – using namespace-name: : name; – type-name = value; –

Vezérlési szerkezetek • Összefoglaló: – using namespace-name: : name; – type-name = value; – type-name(args); – expression; – { statements; }

Vezérlési szerkezetek – while(condition) { statement; } – for(init-statement; condition; expression) { statement; }

Vezérlési szerkezetek – while(condition) { statement; } – for(init-statement; condition; expression) { statement; } – if (condition) statement else statement 2 – return val;

Mutatók, dereferálás • Ha T egy típus, T* a „T-re hivatkozó mutató” típus lesz,

Mutatók, dereferálás • Ha T egy típus, T* a „T-re hivatkozó mutató” típus lesz, azaz egy T* típusú változó egy T típusú objektum címét tartalmazhatja. int* p 12

Mutatók, dereferálás • Változó deklarációja: int i; – A változó bizonyos (4 bájt) memóriát

Mutatók, dereferálás • Változó deklarációja: int i; – A változó bizonyos (4 bájt) memóriát foglal le. • Változó, mely pointer: int *pi = &i; – Az i által lefoglalt memória helye az adott változó címe. – Címének visszaadása: &i – i változó által lefoglalt memória mérete: sizeof(i)

Mutatók, dereferálás • Példa: int *pi = 12; char c = 'a'; char *p

Mutatók, dereferálás • Példa: int *pi = 12; char c = 'a'; char *p = &c; // p a c címét tárolja

Mutatók, dereferálás • Deklarálása: int* pa, pb; • Mi a típusa a változóknak? typeid(pa).

Mutatók, dereferálás • Deklarálása: int* pa, pb; • Mi a típusa a változóknak? typeid(pa). name(); // Pi vagy int* typeid(pb). name(); // i vagy int typeid(&pb). name(); // Pi vagy int* – typeid a typeinfo headerben • Nem mindegy, hogy hova kerül a *!

Mutatók, dereferálás • Jobb, ha így: int *pa, *pb; • Lint: – Használjuk a

Mutatók, dereferálás • Jobb, ha így: int *pa, *pb; • Lint: – Használjuk a *-t a változónál, ne a típusnál. Így automatikusan elkerüljük az ismertetett hibát.

Mutatók, dereferálás • Értékadás: int *p; p = 47; • Mihez rendeltünk értéket? –

Mutatók, dereferálás • Értékadás: int *p; p = 47; • Mihez rendeltünk értéket? – Megváltoztattuk a címét! – Nem mindig fordul! – g++ -Wall main. cpp -fpermissive • Nagy így már fordul • fpermissive kapcsoló: hibákat error szintről warningra nyom le.

Mutatók, dereferálás • A mutatókon elvégezhető művelet a „dereferencia”, azaz a mutató által mutatott

Mutatók, dereferálás • A mutatókon elvégezhető művelet a „dereferencia”, azaz a mutató által mutatott objektumra való hivatkozás. • indirekciónak is hívják; • jele: *

Mutatók, dereferálás • Dereferálás int i = 10; int *pi = &i; *pi =

Mutatók, dereferálás • Dereferálás int i = 10; int *pi = &i; *pi = 12; std: : cout << i << std: : endl; • *mutató: a hivatkozott értékhez hozzáférés, lekérdezés, beállítás

Mutatók, dereferálás #include <iostream> int main() { char c = 'a'; char *p =

Mutatók, dereferálás #include <iostream> int main() { char c = 'a'; char *p = &c; std: : cout << p << std: : endl; // a }

Konstansokról • Néha szeretném, ha egy memóriaterület ne változzon meg. • const kulcsszó •

Konstansokról • Néha szeretném, ha egy memóriaterület ne változzon meg. • const kulcsszó • const int ci = 12; • Azaz ci értékét nem tudom megváltoztatni a későbbiekben. 83

Konstansokról • A const a típusrendszer része, const int külön típus! • Constot beviszem

Konstansokról • A const a típusrendszer része, const int külön típus! • Constot beviszem a típusrendszerbe: – egy int *ip nem mutathat rá. • Megkövetelem: const int *cip legyen, ekkor cip = &ci; • De: cip konstans referencia, ezért *cip = 13 nem lehet! • ++cip működik, ++*cip nem!

Konstansokról • Más nyelvekben: – Java : final – C# : const/readonly – Ada

Konstansokról • Más nyelvekben: – Java : final – C# : const/readonly – Ada : constant 85

Konstansokról • Mi lehet konstans? • Változó, pointer, paraméter, függvény, osztály?

Konstansokról • Mi lehet konstans? • Változó, pointer, paraméter, függvény, osztály?

Konstansok • const int i = 12; • Deklarálunk egy int változót (i néven).

Konstansok • const int i = 12; • Deklarálunk egy int változót (i néven). • Konstans! Tehát értékét nem tudjuk megváltoztatni! • Értékadás a deklarációkor kötelező, mert i értéke a const miatt nem változtatható! 87

Konstansok int main() { const int i; return 0; } • Kimenet: const 01.

Konstansok int main() { const int i; return 0; } • Kimenet: const 01. cpp: 3: error: uninitialized const ’i’ 88

Konstansok int main() { const int i = 12; ++i; return 0; } •

Konstansok int main() { const int i = 12; ++i; return 0; } • Kimenet: const 01. cpp: 4: error: increment of read-only variable ’i’ 89

Konstansok • • Csináljunk pointert! Ráállítom a pointert a változóra! (nem const-ra) A konstans

Konstansok • • Csináljunk pointert! Ráállítom a pointert a változóra! (nem const-ra) A konstans nem változhat! És a mutatott érték? 90

Konstansok • Olyan pointer, melynek nem változhat! – Cím nem változik – És a

Konstansok • Olyan pointer, melynek nem változhat! – Cím nem változik – És a mutatott érték? • const int *cip = &ci; – Konstans int-re mutató pointer – Nem kötelező inicializálni. Egyszerű pointer! • int *const icp = &i; – intre mutató konstans pointer – Érték változhat, cím nem! – Itt is hiba, ha nem inicializáljuk a konstanst.

Konstansok int main() { int i = 12; int *const ip = &i; return

Konstansok int main() { int i = 12; int *const ip = &i; return 0; } • Kimenet: pipa 92

Konstansok #include <iostream> int main() { int i = 12; int *const ip =

Konstansok #include <iostream> int main() { int i = 12; int *const ip = &i; std: : cout << i << ” ” << ip << std: : endl; return 0; } • Kimenet: pipa 12 0 xf 2342 da 324 93

Konstansok #include <iostream> int main() { int i = 12; int *const ip =

Konstansok #include <iostream> int main() { int i = 12; int *const ip = &i; std: : cout << ++i << ” ” << *ip << std: : endl; return 0; } • Kimenet: pipa 13 12 (figyeljünk a kiértékelés sorrendjére!!!) 94

Konstansok #include <iostream> int main() { int i = 12; int *const ip =

Konstansok #include <iostream> int main() { int i = 12; int *const ip = &i; i = 11; std: : cout << i << ” ” << *ip << std: : endl; return 0; } • Kimenet: pipa 95 11 11

Konstansok #include <iostream> int main() { int i = 12; int *const ip =

Konstansok #include <iostream> int main() { int i = 12; int *const ip = &i; std: : cout << ++i << ” ” << ++(*ip); return 0; } • Kimenet: pipa Rontsuk el! ; ] 14 13 (Kiértékelési sorrend!!! Jobbról kezd!!!) 96

Konstansok #include <iostream> int main() { int i = 12; int *const ip =

Konstansok #include <iostream> int main() { int i = 12; int *const ip = &i; std: : cout << ++i << ” ” << ++ip; return 0; } • Kimenet: const 05. cpp: 7: error: increment of read-only variable ’ip’ 97

Konstansok • Ok, de én egy olyan pointert akarok, amit tudok változtatni, de az

Konstansok • Ok, de én egy olyan pointert akarok, amit tudok változtatni, de az értéket, amire mutat, azt nem! 98

Konstansok (nézzük csak másképp!) #include <iostream> int main() { int i = 12; const

Konstansok (nézzük csak másképp!) #include <iostream> int main() { int i = 12; const int *ip = &i; std: : cout << ++i << ” ” << ++(*ip); return 0; } • Kimenet: const 05. cpp: 7: error: increment of read-only variable ’* ip’ 99

Konstansok (nézzük csak másképp!) #include <iostream> int main() { int i = 12; const

Konstansok (nézzük csak másképp!) #include <iostream> int main() { int i = 12; const int *ip = &i; std: : cout << ++i << ” ” << ++ip; return 0; } • Kimenet: 13 0 x 12 df 321 c 5 100

Konstansok (nézzük csak másképp!) #include <iostream> int main() { const int i = 12;

Konstansok (nézzük csak másképp!) #include <iostream> int main() { const int i = 12; int *ip = &i; std: : cout << i << ” ” << ++*ip; return 0; } • Kimenet: const 08. cpp: 6: error: invalid conversion from ’const int*’ to ’int*’ 101

Konstansok • Ajánlott odafigyelni a sorrendre: – const int* i – int* const i

Konstansok • Ajánlott odafigyelni a sorrendre: – const int* i – int* const i 102

Konstansok • Egy olyan pointer kell, amit nem változtathatok és az általa mutatott értéket

Konstansok • Egy olyan pointer kell, amit nem változtathatok és az általa mutatott értéket sem! 103

Konstansokról • const int *const cicp = &ci; – Mutathat konstansra, de mindig ugyanoda

Konstansokról • const int *const cicp = &ci; – Mutathat konstansra, de mindig ugyanoda kell, hogy mutasson. 104

Konstansok • Javítsuk ki, hogy az inkrementációs operátorra panaszkodjon! 105

Konstansok • Javítsuk ki, hogy az inkrementációs operátorra panaszkodjon! 105

Konstansok #include <iostream> int main() { const int i = 12; const int* const

Konstansok #include <iostream> int main() { const int i = 12; const int* const ip = &i; std: : cout << i << ” ” << ++*ip; return 0; } • Kimenet: const 08. cpp: 7: error: increment of read-only location `*(const int*)ip` 106

Konstansok #include <iostream> int main() { const int i = 12; int* const ip

Konstansok #include <iostream> int main() { const int i = 12; int* const ip = &i; std: : cout << i << ” ” << ++*ip; return 0; } • Kimenet: const 08. cpp: 6: error: invalid conversion from ’const int*’ to ’int*’ 107

Konstansok • Tehát egy olyan pointerünk van a const int változó mellett, mely egy

Konstansok • Tehát egy olyan pointerünk van a const int változó mellett, mely egy const intre mutat, és ezzel együtt nem lehet megváltoztatni az értékét. • const int *const ip = &i; • int const *const ip = &i; • A fenti kettő megegyezik! – De utóbbit kerüljük! Kevésbé érthető, kevésbé használt! 108

Konstansokról class Date {. . . } const Date mybirthday =. . . ;

Konstansokról class Date {. . . } const Date mybirthday =. . . ; mybirthday =. . . mybirthday. f(); 109

Konstansokról • Azok a függvények, melyek nem változtatják meg a függvény belsejét, deklarálhatom konstans

Konstansokról • Azok a függvények, melyek nem változtatják meg a függvény belsejét, deklarálhatom konstans tag-függvénynek. 110

Konstansokról class Date { … // ha ez const lenne, // akkor hibát dobna

Konstansokról class Date { … // ha ez const lenne, // akkor hibát dobna a fordító! void set_day(int x) { day = x; } int get_day() const { return day; } … } 111

Függvények bevezetése • Tartalom: – Függvénydeklaráció és –definíció – Paraméterátadás – Visszatérési érték

Függvények bevezetése • Tartalom: – Függvénydeklaráció és –definíció – Paraméterátadás – Visszatérési érték

Függvények • Függvénydefiníció: – A program kisebb egységekre bontása. – Minden függvényt valahol meg

Függvények • Függvénydefiníció: – A program kisebb egységekre bontása. – Minden függvényt valahol meg kell határoznunk. – Függvénydefiníció olyan deklaráció, ahol megadjuk a függvény törzsét. – Felépítése: type name ( parameter 1, parameter 2, . . . ) { statements }

Függvények • Más nyelvekben: – C/C++ alapú nyelvekben szintén void és társai – Adában

Függvények • Más nyelvekben: – C/C++ alapú nyelvekben szintén void és társai – Adában function és procedure keyword

Függvények • Definíció: – A teljes specifikáció! type name ( parameter 1 [paramname], parameter

Függvények • Definíció: – A teljes specifikáció! type name ( parameter 1 [paramname], parameter 2, . . . ) • Szignatúra: – Visszatérési érték típusát nem tartalmazza – Paraméterneveket szintén nem name ( parameter 1, parameter 2, . . . )

Függvények • Függvények deklarációja: – Forward declaration – Megadom a függvény használatának módját –

Függvények • Függvények deklarációja: – Forward declaration – Megadom a függvény használatának módját – Ezt hívjuk még function prototype-nak is

Függvények • Példa: void swap(int*, int*); // deklaráció, function proto. //. . . void

Függvények • Példa: void swap(int*, int*); // deklaráció, function proto. //. . . void swap(int *p, int *q) // definíció { int t = *p; *p = *q; *q = t; }

Függvények • Paraméterátadás – Amikor egy függvény meghívódik, a fordítóprogram a formális paraméterek számára

Függvények • Paraméterátadás – Amikor egy függvény meghívódik, a fordítóprogram a formális paraméterek számára tárterületet foglal le, az egyes formális paraméterek pedig a megfelelő valódi (aktuális) paraméter-értékkel töltődnek fel. – A paraméterátadás szerepe azonos a kezdeti értékátadáséval – A fordítóprogram ellenőrzi, hogy az aktuális paraméterek típusa megegyezik-e a formális paraméterek típusával, és végrehajt minden szabványos és felhasználói típuskonverziót

Függvények • Paraméterátadás – Érték szerinti – Cím szerinti – Referencia szerinti – Eredmény

Függvények • Paraméterátadás – Érték szerinti – Cím szerinti – Referencia szerinti – Eredmény szerinti

Függvények • Paraméterátadás: érték szerint sum(int a, int b) { return a + b;

Függvények • Paraméterátadás: érték szerint sum(int a, int b) { return a + b; } int main() { std: : cout << sum(12, 34) << std: : endl; }

Függvények • Paraméterátadás: cím szerint (pass by address, pass by pointer) int f(int *a)

Függvények • Paraméterátadás: cím szerint (pass by address, pass by pointer) int f(int *a) { // a mutatott érték módosítása std: : cout << ++*a; return *a; } int main() { int i = 10; int *ip = &i; // megkapja i címét! std: : cout << f(ip) << ”|” << *ip << std: : endl; } Kimenet: 11 11|10

Függvények • Mi történik itt? – A pointerek (címek) mindig érték szerint adódnak át!

Függvények • Mi történik itt? – A pointerek (címek) mindig érték szerint adódnak át!

Függvények • Referencia szerinti paraméterátadás void f(int &a) { a += 1; } int

Függvények • Referencia szerinti paraméterátadás void f(int &a) { a += 1; } int main() { int i = 1; f(i); std: : cout << i << std: : endl; // 2 }

Függvények • Referencia szerinti paraméterátadás void f(int &a) { a += 1; } int

Függvények • Referencia szerinti paraméterátadás void f(int &a) { a += 1; } int main() { int i = 1; f(10); std: : cout << i << std: : endl; } type ‘int&’ from an rvalue of type ‘int’

Függvények • rvalue : (később) int a = 42; int b = 43; //

Függvények • rvalue : (később) int a = 42; int b = 43; // a, b l-value: a = b; // ok b = a; // ok a = a * b; // ok // a * b rvalue: int c = a * b; // ok, rvalue jobb oldalon a * b = 42; // error, rvalue bal oldalon

Függvények • Paraméterátadás: Érték és referencia szerint void f(int val, int& ref) { val++;

Függvények • Paraméterátadás: Érték és referencia szerint void f(int val, int& ref) { val++; ref++; } void main() { int i = 1; int j = 1; f(i, j); // i == 1, j == 2 }

Függvények • Eredmény szerinti – pass-by-result vs. pass-by-value-return – Az átadott paraméter (pointer) lemásolódik.

Függvények • Eredmény szerinti – pass-by-result vs. pass-by-value-return – Az átadott paraméter (pointer) lemásolódik. – Maga az érték nem kerül másolásra • Ada

Függvények • Egyéb: – pass-by-name – pass-by-value-returned – pass-by-lazy-evaluation (lusta kiértékelés)

Függvények • Egyéb: – pass-by-name – pass-by-value-returned – pass-by-lazy-evaluation (lusta kiértékelés)

Függvények • Más nyelvekben: – Ada: paraméter átadásától függő, in, out, in out –

Függvények • Más nyelvekben: – Ada: paraméter átadásától függő, in, out, in out – Java: minden érték szerint

Függvények • Visszatérési érték szerint megkülönböztetünk: – Eljárásokat (void) – Függvényeket (minden más)

Függvények • Visszatérési érték szerint megkülönböztetünk: – Eljárásokat (void) – Függvényeket (minden más)

Függvények • return: – visszatérés • void esetén: – return; vezérlés megszakítása – return

Függvények • return: – visszatérés • void esetén: – return; vezérlés megszakítása – return 10; hiba! void nem int!

Függvények • Függvények esetén: – Return utasítás nem kötelező – Ez veszélyes! int f()

Függvények • Függvények esetén: – Return utasítás nem kötelező – Ez veszélyes! int f() { std: : cout << ”Hello”; }

Függvények int f() {} int main() { int i = f(); std: : cout

Függvények int f() {} int main() { int i = f(); std: : cout << i; // kimenet: 1 }

Függvények int f() { return; } int main() { int i = f(); std:

Függvények int f() { return; } int main() { int i = f(); std: : cout << i; } error: return-statement with no value, . . .

Függvények • Visszatérési érték – A main() kivételével minden nem void metódusnak kell visszatérési

Függvények • Visszatérési érték – A main() kivételével minden nem void metódusnak kell visszatérési értékkel rendelkeznie. – lokális változóra hivatkozó mutatót soha nem szabad visszaadni

Függvények int f 1() { } // hiba: nincs visszatérési érték, ettől még lehet

Függvények int f 1() { } // hiba: nincs visszatérési érték, ettől még lehet jó void f 2() { } // rendben int f 3() { return 1; } // rendben void f 4() { return 1; } // hiba: visszatérési érték void függvényben int f 5() { return; } // hiba: visszatérési érték hiányzik void f 6() { return; } // rendben

Függvények • Nézzük a rázós eseteket. • Kezdjük kicsivel.

Függvények • Nézzük a rázós eseteket. • Kezdjük kicsivel.

Függvények int f() { return ’c’; } int main() { std: : cout <<

Függvények int f() { return ’c’; } int main() { std: : cout << f() << std: : endl; // 99 return 0; }

Függvények int f() { int i = a + b; } int main() {

Függvények int f() { int i = a + b; } int main() { std: : cout << f(10, 12); // 22 return 0; }

Függvények int f() { int i = a + b; int k; } int

Függvények int f() { int i = a + b; int k; } int main() { std: : cout << f(10, 12); // 22 return 0; }

Függvények int f() { int i = a + b; int k; 10 +

Függvények int f() { int i = a + b; int k; 10 + 8; } int main() { std: : cout << f(10, 12); // 22 return 0; }

Függvények int f() { int i = a + b; int k; 10 +

Függvények int f() { int i = a + b; int k; 10 + 8; i = b + 100; } int main() { std: : cout << f(10, 12); // 112 return 0; }

Függvények int f() { int i = a + b; int k; 10 +

Függvények int f() { int i = a + b; int k; 10 + 8; i = b + 100; i = a + 1; } int main() { std: : cout << f(10, 12); // 11 return 0; }

Függvények int f() { int i = a + b; int k; 10 +

Függvények int f() { int i = a + b; int k; 10 + 8; i = b + 100; i = a + 1; std: : cout << ”hello”; } int main() { std: : cout << f(10, 12); // 1234520896 return 0; }

Függvények int f() { int i = a + b; int k; 10 +

Függvények int f() { int i = a + b; int k; 10 + 8; i = b + 100; i = a + 1; std: : cout << ”hello”; k = 19 + a; } int main() { std: : cout << f(10, 12); // 29 return 0; }

Függvények bevezetése • Túlterhelés: – Később!

Függvények bevezetése • Túlterhelés: – Később!

Konstansok és függvények • Függvények visszatérési értéke gubancos lehet! • Baj van, ha valami

Konstansok és függvények • Függvények visszatérési értéke gubancos lehet! • Baj van, ha valami gubanc futás időben derül ki! • Javítsuk úgy a kódot, hogy fordítási időben kiszűrjük a bajos részeket! 147

Konstansok (függvény visszatérési értéke) #include <iostream> char* f() { return ”szoveg”; } int main()

Konstansok (függvény visszatérési értéke) #include <iostream> char* f() { return ”szoveg”; } int main() { f()[0] = ’b’; } • Segmentation fault 148

Konstansok (függvény visszatérési értéke) #include <iostream> const char* f() { return ”szoveg”; } int

Konstansok (függvény visszatérési értéke) #include <iostream> const char* f() { return ”szoveg”; } int main() { f()[0] = ’b’; } • Kimenet: fconst 01. cpp: 10: error: assignment of read-only location ’* f()’ 149

Konstansok (függvény visszatérési értéke) #include <iostream> int* f() { int i = 12; const

Konstansok (függvény visszatérési értéke) #include <iostream> int* f() { int i = 12; const int* ip = &i; return ip; } • Kimenet: fconst 01. cpp: 7: error: invalid conversion from ’const int*’ to ’int*’ 150

Konstansok (paraméterátadás) • Érték, referencia, pointer szerint! void f( int i ) { i

Konstansok (paraméterátadás) • Érték, referencia, pointer szerint! void f( int i ) { i = 10; } void f( int& i ) { i = 10; } void f( int* i ) { *i = 10; } 151

Konstansok • Kicsit előre ugrunk! • User-defined type void f( my. Type &my );

Konstansok • Kicsit előre ugrunk! • User-defined type void f( my. Type &my ); • Ekkor: – Valamilyen belső műveletet szeretnénk elvégeztetni rajta! – Optimalizálás: csak a címét másoljuk, ne az egész objektumot! Gyorsabb, nő a hatékonyság! • De mi van akkor, ha valaki módosítja a saját tudta nélkül? Arra gondol, hogy úgy sem módosul a metódus belsejében! Gubancos! • void f( const my. Type &my ); 152

Konstansok • Haladjunk az osztályok mentén még mindig! • Osztály specifikációja: class Clazz {

Konstansok • Haladjunk az osztályok mentén még mindig! • Osztály specifikációja: class Clazz { void f(); int i; } 153

Konstansok • Ennek az implementációja: void Clazz: : f() { ++i; } • Mi

Konstansok • Ennek az implementációja: void Clazz: : f() { ++i; } • Mi történik, ha a specifikációban megtiltom, hogy az adott metódus implementációja módosítsa az osztály adott mezőjét? • Nézzünk egy példát! 154

Konstansok class Clazz { void f() const; int i; } • Kimenet: increment of

Konstansok class Clazz { void f() const; int i; } • Kimenet: increment of data-member ’Clazz: : i’ in read-only structure 155

Konstansok • És akkor nézzünk valami nagyon advanced-et! • Interjún megkérdezhetik! • Mit csinál

Konstansok • És akkor nézzünk valami nagyon advanced-et! • Interjún megkérdezhetik! • Mit csinál az alábbi metódus! Mondj el mindent, amit tudsz róla! const int* const Method 3( const int* const& ) const; 156

Kódelemzés • Feladat: Írj olyan programot, mely kiszámolja egy Fahrenheit értékhez tartozó Celsius értéket!

Kódelemzés • Feladat: Írj olyan programot, mely kiszámolja egy Fahrenheit értékhez tartozó Celsius értéket! -100 -tól indulunk, +300 -ig megyünk, és 10 a lépésnagyság!

Kódelemzés fahr 2 cels v 1 (C): #include <stdio. h> // a program fahrenheit

Kódelemzés fahr 2 cels v 1 (C): #include <stdio. h> // a program fahrenheit és ahhoz megfelelő celsius értékeket ír ki int main() { int fahr; for (fahr = -100 ; fahr <= 300; fahr += 10) { printf("fahr = %dt cels =%dn", fahr, 5/9 * (fahr - 32)); } return 0; } Kimenet: F=0 C=0 F = 40 C = 0. . .

Kódelemzés • Mi történik itt? • Statikus típusrendszerű nyelvek esetén a fordítóprogramnak már fordítási

Kódelemzés • Mi történik itt? • Statikus típusrendszerű nyelvek esetén a fordítóprogramnak már fordítási időben kell tudnia, hogy milyen típusokkal dolgozik, e szerint foglal majd memóriát, vizsgálja a műveleteket! • int / int => int • Fordító nem foglalkozik azzal, hogy értékvesztéssel jár a művelet, fordítási időben nem tudja, hogy milyen érték kerül a változóba

Kódelemzés fahr 2 cels v 2 (C): #include <stdio. h> // a program fahrenheit

Kódelemzés fahr 2 cels v 2 (C): #include <stdio. h> // a program fahrenheit és ahhoz megfelelő celsius értékeket ír ki int main() { int fahr; for (fahr = -100; fahr <= 300; fahr += 10) { printf("fahr = %dt cels =%dn", fahr, 5. /9 * (fahr - 32)); } return 0; } Kimenet: fahr 2 cels 2. c: In function ‘main’: fahr 2 cels 2. c: 13: warning: format ‘%d’ expects type ‘int’, but argument 4 has type ‘double’

Kódelemzés • A kód ugyan lefordul, de a warning mindig rossz ómen! • float

Kódelemzés • A kód ugyan lefordul, de a warning mindig rossz ómen! • float / int => float

Kódelemzés fahr 2 cels v 3 (C): #include <stdio. h> // a program fahrenheit

Kódelemzés fahr 2 cels v 3 (C): #include <stdio. h> // a program fahrenheit és ahhoz megfelelő celsius értékeket ír ki int main() { int fahr; for (fahr = -100; fahr <= 300; fahr += 10) { printf("fahr = %dt cels =%fn", fahr, 5. /9 * (fahr - 32)); } return 0; } Kimenet: F = 0 C = -17. 777778 F = 40 C = 4. 444444. . .

Kódelemzés fahr 2 cels v 4 (C): #include <stdio. h> #define LOWER -100 #define

Kódelemzés fahr 2 cels v 4 (C): #include <stdio. h> #define LOWER -100 #define UPPER 300 #define STEP 10 // a program fahrenheit és ahhoz megfelelő celsius értékeket ír ki int main() { int fahr; for (fahr = LOWER; fahr <= UPPER; fahr += STEP) { printf("fahr = %dt cels =%fn", fahr, 5. /9 * (fahr - 32)); } return 0; } Kimenet: F = 0 C = -17. 777778 F = 40 C = 4. 444444. . .

Kódelemzés • Ha már megoldottuk C-ben, láttuk a hátrányait, akkor nézzük meg ugyanezt a

Kódelemzés • Ha már megoldottuk C-ben, láttuk a hátrányait, akkor nézzük meg ugyanezt a feladatot C++-ben!

Kódelemzés fahr 2 cels v 5 (C++): #include <iostream> using namespace std; int main()

Kódelemzés fahr 2 cels v 5 (C++): #include <iostream> using namespace std; int main() { } for ( int fahr = 0; fahr <= 200; fahr+=40) { cout << "F = " << fahr << 't' << "C = " << 5. /9*(fahr-32) << endl; } return 0; // Opcionális!

Kódelemzés • Egyszerűen típushelyesen tudom kiíratni, és fordítási időben kapok jelzés, ahelyett, hogy futásidőben

Kódelemzés • Egyszerűen típushelyesen tudom kiíratni, és fordítási időben kapok jelzés, ahelyett, hogy futásidőben szállna el, vagy kapnék rossz eredményt!

Kódelemzés fahr 2 cels v 6 (C++): #include <iostream> using namespace std; int main()

Kódelemzés fahr 2 cels v 6 (C++): #include <iostream> using namespace std; int main() { const int lower = 0; const int upper = 200; const int step = 40; for ( int fahr = lower; fahr <= upper; fahr+=step ) { cout << "F = " << fahr << 't' << "C = " << 5. /9*(fahr-32) << endl; } return 0; }

Kódelemzés • Mi az a const és miért kell? • Növeltük a maintence-t! Kiemeltük

Kódelemzés • Mi az a const és miért kell? • Növeltük a maintence-t! Kiemeltük a constans értékeket! • const : nem állhat az értékadás bal oldalán!

Kódelemzés fahr 2 cels v 7 (C++): #include <iostream> using namespace std; inline double

Kódelemzés fahr 2 cels v 7 (C++): #include <iostream> using namespace std; inline double fahr 2 cels( double f ) { return 5. /9 * ( f-32 ); } int main() { const int lower = 0; const int upper = 200; const int step = 40; for ( int fahr = lower; fahr <= upper; fahr+=step ) { cout << "F = " << fahr << 't' << "C = " << fahr 2 cels(fahr) << endl; } return 0; }

Kódelemzés • inline: az egyik legjobb hatékonyságnövelő eszköz. • Abban az esetben, amikor egyszerű

Kódelemzés • inline: az egyik legjobb hatékonyságnövelő eszköz. • Abban az esetben, amikor egyszerű fgv-törzsről van szó, behelyettesíti az adott kódot a meghívó helyére! • Egy esetben nem lehet ezt megcsinálni, amikor virtuális fgv-eket használok! Ugyanis futásidőben dől el, hogy a dinamikus kötések melyikével, melyik implementációval futtassa a fgv-t! Ezek kiértékelése a fordító számára sokkal lassabb! (De ezekről később)

Kódelemzés • Feladat: Írjuk meg a jó öreg cat parancsot! Amit begépelünk, azt adja

Kódelemzés • Feladat: Írjuk meg a jó öreg cat parancsot! Amit begépelünk, azt adja vissza a következő sorban, ha entert vagy Ctrl+D-t ütöttünk!

Kódelemzés cat (C): #include <stdio. h> int main() { int ch; while ( (ch

Kódelemzés cat (C): #include <stdio. h> int main() { int ch; while ( (ch = getchar()) != EOF) { putchar(ch); } return 0; } Kimenet: asdf asd fasd fas

Kódelemzés • cat (C++): #include <iostream> int main() { char ch; std: : cin

Kódelemzés • cat (C++): #include <iostream> int main() { char ch; std: : cin >> ch; // egy előolvasás! while ( std: : cin. good() ) { std: : cout << ch; // ha nem volt hiba, akkor mehetünk tovább! ch << std: : cin; } return 0; }

Kódelemzés cat (C++): #include <iostream> using namespace std; int main() { char ch; //

Kódelemzés cat (C++): #include <iostream> using namespace std; int main() { char ch; // fontos, defaultból tetsz. karakter while ( cin >> ch ) { cout << ch; } return 0; } Kimenet: asdf asd fas asdfasdfas

Kódelemzés #include <iostream> int main() { char ch; std: : cin >> noskipws; std:

Kódelemzés #include <iostream> int main() { char ch; std: : cin >> noskipws; std: : cin >> ch; // egy előolvasás! while ( std: : cin. good() ) { // ha nem volt hiba, akkor mehetünk tovább! std: : cout << ch; std: : cin >> ch; } return 0; }

Kódelemzés cat (C++): #include <iostream> using namespace std; int main() { char ch; //

Kódelemzés cat (C++): #include <iostream> using namespace std; int main() { char ch; // fontos, defaultból tetsz. Karakter // cin >> átugorja a whitespace-eket!!! while ( cin. get(ch)) { cout. put(ch); } return 0; } Kimenet: asdf asd fasd fas