programozási nyelvek (c++) gyakorlat gyak 02

176
Programozási Nyelvek (C++) Gyakorlat Gyak 02. Török Márk [email protected] D-2.620 1

Upload: galena

Post on 19-Mar-2016

76 views

Category:

Documents


7 download

DESCRIPTION

Programozási Nyelvek (C++) Gyakorlat Gyak 02. Török Márk tmark @ caesar.elte.hu D-2.620. 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 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Programozási Nyelvek (C++) Gyakorlat

Gyak 02.

Török Má[email protected]

D-2.620

1

Page 2: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 3: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Típusozás

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

Page 4: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Típusozás

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

Page 5: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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, AdaCore

• 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!

Page 6: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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.1end Strong;

Page 7: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 8: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Gyengén típusos nyelv (C++)void weakTyping ( void ) {

int alpha = 1 ; int beta = 10 ; float result; result = alpha / beta; // 0

}

Page 9: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Gyengén típusos nyelv (Java)void weakTyping () {

int alpha = 1 ; int beta = 10 ; float result; result = alpha / beta; // 0

}

Page 10: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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.

Page 11: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 12: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 13: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 : %f\t, si : %f\n", sizeof(s), sizeof(si));}

Page 14: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Típusos nyelv#include <stdio.h>

int main() { short s = 10; short int si = 1; printf ("s : %d\t, si : %d\n", sizeof(s), sizeof(si));}

Page 15: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 : %f\t, si : %f\n", 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!

Page 16: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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*

Page 17: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 18: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Statikus típusrendszer (C++-ben)

int main(){

auto i;return 0;

}

error: declaration of ‘auto i’ has no initializer

Page 19: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Statikus típusrendszer (C++-ben)

int main(){

auto i;i = 12;return 0;

}

error: declaration of ‘auto i’ has no initializer

Page 20: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Statikus típusrendszer (C++-ben)

int main(){

auto i = 12;return 0;

}

Page 21: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Statikus típusrendszer (C++-ben)#include <iostream>#include <typeinfo>

int main(){

auto i = 12;std::cout << typeid(i).name(); // ireturn 0;

}

Page 22: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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>’

Page 23: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Statikus típusrendszer (C++-ben)#include <iostream>#include <typeinfo>

class Clazz { };

int main(){

auto i = new Clazz();std::cout << typeid(i).name(); // PlClazzreturn 0;

}

Page 24: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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ú!

Page 25: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Statikus típusrendszer (C++-ben)

int main(){

register int i = 12;return 0;

}

Page 26: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Statikus típusrendszer (C++-ben)#include <iostream>#include <typeinfo>

int main(){

int i = 12;decltype(i) j = ’c’;std::cout << typeid(j).name(); // ireturn 0;

}

Page 27: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 • JavaScript (Elképesztő gyenge lábakon álló típusrendszer)

Page 28: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Deklaráció és értékadás

• Deklaráció:– típusnév változónév1;– típusnév változónév1, változónév2, …;

• É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ó.

Page 29: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Deklaráció és értékadás

int main(){

int i;i = 0;int k;

}

Page 30: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Deklaráció és értékadás

int main(){

int i = 0;int k;

}

Page 31: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Deklaráció és értékadás• C-ben:

#include <stdio.h>

int main() { int i, j, k = 0; printf("%d | %d | %d", i, j, k); return 0;}

Page 32: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Deklaráció és értékadás• C-ben:

– Fordítás: gcc dek01.c -o dek01 –Wall

– Fordítás eredménye:dek01.c: In function ‘main’:dek01.c:5: warning: ‘i’ is used uninitialized in this functiondek01.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?!?!

Page 33: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Deklaráció és értékadás• C-ben:

#include <stdio.h>

int main() { int i = j = k = 0; printf("%d | %d | %d", i, j, k); return 0;}

Page 34: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Deklaráció és értékadás• C-ben:

– Fordítás: gcc dek01.c -o dek01 –Wall

– Fordítás eredménye:dek01.c: In function ‘main’:dek01.c:5: error: ‘j’ undeclared (first use in this function)dek01.c:5: error: (Each undeclared identifier is reported only

oncedek01.c:5: error: for each function it appears in.)dek01.c:5: error: ‘k’ undeclared (first use in this function)

• Error!• Más út?

Page 35: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Deklaráció és értékadás• C-ben:

#include <stdio.h>

int main() { int i, j, k; i = j = k = 0; printf("%d | %d | %d", i, j, k); return 0;}

Page 36: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Deklaráció és értékadás• C-ben:

– Fordítás: gcc dek01.c -o dek01 –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-külön az elemeknek?

Page 37: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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!

Page 38: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 dek01inada is i, j, k : integer := 0;begin ada.text_io.put_line( Integer'Image(i)

& Integer'Image(j) & Integer'Image(k));

end dek01inada;

Page 39: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Deklaráció és értékadás• Az output:$ gnatmake dek01inada.adb …$ ./dek01inada 0 0 0

• Siker! Adában meg lehet csinálni!

Page 40: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Üres utasítás

• A jó öreg skip!• ;

int main(){

;;; // három üres utasításreturn 0;

}

Page 41: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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.– else if után jöhet a végén else, opcionálisan.

Page 42: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

• Elágazás (C):

#include <stdio.h>

int main() { int i = 10; if ( i < 15 ) // log kif! { // ... } return 0;}

Page 43: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

• Elágazás (C):

#include <stdio.h>

int main() { int i = 10; if ( i < 15 ) // log kif! { // ... } else { // ... } return 0;}

Page 44: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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;}

Page 45: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

• Elágazás(C++):

#include <iostream>

int main() { bool b = true; if ( b ) // log kif! { // ... }}

Page 46: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

• Elágazás(C++):

#include <iostream>

int main() { bool b = false; if ( b == true ) // log kif! { // ... } // else …}

Page 47: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 …}

Page 48: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 …}

Page 49: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 …}

Page 50: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 …}

Page 51: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 52: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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>

int main() { bool b = false; if ( b == true )//log kif { std::cout << ”bent”; } // else …}

=> Helyett => #include <iostream>

int main() { bool b = false; if ( b = true )// log kif { std::cout << ”bent”; } // else …}

Page 53: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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>

int main() { int i = 10; if (i == 0) // log kif! { std::cout << ”bent”; } // else …}

=> Helyett => #include <iostream>

int main() { int i = 10; if ( i = 0 ) // log kif! { std::cout << ”bent”; } // else …}

Page 54: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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"); } }}

Page 55: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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"); } }}

Page 56: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 Elag01inada is b : Boolean := true;begin if b := false then null; end if;end Elag01inada;

Page 57: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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;

Page 58: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 ||= {};

Page 59: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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!

Page 60: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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"; } }

Page 61: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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"; } }

Page 62: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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"; } }

Page 63: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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; } }

Page 64: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

• Ciklus: Előltesztelős

#include <iostream>int main() { int i = 0; while (i < 10) { i += 1; } }

Page 65: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

• Ciklus: Hátultesztelős

#include <iostream>int main() { int i = 0; do { // … } while (i < 10);}

Page 66: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

• Ciklus: Számlálós

#include <iostream>

int main() { for(int i = 0; i < 10; i += 1) { // … }}

Page 67: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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) { // … }}

Page 68: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

• Ciklus: Végtelen ciklusok

#include <iostream>

int main() { for(;;) { // … }}

int main() { while ( true ) { // … }}

Page 69: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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;}

Page 70: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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; } }

Page 71: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

• break;• continue;• labels

Page 72: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

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

Page 73: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Vezérlési szerkezetek

– while(condition) { statement; }– for(init-statement; condition; expression)

{ statement; }– if (condition) statement– if (condition) statement else statement2– return val;

Page 74: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 75: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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)

Page 76: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Mutatók, dereferálás

• Példa:int *pi = 12;char c = 'a';char *p = &c; // p a c címét tárolja

Page 77: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 inttypeid(&pb).name(); // Pi vagy int*– typeid a typeinfo headerben

• Nem mindegy, hogy hova kerül a *!

Page 78: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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.

Page 79: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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.

Page 80: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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: *

Page 81: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Mutatók, dereferálás

• Dereferálásint 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

Page 82: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Mutatók, dereferálás

#include <iostream>

int main() { char c = 'a'; char *p = &c;

std::cout << p << std::endl; // a}

Page 83: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 84: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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!

Page 85: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansokról

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

85

Page 86: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansokról

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

Page 87: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 88: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansokint main(){

const int i;return 0;

}

• Kimenet:const01.cpp: 3: error: uninitialized const ’i’

88

Page 89: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansokint main(){

const int i = 12;++i;return 0;

}

• Kimenet:const01.cpp: 4: error: increment of read-only variable ’i’

89

Page 90: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 91: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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.

Page 92: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansokint main(){

int i = 12;int *const ip = &i;return 0;

}

• Kimenet: pipa

92

Page 93: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok#include <iostream>

int main(){

int i = 12;int *const ip = &i;std::cout << i << ” ” << ip <<

std::endl;return 0;

}

• Kimenet: pipa12 0xf2342da324 93

Page 94: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok#include <iostream>

int main(){

int i = 12;int *const ip = &i;std::cout << ++i << ” ” << *ip <<

std::endl;return 0;

}

• Kimenet: pipa13 12 (figyeljünk a kiértékelés sorrendjére!!!) 94

Page 95: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok#include <iostream>

int main(){

int i = 12;int *const ip = &i;i = 11;std::cout << i << ” ” << *ip <<

std::endl;return 0;

}• Kimenet: pipa

11 1195

Page 96: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 97: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok#include <iostream>

int main(){

int i = 12;int *const ip = &i;std::cout << ++i << ” ” << ++ip;return 0;

}

• Kimenet:const05.cpp: 7: error: increment of read-only variable ’ip’

97

Page 98: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok

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

98

Page 99: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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: const05.cpp: 7: error: increment of read-only variable ’* ip’

99

Page 100: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 0x12df321c5

100

Page 101: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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: const08.cpp:6: error: invalid conversion from ’const int*’ to ’int*’

101

Page 102: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok

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

102

Page 103: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok

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

103

Page 104: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansokról

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

hogy mutasson.

104

Page 105: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok

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

105

Page 106: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok#include <iostream>

int main(){

const int i = 12;const int* const ip = &i;std::cout << i << ” ” << ++*ip;return 0;

}

• Kimenet: const08.cpp:7: error: increment of read-only location `*(const int*)ip`

106

Page 107: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok#include <iostream>

int main(){

const int i = 12;int* const ip = &i;std::cout << i << ” ” << ++*ip;return 0;

}

• Kimenet: const08.cpp:6: error: invalid conversion from ’const int*’ to ’int*’

107

Page 108: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 109: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansokról

class Date{

...}const Date mybirthday = ...;mybirthday = ...mybirthday.f();

109

Page 110: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 111: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansokrólclass 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

Page 112: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények bevezetése

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

Page 113: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 ( parameter1, parameter2, ...) { statements }

Page 114: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

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

Page 115: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

• Definíció:– A teljes specifikáció!type name ( parameter1 [paramname], parameter2, ...)

• Szignatúra:– Visszatérési érték típusát nem tartalmazza– Paraméterneveket szintén nemname ( parameter1, parameter2, ...)

Page 116: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 117: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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;

}

Page 118: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 119: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

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

Page 120: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

• Paraméterátadás: érték szerint

int sum(int a, int b){

return a + b;}int main(){

std::cout << sum(12, 34) << std::endl;}

Page 121: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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ásastd::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: 1111|10

Page 122: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

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

Page 123: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

}

Page 124: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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’

Page 125: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 oldalona * b = 42; // error, rvalue bal oldalon

Page 126: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

}

Page 127: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 128: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

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

Page 129: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

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

Page 130: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

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

Page 131: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

• return:– visszatérés

• void esetén:– return; vezérlés megszakítása– return 10; hiba! void nem int!

Page 132: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

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

std::cout << ”Hello”;}

Page 133: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

int f() {}int main(){

int i = f();std::cout << i; // kimenet: 1

}

Page 134: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

int f() {

return;}int main(){

int i = f();std::cout << i;

}error: return-statement with no value,...

Page 135: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 136: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

int f1() { } // hiba: nincs visszatérési érték, ettől még lehet jóvoid f2() { } // rendben

int f3() { return 1; } // rendbenvoid f4() { return 1; } // hiba: visszatérési érték void függvényben

int f5() { return; } // hiba: visszatérési érték hiányzikvoid f6() { return; } // rendben

Page 137: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények

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

Page 138: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvényekint f(){

return ’c’;}

int main(){

std::cout << f() << std::endl; // 99return 0;

}

Page 139: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvényekint f(){

int i = a + b;}

int main(){

std::cout << f(10, 12); // 22return 0;

}

Page 140: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvényekint f(){

int i = a + b;int k;

}

int main(){

std::cout << f(10, 12); // 22return 0;

}

Page 141: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvényekint f(){

int i = a + b;int k;10 + 8;

}

int main(){

std::cout << f(10, 12); // 22return 0;

}

Page 142: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvényekint f(){

int i = a + b;int k;10 + 8;i = b + 100;

}

int main(){

std::cout << f(10, 12); // 112return 0;

}

Page 143: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvényekint f(){

int i = a + b;int k;10 + 8;i = b + 100;i = a + 1;

}

int main(){

std::cout << f(10, 12); // 11return 0;

}

Page 144: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvényekint 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); // 1234520896return 0;

}

Page 145: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvényekint 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); // 29return 0;

}

Page 146: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Függvények bevezetése• Túlterhelés:

– Később!

Page 147: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 148: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok (függvény visszatérési értéke)

#include <iostream>

char* f(){

return ”szoveg”;}int main(){

f()[0] = ’b’;}•

Segmentation fault

148

Page 149: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok (függvény visszatérési értéke)

#include <iostream>

const char* f(){

return ”szoveg”;}int main(){

f()[0] = ’b’;}• Kimenet:

fconst01.cpp:10: error: assignment of read-only location ’* f()’

149

Page 150: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok (függvény visszatérési értéke)

#include <iostream>

int* f(){

int i = 12;const int* ip = &i;return ip;

}• Kimenet:

fconst01.cpp:7: error: invalid conversion from ’const int*’ to ’int*’

150

Page 151: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 152: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok

• Kicsit előre ugrunk!• User-defined type

void f( myType &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 myType &my ); 152

Page 153: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok

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

void f();int i;

}

153

Page 154: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 155: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Konstansok

class Clazz{

void f() const;int i;

}• Kimenet:

increment of data-member ’Clazz::i’ in read-only structure

155

Page 156: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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 Method3( const int* const& ) const;

156

Page 157: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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!

Page 158: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzésfahr2cels v1 (C):

#include <stdio.h>

// a program fahrenheit és ahhoz megfelelő celsius értékeket ír kiint main() {

int fahr; for (fahr = -100 ; fahr <= 300; fahr += 10) {

printf("fahr = %d\t cels =%d\n", fahr, 5/9 * (fahr - 32));

}return 0;

}

Kimenet:F = 0 C = 0F = 40 C = 0...

Page 159: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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

Page 160: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzésfahr2cels v2 (C):

#include <stdio.h>// a program fahrenheit és ahhoz megfelelő celsius értékeket ír kiint main() {

int fahr; for (fahr = -100; fahr <= 300; fahr += 10) {printf("fahr = %d\t cels =%d\n", fahr, 5./9 * (fahr - 32)); }return 0;

}

Kimenet:fahr2cels2.c: In function ‘main’:fahr2cels2.c:13: warning: format ‘%d’ expects type ‘int’, but

argument 4 has type ‘double’

Page 161: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzés

• A kód ugyan lefordul, de a warning mindig rossz ómen!

• float / int => float

Page 162: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzésfahr2cels v3 (C):

#include <stdio.h>// a program fahrenheit és ahhoz megfelelő celsius értékeket ír kiint main() {

int fahr; for (fahr = -100; fahr <= 300; fahr += 10) {printf("fahr = %d\t cels =%f\n", fahr, 5./9 * (fahr - 32)); }return 0;

}

Kimenet:F = 0 C = -17.777778F = 40 C = 4.444444...

Page 163: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzésfahr2cels v4 (C):

#include <stdio.h>#define LOWER -100#define UPPER 300#define STEP 10// a program fahrenheit és ahhoz megfelelő celsius értékeket ír kiint main() {

int fahr; for (fahr = LOWER; fahr <= UPPER; fahr += STEP) {printf("fahr = %d\t cels =%f\n", fahr, 5./9 * (fahr - 32)); }return 0;

}

Kimenet:F = 0 C = -17.777778F = 40 C = 4.444444...

Page 164: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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!

Page 165: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzésfahr2cels v5 (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!

}

Page 166: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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!

Page 167: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzésfahr2cels v6 (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;

}

Page 168: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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!

Page 169: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzésfahr2cels v7 (C++):

#include <iostream> using namespace std;

inline double fahr2cels( 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 = " <<

fahr2cels(fahr) << endl; } return 0;

}

Page 170: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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)

Page 171: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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!

Page 172: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzéscat (C):

#include <stdio.h> int main() {

int ch; while ( (ch = getchar()) != EOF) {

putchar(ch); } return 0;

} Kimenet:asdf asd fasd fasasdf asd fasd fas

Page 173: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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;

}

Page 174: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzéscat (C++):

#include <iostream> using namespace std;

int main() {

char ch; // fontos, defaultból tetsz. karakterwhile ( cin >> ch ) {

cout << ch; } return 0;

} Kimenet:

asdf asd fasd fasasdfasdfasdfas

Page 175: Programozási Nyelvek (C++) Gyakorlat Gyak 02

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;

}

Page 176: Programozási Nyelvek (C++) Gyakorlat Gyak 02

Kódelemzéscat (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 fasasdf asd fasd fas