1.76k likes | 1.96k Views
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
E N D
Programozási Nyelvek (C++) GyakorlatGyak 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 • 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
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!
Erősen típusos nyelv (Ada) procedureStrong_Typingis Alpha : Integer := 1 ; Beta : Integer := 10 ; Result : Float; begin Result := Float ( Alpha ) / Float ( Beta ) ; -- 0.1 endStrong;
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++) voidweakTyping ( void ) { intalpha = 1 ; intbeta = 10 ; floatresult; result = alpha / beta; // 0 }
Gyengén típusos nyelv (Java) voidweakTyping() { intalpha = 1 ; intbeta = 10 ; floatresult; result = alpha / beta; // 0 }
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 • 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)Modifiers: short, long, signed, unsigned • int: • shortint: -32,768 -> +32,767 (16 bit) • unsignedshortint: 0 -> +65,535 (16 bit) • unsignedint: 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: • signedchar : -128 -> +127 • unsignedchar: 0 -> +255 • float: 32 bit • double: • double: 96 bit • longdouble : 64 bit
Erőssen(?) típusos nyelv (Na, mégegyszer) • Házi feladat: Hogy is van ez? #include <stdio.h> int main() { shorts = 10; shortintsi = 1; printf ("s : %f\t, si : %f\n", sizeof(s), sizeof(si)); }
Típusos nyelv #include<stdio.h> int main() { short s = 10; shortintsi = 1; printf("s : %d\t, si : %d\n", sizeof(s), sizeof(si)); }
Erőssen (?) típusos nyelv • Házi feladat: Hogy is van ez? #include <stdio.h> int main() { short s = 10; shortintsi = 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!
C++ típusrendszere • C++-ben a leggyakoribb alaptípusok: • Egészszámoktípusa: int, short int, long int • Lebegopontos számok típusa: float, double, longdouble • 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 • 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; return0; } error: declaration of ‘auto i’ has no initializer
Statikus típusrendszer (C++-ben) int main() { auto i; i = 12; return0; } error: declaration of ‘auto i’ has no initializer
Statikus típusrendszer (C++-ben) int main() { auto i = 12; return0; }
Statikus típusrendszer (C++-ben) #include<iostream> #include<typeinfo> int main() { auto i = 12; std::cout << typeid(i).name(); // i return0; }
Statikus típusrendszer (C++-ben) #include<iostream> #include<typeinfo> classClazz; int main() { auto i = newClazz(); std::cout << typeid(i).name(); return0; } error: unabletodeduce ’auto’ from ’<expressionerror>’
Statikus típusrendszer (C++-ben) #include<iostream> #include<typeinfo> classClazz{ }; intmain() { auto i = newClazz(); std::cout << typeid(i).name(); // PlClazz return0; }
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; return0; }
Statikus típusrendszer (C++-ben) #include<iostream> #include<typeinfo> int main() { int i = 12; decltype(i) j = ’c’; std::cout << typeid(j).name(); // i return0; }
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)
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ó.
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 • C-ben: #include<stdio.h> int main() { int i, j, k = 0; printf("%d| %d| %d", i, j, k); return0; }
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?!?!
Deklaráció és értékadás • C-ben: #include<stdio.h> int main() { inti = j = k = 0; printf("%d| %d| %d", i, j, k); return0; }
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?
Deklaráció és értékadás • C-ben: #include<stdio.h> int main() { inti, j, k; i = j = k = 0; printf("%d| %d| %d", i, j, k); return0; }
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?
Deklaráció és értékadás • Hogy megy ez C++-ben? #include<iostream> int main() { inti, 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! withada.text_io; proceduredek01inada is i, j, k : integer := 0; begin ada.text_io.put_line( Integer'Image(i) &Integer'Image(j) &Integer'Image(k)); end dek01inada;
Deklaráció és értékadás • Az output: $ gnatmake dek01inada.adb … $ ./dek01inada 0 00 • Siker! Adában meg lehet csinálni!
Üres utasítás • A jó öreg skip! • ; int main() { ;;; // három üres utasítás return0; }
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 elseif. Ez is opcionális. • elseif után jöhet több elseif. • elseif után jöhet a végén else, opcionálisan.
Vezérlési szerkezetek • Elágazás (C): #include<stdio.h> intmain() { inti = 10; if ( i < 15 ) // log kif! { // ... } return0; }
Vezérlési szerkezetek • Elágazás (C): #include<stdio.h> intmain() { inti = 10; if ( i < 15 ) // log kif! { // ... } else { // ... } return0; }
Vezérlési szerkezetek • Elágazás (C): #include<stdio.h> intmain() { inti = 10; if ( i < 15 ) // log kif! { // ... } elseif( i > -1 ) { // … }else { // ... } return0; }
Vezérlési szerkezetek • Elágazás(C++): #include<iostream> intmain() { boolb= true; if ( b ) // log kif! { // ... } }
Vezérlési szerkezetek • Elágazás(C++): #include<iostream> intmain() { boolb= 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, akkor az megfelel az igaz kiértékelésnek. • float, int, double, short, … #include<stdio.h> intmain() { inti= 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, akkor az megfelel a hamis kiértékelésnek. #include<stdio.h> intmain() { inti= 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 NULL egy object, akkor false. #include<iostream> intmain() { Kutya k = newKutya(); // 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 NULL egy object, akkor false. #include<iostream> intmain() { Kutya k = NULL; // Később megnézzük, mi ez a Kutya! if(k ) // nem log kif, de jó! { // ... }// else … }