Repetitorium Programmieren I + II Stephan Gimbel Johanna Mensik Michael Roth 6. März 2012
Agenda 1 Operatoren 2 Datentypen Gleitpunkt Zahl Typkonvertierung 3 Strommanipulatoren 4 Bedingungen if-else switch-case 5 Schleifen for-schleifen while-schleife do-while-schleife 6 Funktionen 7 Klassen
Operatoren Rang Operatoren 1 :: 2. -> [] () sizeof 3! + - ++ - - & (Adresse) *(Zeiger) new delete 4 * / % 5 + - 6 << >> 7 < > <= >= 8 ==!= 9 &(bitweises UND) 10 ˆ 11 12 && 13 14?: 15 Zuweisungen, wie = += 16,
Operatoren Unäre arithmetische Operatoren Nur für Ganzzahl-Datentypen definiert. Es gibt zwei Arten: die vorlaufende oder die nachlaufende Inkrementierung / Dekrementierung. Anwendung i n t a ; a++; ++a ;
Operatoren Binäre arithmetische Operatoren Diese Art der Operatoren wird erzeugt durch die Zeichen + - / * und % (=Modulo). Anwendung i n t a = 1, b =2; a = a + b ; a = a b ; ist äquivalent zu: Anwendung i n t a = 1, b =2; a += b ; a = b ;
Operatoren Ternärer Operator Einziger Operator, der drei Operanden hat:? : Operand1? Operand2 : Operand3 Anwendung i n t a, b = 1, c = 2 ; a = ( b < c )? 42 : 2 3 ; ist äquivalent zu: Anwendung i n t a, b = 1, c = 2 ; i f ( b < c ) a = 4 2 ; e l s e a = 2 3 ;
Operatoren Logische Operatoren Sie geben immer einen Wahrheitswert true = 1 oder false = 0 zurück. Sie können anschließend im Datentyp bool gespeichert werden. Ausrücke die mittels Vergleichsoperatoren erstellt wurden können mit Logische Verknüpfungen verbunden werden. Operator Name < kleiner > größer <= kleiner gleich >= größer gleich == gleich!= ungleich Logische Verknüpfung Name && und oder! nicht
Operatoren Logische Operatoren Sehr häufiger Fehler i n t a = 2 ; i n t b = 5 0 0 ; i f ( a=b ) cout << Wahr << e n d l ; e l s e cout << F a l s c h << e n d l ; Zuweisungsoperator (=) statt Vergleichsoperator (==)
Datentypen Datentyp Datenbereich Art short 32.768 32.767 int 2.147.483.648 2.147.483.647 Ganze Zahl long 9 10 18 9 10 18 float 3.4 10 38 3.4 10 38 double 1.7 10 308 1.7 10 308 Gleitpunkt Zahl long double 3.4 10 4932 3.4 10 4932 bool true (1), false(0) Wahrheitswert char a, A,... (ASCII-Zeichen) Zeichen Anwendung <Datentyp> <Variablenamen> [ = <Zuweisungswert> ]
Datentypen Die Größe des Datentyps kann Plattformabhängig sein (32/64 Bit) Ermitteln der Größe cout << s i z e o f ( i n t ) ; Ermitteln des Datenbereichs #i n c l u d e < l i m i t s. h>... cout << n u m e r i c l i m i t s <i n t >:: min ( ) << e n d l ; cout << n u m e r i c l i m i t s <i n t >:: max ( ) << e n d l ;
Gleitpunkt Zahl Datentyp Datenbereich Genauigkeit float 3.4 10 38 3.4 10 38 6 Stellen double 1.7 10 308 1.7 10 308 15 Stellen long double 3.4 10 4932 3.4 10 4932 19 Stellen Aber f l o a t x ; x = 1 / 2 ; // E r g e b n i s s 0
Typkonvertierung double x = 5 / 3 ; // i m p l i z i t e Typumwandelung cout << x << e n d l ; i n t i = 2 0 ; x = ( double ) i ; // e x p l i z i t e Typumwandelung cout << x << e n d l ; implizite Typumwandelung Anwendung geschieht automatisch durch den Compiler. explizite Typumwandelung Anwendung <Datentyp> (< V a r i a b l e >) (<Datentyp >) <V a r i a b l e > s t a t i c c a s t < <Datentyp> > (< V a r i a b l e >) // empfohlen
Typkonvertierung const cast () - Casting the const away... c o n s t i n t x = 1 0 ; c o n s t i n t xp = &x ; xp = 0 ; // geht n i c h t aber... c o n s t i n t x = 1 0 ; i n t xp = c o n s t c a s t <i n t >(&x ) ; xp = 0 ; // ä n d e r t den Wert von x!!!
Typkonvertierung reinterpret cast () i n t i = 2 5 ; f l o a t f p = r e i n t e r p r e t c a s t <f l o a t >( i ) ; // f p z e i g t a u f f l o a t Datentyp an A d r e s s e 25 oder i n t a = new i n t ( ) ; v o i d b = r e i n t e r p r e t c a s t <v o i d >(a ) ; i n t c = r e i n t e r p r e t c a s t <i n t >(b ) ; // a und c g l e i c h, b w a h r s c h e i n l i c h g l e i c h
Typkonvertierung dynamic cast () B a s i s K l a s s e pb ; A b g e l e i t e t e K l a s s e pa= dynamic cast <A b g e l e i t e t e K l a s s e >(pb) ; Downcasting zur Laufzeit Typ muss noch nicht feststehen
Typkonvertierung static cast () enum dayofweek sunday, monday, tuesday, wednesday, t h u r s d a y, f r i d a y, s a t u r d a y today = monday ; i n t i = monday ; // i m p l i z i t today = i ; // geht n i c h t today = s t a t i c c a s t <dayofweek>( i ) ; // geht!
Strommanipulatoren
Strommanipulatoren ab hier die Bibliothek #include <iomanip>
Strommanipulatoren
Kontrollstrukturen (Selection Structure / Bedingungen) Anwendung: if-else i f ( V a r i a b l e > 10) cout<< V a r i a b l e hat e i n e n Wert g r ö ß e r a l s 1 0. << e n d l ; e l s e cout<< V a r i a b l e hat e i n e n Wert k l e i n e r g l e i c h 1 0. << e n d l ;
Kontrollstrukturen (Selection Structure / Bedingungen) Anwendung: if-else i f ( V a r i a b l e > 50) cout<< V a r i a b l e hat e i n e n Wert g r ö ß e r 5 0. << e n d l ; e l s e i f ( V a r i a b l e > 40) cout<< V a r i a b l e hat e i n e n Wert g r ö ß e r 4 0. << e n d l ; e l s e i f ( V a r i a b l e > 30) cout<< V a r i a b l e hat e i n e n Wert g r ö ß e r 3 0. << e n d l ; e l s e i f ( V a r i a b l e > 20) cout<< V a r i a b l e hat e i n e n Wert g r ö ß e r 2 0. << e n d l ; e l s e cout<< V a r i a b l e hat e i n e n Wert k l e i n e r g l e i c h 2 0. << e n d l ;
Kontrollstrukturen (Selection Structure / Bedingungen) Anwendung: if-else i f ( V a r i a b l e == 50) cout<< V a r i a b l e hat den Wert 5 0. << e n d l ; e l s e i f ( V a r i a b l e == 40) cout<< V a r i a b l e hat den Wert 4 0. << e n d l ; e l s e i f ( V a r i a b l e == 30) cout<< V a r i a b l e hat den Wert 3 0. << e n d l ; e l s e i f ( V a r i a b l e == 20) cout<< V a r i a b l e hat den Wert 2 0. << e n d l ; e l s e cout<< V a r i a b l e hat e i n e n anderen Wert << e n d l ;
Kontrollstrukturen (Selection Structure / Bedingungen) Anwendung: switch-case s w i t c h ( V a r i a b l e ) case 1 0 : cout<< V a r i a b l e hat den Wert 1 0. << e n d l ; break ; case 2 0 : cout<< V a r i a b l e hat den Wert 2 0. << e n d l ; break ; case 3 0 : cout<< V a r i a b l e hat den Wert 3 0. << e n d l ; break ; case 4 0 : cout<< V a r i a b l e hat den Wert 4 0. << e n d l ; break ; d e f a u l t : cout<< Es wurde e i n e f a l s c h e Zahl e i n g e g e b e n. << e n d l ;
Kontrollstrukturen (Repedition Structure / Schleifen) = Zum wiederholen eines Vorgangs Drei Parameter: Initialisierung; Wiederholungsbedingung; was passiert nach jedem Durchlauf Anwendung: for-schleife f o r ( i n t i =0; i < 1 0 ; i ++) cout << i << e n d l ; Anwendung: for-schleife (Sonderfall) i n t i, sum ; f o r ( i =1, sum=0; i <=10; sum+=i, i ++) ; Achtung!!! Beim Sonderfall sind die Teilparameter mit Komma getrennt!
Kontrollstrukturen (Repedition Structure / Schleifen) Anwendung: while-schleife I i= 0 ; w h i l e ( i < 10) cout << i << e n d l ; i ++; Anwendung: while-schleife II i= 1 1 ; w h i l e ( i < 10) cout << i << e n d l ; i ++;
Kontrollstrukturen (Repedition Structure / Schleifen) Anwendung: do-while-schleife I i n t x = 0 ; do cout << x << e n d l ; x++; w h i l e ( x < 10) Anwendung: do-while-schleife II i n t x = 1 1 ; do cout << x << e n d l ; x++; w h i l e ( x < 10)
Kontrollstrukturen (Repedition Structure / Schleifen) Anwendung: Verlassen von Schleifen i n t i = 0 ; w h i l e ( t r u e ) cout << i << e n d l ; i f ( i ==42) break ; i ++; // Ausgabe? cout << S c h l e i f e v e r l a s s e n << e n d l ; Anwendung: Springen in Schleifen i n t i = 0 ; w h i l e ( t r u e ) cout << i << e n d l ; i f ( i ==42) c o n t i n u e ; i ++; // Ausgabe?
Funktionen Aufbau der Funktion Anwendung i n t summe ( i n t a, i n t b )... r e t u r n a ; Datentyp : erwarteter Rückgabewert (z.b. int = Ganzzahl, void = nix) Funktionsname: damit wird im Programm die Funktion aufgerufen Parameter in (): werden in der Funktion verwendet
Funktionen Anwendung i n t summe ( i n t a, i n t b ) i n t c ; c=a+b ; r e t u r n ( c ) ; i n t main ( )... cout << summe ( 2 5, 1 0 ) ; // A u f r u f d e r F u n k t i o n...
Funktionen Call By Value i n t main ( ) i n t a = 10, b = 20 cout << summe( a, b ) ; // A u f r u f d e r F u n k t i o n... // a und b s i n d u n v e r ä n d e r t i n t summe( i n t x, i n t y ) // Beginn d e r F u n k t i o n x++; y++; r e t u r n x+y ; Es werden Kopien der Übergabeparameter angefertigt. Somit wird sichergestellt das die Variablen der aufrufenden Funktion nicht verändert werden können.
Funktionen Call By Reference v o i d swap ( i n t &a, i n t &b ) i n t tmp=a ; a=b ; b=tmp ; ; Die übergeben Variablen werden direkt übergeben. Es ist nicht möglich Konstanten als Parameter anzugeben (z.b. swap(1, 2);)
Funktionen Call By Reference i n t main ( ) i n t a = 10, b = 20 cout << summe( a, b ) ; // A u f r u f d e r F u n k t i o n... // a und b s i n d v e r ä n d e r t!!! i n t summe( i n t &x, i n t &y ) // Beginn d e r F u n k t i o n x++; y++; r e t u r n x+y ; Achtung!!! Variablen die als Referenz übergeben werden, werden verändert!!!
Funktionen Call By Reference (ohne Veränderung) i n t main ( ) i n t a = 10, b = 20 cout << summe( a, b ) ; // A u f r u f d e r F u n k t i o n i n t summe( c o n s t i n t &x, c o n s t i n t &y ) // Beginn d e r F u n k t i o n x++; // C o m p i l e r f e h l e r y++; // C o m p i l e r f e h l e r r e t u r n x+y ;
Funktionen Inline Funktionen i n l i n e i n t summe( i n t x, i n t y ) r e t u r n x+y ; i n t main ( ) cout << summe ( 4 2, 23) << e n d l ; Compiler ersetzt Inline Funktionen an passender Stelle. Dies kann u.u. schneller sein als der Funktionsaufruf inkl. Parameterübergabe.
Funktionen Funktionen mit statischen Variablen i n t s t a t i c F u n c t i o n ( i n t x ) s t a t i c i n t a = 5 ; r e t u r n a++ + x ; i n t main ( ) cout << s t a t i c F u n c t i o n ( 1 ) << e n d l ; // Ausgabe : 6 cout << s t a t i c F u n c t i o n ( 1 ) << e n d l ; // Ausgabe :? cout << s t a t i c F u n c t i o n ( 1 ) << e n d l ; // Ausgabe :? Statische Variablen haben einen festen Platz im Speicher und werden nur beim ersten Aufruf initialisiert. Falls kein Wert angegeben ist, erfolgt die Initialisierung mit 0. Achtung!!! Nicht verwechseln mit static in Dateien! (s. Klassen)
Funktionen Function Pointer - Pointer auf Funktionen Function Pointer // F u n c t i o n P o i n t e r a l s Parameter v o i d p r i n t ( s t r i n g a, s t r i n g b, s t r i n g ( f u n c ) ( s t r i n g, s t r i n g ) ) // A u f r u f d e r übergebenen F u n k t i o n cout << ( f u n c ) ( a, b ) << e n d l ; // A u f r u f d e r übergebenen F u n k t i o n Diese print-funktion bekommt einen Function Pointer auf eine andere Funktion (Platzhaltername func) übergeben, die zwei Strings als Parameter erhält und einen String zurückliefert.
Funktionen Function Pointer s t r i n g f u n k t i o n 1 ( s t r i n g e i n s, s t r i n g z w e i ) r e t u r n e i n s + + z w e i ; s t r i n g f u n k t i o n 2 ( s t r i n g e i n s, s t r i n g z w e i ) r e t u r n z w e i + + e i n s ; Diese Funktionen erfüllen die Voraussetzungen, um von der gezeigten print-funktion genutzt zu werden.
Funktionen Function Pointer - Anwendung i n t main ( ) s t r i n g wort1 = H a l l o, wort2 = Welt ; // A d r e s s e d e r gewünschten F u n k t i o n d i r e k t übergeben... p r i n t ( wort1, wort2, &f u n k t i o n 1 ) ; // Ausgabe : H a l l o Welt p r i n t ( wort1, wort2, &f u n k t i o n 2 ) ; // Ausgabe : Welt H a l l o //... o d e r w i e d e r e i n e n F u n c t i o n P o i n t e r e r s t e l l e n. s t r i n g ( f u n c t i o n P t r ) ( s t r i n g, s t r i n g ) = &f u n k t i o n 1 ; p r i n t ( wort1, wort2, f u n c t i o n P t r ) ; // Ausgabe : H a l l o Welt f u n c t i o n P t r = &f u n k t i o n 2 ; p r i n t ( wort1, wort2, f u n c t i o n P t r ) ; // Ausgabe : Welt H a l l o
Funktionen Achtung!!! Function Pointer können nur dann wie beschrieben verwendet werden, wenn die Funktion, auf die der Pointer zeigt, keine Methode einer Klasse oder statische Methode einer Klasse ist. Wenn die verwendeten Funktionen nicht-statische Methoden einer Klasse sind, muss angegeben werden, zu welcher Klasse und welchem Objekt die Methode gehört.
Funktionen Function Pointer bei nicht-statischen Methoden c l a s s K l a s s e p u b l i c : s t r i n g f u n k t i o n 1 ( s t r i n g e i n s, s t r i n g z w e i )... s t r i n g f u n k t i o n 1 ( s t r i n g e i n s, s t r i n g z w e i )... // Angabe des Klassennamens b e i d e r D e f i n i t i o n des FuncPtr v o i d p r i n t ( s t r i n g a, s t r i n g b, s t r i n g ( K l a s s e : : f u n c ) ( s t r i n g, s t r i n g ) ) cout << ( t h i s > f u n c ) ( a, b ) << e n d l ; // Methode des j e w e i l i g e n O b j e k t s verwenden ; i n t main ( ) K l a s s e neu ; s t r i n g wort1 = H a l l o, wort2 = Welt ; // Angabe des Klassennamen f ü r d i e F u n c t i o n P o i n t e r neu. p r i n t ( wort1, wort2,& K l a s s e : : f u n k t i o n 1 ) ; // H a l l o Welt s t r i n g ( K l a s s e : : f P t r ) ( s t r i n g, s t r i n g ) = &K l a s s e : : f u n k t i o n 2 ; neu. p r i n t ( wort1, wort2, f P t r ) ; // Welt H a l l o
Klasse EineKlasse.h c l a s s E i n e K l a s s e p u b l i c : E i n e K l a s s e ( ) ; // d e r D e f a u l t K o n s t r u k t o r E i n e K l a s s e ( i n t ) ; // w e i t e r e r K o n s t r u k t o r mit Parameter E i n e K l a s s e ( E i n e K l a s s e& a ) ; // Copy K o n s t r u k t o r E i n e K l a s s e ( ) ; // d e r D e s t r u k t o r ; i n t einemethode ( i n t ) ; i n t nocheinemethode ( i n t x=42) ; // Methode mit ( D e f a u l t ) // Parameter p r i v a t e : i n t m e i n A t t r i b u t ;
Klasse EineKlasse.cpp #i n c l u d e E i n e K l a s s e. h E i n e K l a s s e : : E i n e K l a s s e ( ) E i n e K l a s s e : : E i n e K l a s s e ( i n t param ) m e i n A t t r i b u t = param ; E i n e K l a s s e : : E i n e K l a s s e ( ) i n t E i n e K l a s s e : : einemethode ( i n t x ) //.. do something i n t E i n e K l a s s e : : nocheinemethode ( i n t x ) //.. do something
Klasse - Initialisierungsliste EineKlasse.h #i f n d e f EINEKLASSE H #d e f i n e EINEKLASSE H c l a s s E i n e K l a s s e p u b l i c : E i n e K l a s s e ( i n t einx =0, i n t einy =0) : x ( einx ), y ( einy ) // some code p r i v a t e : i n t x, y ; ; #e n d i f Main.cpp #i n c l u d e E i n e K l a s s e. h i n t main ( ) E i n e K l a s s e meinobjekt ; E i n e K l a s s e meinobjekt1 ( 2 3, 42) ;
Klasse - statische Members EineKlasse.h c l a s s E i n e K l a s s e p u b l i c : E i n e K l a s s e ( i n t ) ; E i n e K l a s s e ( ) ; s t a t i c i n t count ; p r i v a t e : i n t member ; ; EineKlasse.cpp i n t E i n e K l a s s e : : count = 0 ; E i n e K l a s s e : : E i n e K l a s s e ( i n t x = 0) member = x ; E i n e K l a s s e : : count++; E i n e K l a s s e : : E i n e K l a s s e ( ) E i n e K l a s s e : : count ;
Klasse - statische Members Main.cpp - Zugriff auf public static Members #i n c l u d e E i n e K l a s s e. h i n t main ( ) cout << E i n e K l a s s e : : count << e n d l ; // Ausgabe : 0 E i n e K l a s s e meinobjekt1 ; E i n e K l a s s e meinobjekt2 ; cout << E i n e K l a s s e : : count << e n d l ; // Ausgabe : 2 r e t u r n 0 ; Achtung!!! Klappt aber nur für public Members, nicht für private!
Klasse - statische Methoden EineKlasse.h - private static Members c l a s s E i n e K l a s s e p u b l i c : s t a t i c i n t getcount ( ) ;... p r i v a t e : i n t member ; s t a t i c i n t count ; ; Main.cpp i n t main ( ) cout << E i n e K l a s s e : : getcount ( ) << e n d l ; // Ausgabe : 0 E i n e K l a s s e meinobjekt ; cout << E i n e K l a s s e : : getcount ( ) << e n d l ; // Ausgabe : 1
Klasse - statische Methoden EineKlasse.h - private static Members c l a s s E i n e K l a s s e p u b l i c : s t a t i c i n t getcount ( ) ;... p r i v a t e : i n t member ; s t a t i c i n t count ; ; EineKlasse.cpp... i n t E i n e K l a s s e : : getcount ( ) member = 4 2 ; // C o m p i l e r f e h l e r r e t u r n E i n e K l a s s e : : count ;...
Klasse - Mehrfacheinbindung (#include guard) EineKlasse.h #i f n d e f EINEKLASSE H #d e f i n e EINEKLASSE H c l a s s E i n e K l a s s e p u b l i c : ;... #e n d i f EineKlasse.h - Alternative #pragma once // non s t a n d a r d