Programmierkurs C++ - ZAIK
Transcription
Programmierkurs C++ - ZAIK
Zentrum für Angewandte Informatik Köln Arbeitsgruppe Faigle / Schrader Universität zu Köln Lösungen zum Übungsblatt 4 Programmierkurs C++ Nils Eissfeldt und Jürgen Gräfe 09. November 2001 Da die Beispiel–Listings der Übung etwas umfangreicher sind, als bisher, finden sich diese am Ende der Lösung. Alle Listings finden sich auch zum Ausprobieren wie gewohnt im WWW unter http://www.zaik.uni-koeln.de/AFS/teachings/ws0102/ProgKurs/ . Aufgabe 9 (Tag des Jahres) Teil a: Z. 8-11 Zur Lösung der Aufgabe ist es sinnvoll, sich ein Feld mit den Tagen jedes Monats zu definieren und zwar einmal für ein normales Jahr (Februar = 28 Tage) und für ein Schaltjahr. Dadurch kann die Berechnung für beide Fälle in einem codiert werden. Da üblicherweise der Januar der 1. Monat ist, wird für den Index 0 ein „nichtvorhandener “Monat eingefügt, so daß man nicht mehr bei den Indizes des Feldes überlegen muß. Z. 13ff. In der Funktion werden die Tage der vorangegangenen Monate zum Tag des Monats addiert. main() Bis auf die Überprüfung, ob ein gültiges Datum eingegeben wurde, enthält das Hauptprogramm neben der Ein- und Ausgabe nur den Aufruf der Funktion zur Berechnung des Tages im Monat. Teil b: Z. 2ff. Rückgabe, ob Schaltjahr oder nicht. 1 void datum_des_tages(...) Die Funktion gibt keinen Wert zurück, deshalb void. Übergeben werden die Zeiger auf tag und monat (Call by Reference). Indem man über die Dereferenzierung *tag bzw. *monat das Ergebnis der Berechnung zuweist, wird dieses an die Speicherstelle geschrieben, unter der die beiden Variablen (definiert im Hauptprogramm) liegen. Deshalb ist es dann auch im Hauptprogramm verfügbar. Aufgabe 10 (Buchstaben zählen) Angelegt wird ein Feld von char, in dem die Buchstaben gezählt werden (Z. 37). In der Eingabe wird zuächst überprüft, ob es sich um Buchstaben handelt. Wenn ja, wird das entsprechende Feld des Buchstaben um einen Zähler hochgezählt. Dabei macht man sich zu Nutze, daß man mit char ganz normal rechnen kann, da es sich um einen Ganzzahltyp handelt. Die Interpretation als Buchstabe findet nur bei der Übergabe von der Tastatur bzw. zum Bildschirm über die ASCII– Tabelle statt. So gibt char c = ’d’; char index = c - ’a’; // index ist gleich 3 Das eingebundene File iomanip (Z. 5) dient zur Formatierung der Ausgabe in Z. 20. setw(9) sorgt dafür, daß die nachfolgende Ausgabe der Zahl vom Typ double 9 Zeichen lang ist. Aufgabe 11∗ (Determinante einer 3 × 3 Matrix) Das Einlesen der Matrix geschieht analog zum Vorgehen in der Vorlesung (Z. 40ff.). Zur Berechnung der Determinante müssen die Determinanten von 2×2 Matrizen berechnet werden. Dies geschieht in der Funktion int det_2x2(...) in Z.8 ff.. Der übergebene Parameter ist ein Zeiger auf einen Zeiger, da im Hauptprogramm die Untermatrix dynamisch allokiert wurde (s. Definition der Matrix m2x2 in Z. 66). Das Vorgehen hierzu ist ganz analog zur Vorlesung. Um die drei notwendigen Streichungsmatrizen zu erzeugen (Entwickeln nach der ersten Zeile) läuft die äußere Schleife über die drei Spalten (Z. 58 –105). Die Zahl der Laufvariablen bei der Initialisierung der 2 × 2 Matrix sollte Sie nicht verwirren. In einer äußeren Schleife (i,j) werden die Elemente der 2. und 3. Zeile sowie der drei Spalten der 3 × 3 Matrix durchlaufen. Beim Initialisieren der Streichungsmatrix ist dann lediglich darauf zu achten, daß der aktuelle Spaltenindex s die gestrichene Spalte der Matrix darstellt (Z. 80), diese Elemente also nicht verwendet werden. In der Schleife über s wird für jede Spalte der entsprechende Koeffizient koeffizient[s] inklusive seinem Vorzeichen bestimmt, sowie der Wert der Determinante der entsprechenden Streichungsmatrix. Diese werden in Z. 118 entsprechend dem angegebenen Entwicklungssatz aufsummiert, um das Ergebnis zu erhalten. Aufgabe 12∗ (Argumente aus der Kommandozeile) In Programmierumgebungen für C/C++ kann man normalerweise Argumente aus der Kommandozeile beim Start an ein Programm übergeben. Mit dem Aufruf von main werden zwei Argu- 2 mente übergeben. Das erste Argument ist die Anzahl der Argumente aus der Kommandozeile, mit der das Programm aufgerufen wurde (argc); das zweite Argument ist ein Zeiger auf ein Feld von Zeigern auf Zeichenketten, die die Argumente enthalten, ein Argument pro Zeichenkette. Compiliert man das angegebenen Beispielprogramm und startet es über $ a.out 1998 42 ist argc = 3 und argv stellt sich wie folgt dar argv: a.out 1998 42 0 Nach Konvention ist argv[0] der Name, mit dem das Programm aufgerufen wurde, also ist argc wenigstens 1. In dem Beispiel sind argv[1] = ”1998” und argv[2] = ”42”. Da es sich um Zeichenketten handelt, müssen diese im Programm in Zahlen umgewandelt werden (atoi(), z.B. Z. 85). Anhand des Argumentes argc läßt sich entscheiden, welche Funktion aufgerufen werden soll. Bei 2 Argumenten, soll das Datum eines Tages im Jahr berechnet, bei 3 Argumenten ein Datum in den Tag des Jahres umgewandelt werden. Ansonsten werden nur Elemente der Programme aus Aufgabe 9 verwendet. 3 Aufgabe 9a: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 / / Der w i e v i e l t e Tag im J a h r i s t d e r / / t t .mm. j j j j ? # include<iostream> u s i n g namespace s t d ; / / 1 3 E i n t r a e g e um I n d e x = Monat v e r w e n d e n zu k o e n n e n i n t tage_im_monat [ 2 ] [ 1 3 ] = { {0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31} }; int tag_des_jahres ( int j , int m, int t , int s ) { int i ; / / A d d i e r e a u f Tag t d i e Z a h l d e r Tage / / v o r h e r g e g a n g e n e r Monate f o r ( i = 1 ; i < m ; i ++){ t + = tage_im_monat [ s ] [ i ] ; } return t ; } i n t main ( ) { i n t t a g , monat , j a h r ; c o u t < < " E i n g a b e : Tag Monat J a h r " < < e n d l ; c i n > > t a g > > monat > > t a g ; / / E i n g a b e n > 0 und monat < = 1 2 ? / / s o n s t Datum u n g u e l t i g i f ( ( tag > 0) && ( j a h r > 0) && ( monat > 0 ) & & ( monat < = 1 2 ) ) { / / Schaltjahr ? int schaltjahr = ( ( j a h r %4 == 0) && ( j a h r % 1 0 0 ! = 0 ) | | ( jahr %400 == 0)); / / Hat d e r Monat ’ t a g ’ Tage ? / / s o n s t Datum u n g u e l t i g i f ( t a g < = t a g e _ i m _ m o n a t [ s c h a l t j a h r ] [ monat ] ) { c o u t < < " Der " < < t a g < < " . " < < monat < < " . " << j a h r < < " i s t der " < < t a g _ d e s _ j a h r e s ( j a h r , monat , t a g , s c h a l t j a h r ) < < " . Tag d e s J a h r e s . " < < e n d l ; return 0 ; } } c o u t < < " Der " < < t a g < < " . " < < monat < < " . " < < j a h r < < " i s t k e i n g u e l t i g e s Datum " << endl ; return 0 ; } 4 Aufgabe 9b: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 //... int schaltjahr ( int j ) { / / Rueckgabe : / / = 0 : kein S c h a l t j a h r / / = 1 : Schaltjahr return ( ( j %4 == 0) && ( j % 1 0 0 ! = 0 ) | | ( j %400 == 0)); } / / B e r e c h n u n g d e s Datums // / / Im P a r a m e t e r k o p f w i r d f u e r t a g und monat j e w e i l s d e r / / Zeiger auf die S p e i c h e r s t e l l e uebergeben , die diese / / V a r i a b l e n d u r c h d i e V e r e i n b a r u n g im main ( ) b e s i t z e n . / / Damit kann i n n e r h a l b d e r F u n k t i o n d a s E r g e b n i s d e r B e r e c h u n g / / d o r t h i n g e s c h r i e b e n werden und i s t im main ( ) a b r u f b a r . / / ( C a l l by R e f e r e n c e , s . KE5 ) // / / void i s t der Bezeichner fuer eine Funktion , die keinen / / Wert z u r u e c k g i b t ! // v o i d d a t u m _ d e s _ t a g e s ( i n t j , i n t t , i n t ∗ t a g , i n t ∗ monat ) { int i ; int s = schaltjahr ( j ); f o r ( i = 1 ; t > t a g e _ i m _ m o n a t [ s ] [ i ] ; i ++){ t −= tage_im_monat [ s ] [ i ] ; } // // // // i i s t j e t z t g l e i c h dem I n d e x d e s Monats , i n dem d e r Tag l i e g t . S c h r e i b e i an den S p e i c h e r p l a t z a u f den d e r Z e i g e r ( i n t ∗ ) monat z e i g t . ∗ monat = i ; / / t i s t j e t z t g l e i c h dem Tag d e s Monats , i n dem / / d e r g e s u c h t e Tag l i e g t . ∗tag = t ; return ; } i n t main ( ) { i n t t a g , monat , j a h r , t ; / / . . . E i n g a b e und U e b e r p r u e f u n g d e r E i n g a b e d a t u m _ d e s _ t a g e s ( j a h r , t , & t a g , & monat ) ; c o u t < < " Der " < < t < < " . Tag d e s J a h r e s " << j a h r < < " i s t der " << t a g < < " . " < < monat < < " . " < < e n d l ; return 0 ; } 5 Aufgabe 10: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 / / Buchstaben zaehlen / / Ausgabe e i n e s H i s t o g r a mm s / / Quelle : Matthias Elf ( Lehrstuhl Juenger ) # include < iostream> # include < iomanip> u s i n g namespace s t d ; void histogramm_buchstaben ( long anzahlBuchstaben [ ] ) { int i , j ; i n t gesamtZahl = 0 ; / / Gesamtzahl der Buchstaben bestimmen f o r ( i = 0 ; i < = 2 5 ; i ++) gesamtZahl += anzahlBuchstaben [ i ] ; f o r ( i = 0 ; i < = 2 5 ; i ++){ / / Anzahl der S t e r n e ( 7 0 S t e r n e = 100%) i n t anzahlSterne = ( 7 0 ∗ anzahlBuchstaben [ i ] ) / gesamtZahl ; c o u t < < char ( 6 5 + i ) < < " ( " < < s e t w ( 9 ) << double ( a n z a h l B u c h s t a b e n [ i ] ) / double ( gesamtZahl ) ∗ 1 0 0 << " ) : " ; / / Ausgabe d e r S t e r n e f o r ( j = 1 ; j < = a n z a h l S t e r n e ; j ++) cout < < "∗" ; cout << endl ; } return ; } i n t main ( ) { char c ; / / F e l d zum Z a e h l e n d e r B u c h s t a b e n long anzahlBuchstaben [ 2 5 ] ; / / Feld auf 0 i n i t i a l i s i e r e n f o r ( i n t i = 0 ; i < = 2 5 ; i ++) anzahlBuchstaben [ i ]=0; / / E i n g a b e b i s EOF l e s e n w h i l e ( c i n >> c ) { / / Falls Grossbuchstabe i f ( ( c >=’A’ ) & & ( c <=’Z ’ ) ) a n z a h l B u c h s t a b e n [ c−’A’ ] + + ; / / Falls Kleinbuchstabe e l s e i f ( ( c >=’ a ’ ) & & ( c <=’ z ’ ) ) a n z a h l B u c h s t a b e n [ c−’a ’ ] + + ; } / / E r g e b n i s a l s Histogramm a u s g e b e n histogramm_buchstaben ( anzahlBuchstaben ) ; return 0 ; } 6 Aufgabe 11: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 / / D e t e r m i n a n t e e i n e r 3 x3 M a t r i x / / Dynamische F e l d e r # include<iostream> # include < iomanip> u s i n g namespace s t d ; / / D e t e r m i n a n t e e i n e r 2 x2 M a t r i x / / Uebergabe e i n e s Z e i g e r s auf e i n e Z e i g e r i n t d e t _ 2 x 2 ( i n t ∗ ∗m) { r e t u r n m[ 0 ] [ 0 ] ∗m[ 1 ] [ 1 ] − m [ 0 ] [ 1 ] ∗ m [ 1 ] [ 0 ] ; } / / B e r e c h e n m hoch i m i t m, n E l e m e n t d e r g a n z e n Z a h l e n / / ( s . Aufgabe 4 ) i n t power ( i n t m , i n t i ) { int ergebnis = 1; while ( i > 0 ) { e r g e b n i s ∗ = m; i −= 1; } return e r g e b n i s ; } i n t main ( ) { int i , j , s ; / / Ein z w e i d i m e n s i o n a l e s Feld / / kann man s i c h v o r s t e l l e n a l s / / Feld aus Feldern i n t m3x3 [ 3 ] [ 3 ] = { } ; int koeffizient [3] = {}; int sdet [3] = {}; / / Zeilenweises e i n l e s e n der Matrix i n t ∗ p = & m3x3 [ 0 ] [ 0 ] ; i = 1; while ( ( cin >> ∗ p ) && ( i < 9 ) ) { i ++; p ++; } / / Ausgabe d e r Aufgabe : cout < < " Determinante der Matrix : " << endl < < endl ; f o r ( i = 0 ; i < 3 ; i ++){ cout << "\ t " ; f o r ( j = 0 ; j < 3 ; j ++) c o u t < < s e t w ( 4 ) < < m3x3 [ i ] [ j ] < < " " ; cout << endl ; } cout << endl ; / / Berechnung der Determinante f o r ( s = 0 ; s < 3 ; s ++){ 7 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 / / M u l t i p l i k a t o r der Streichungsdeterminante k o e f f i z i e n t [ s ] = power (−1, s + 2 ) ∗ m3x3 [ 0 ] [ s ] ; / / Anlegen der S t r e i c h u n g s d e t e r m i n a n t e / / ( s . Vorlesung ) i n t ∗ ∗ m2x2 ; m2x2 = new i n t ∗ [ 2 ] ; f o r ( i = 0 ; i < 2 ; i ++) m2x2 [ i ] = new i n t [ 2 ] ; / / Matrixeintraege i n t a = 0 ; / / Z e i l e n von m2x2 i n t b = 0 ; / / S p a l t e n von m2x2 / / S c h l e i f e u e b e r d i e Z e i l e n 2 und 3 von m3x3 f o r ( i = 1 ; i < 3 ; i ++){ / / S c h l e i f e u e b e r d i e S p a l t e n von m3x3 f o r ( j = 0 ; j < 3 ; j ++){ / / S t r e i c h e S p a l t e s von m3x3 i f ( j ! = s ){ m2x2 [ a ] [ b ] = m3x3 [ i ] [ j ] ; b ++; } } a ++; b =0; } s d e t [ s ] = d e t _ 2 x 2 ( m2x2 ) ; / / Ausgabe d e r S t r e i c h u n g s d e t e r m i n a n t e cout < < " S t r e i c h u n g s d e t e r m i n a n t e " << s +1 << endl < < endl ; f o r ( i = 0 ; i < 2 ; i ++){ cout << "\ t " ; f o r ( j = 0 ; j < 2 ; j ++) c o u t < < s e t w ( 4 ) < < m2x2 [ i ] [ j ] < < " " ; cout << endl ; } c o u t < < " \ t \ t \ t −> " < < s d e t [ s ] < < e n d l < < e n d l ; / / Freigabe der Streichungsdeterminante f o r ( i = 0 ; i < 2 ; i ++) d e l e t e [ ] m2x2 [ i ] ; d e l e t e [ ] m2x2 ; } / / Ausgabe d e s E r g e b n i s s e s int ergebnis = 0; cout << " Determinante = " ; f o r ( i = 0 ; i < 3 ; i ++){ cout < < k o e f f i z i e n t [ i ] < < " ∗ " << s d e t [ i ] ; if ( i == 2) cout << " = " ; else cout << " + " ; / / Berechnung der Determinante ergebnis += koeffizient [ i ] ∗ sdet [ i ]; } cout << ergebnis << endl ; } 8 Aufgabe 12: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 / / K o m b i n a t i o n d e r Programme / / a u s Aufgabe9 . / / Argumente a u s d e r Kommandozeile # include<iostream> # i n c l u d e < s t d l i b . h> u s i n g namespace s t d ; / / L i s t e d e r Tage im Monat i n t tage_im_monat [ 2 ] [ 1 3 ] = { {0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31} }; / / Schaltjahr ? int schaltjahr ( int j ) { / / Rueckgabe : / / = 0 : kein S c h a l t j a h r / / = 1 : Schaltjahr return ( ( j %4 == 0) && ( j % 1 0 0 ! = 0 ) | | ( j %400 == 0)); } / / B e r e c h n e den Tag d e s J a h r e s / / G u e l t i g e s Datum ? bool g u e l t i g e s _ d a t u m ( i n t j , i n t m, i n t t ) { bool g u e l t i g = f a l s e ; i f ( ( t > 0) && ( j > 0) && (m > 0 ) & & (m < = 1 2 ) ) { int s = schaltjahr ( j ); i f ( t < = t a g e _ i m _ m o n a t [ s ] [m] ) g u e l t i g = true ; } return g u e l t i g ; } / / Berechnung int tag_des_jahres ( int j , int m, int t ) { int i ; int s = schaltjahr ( j ); f o r ( i = 1 ; i < m ; i ++){ t + = tage_im_monat [ s ] [ i ] ; } return t ; } / / B e r e c h n e d a s Datum / / G u e l t i g e s Datum ? bool g u e l t i g e s _ d a t u m ( i n t j , i n t t ) { bool g u e l t i g = f a l s e ; i f ( ( j > 0) && t <= (365+ s c h a l t j a h r ( j ) ) ) 9 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 g u e l t i g = true ; return g u e l t i g ; } / / Berechnung v o i d d a t u m _ d e s _ t a g e s ( i n t j , i n t t , i n t ∗ t a g , i n t ∗ monat ) { int i ; int s = schaltjahr ( j ); f o r ( i = 1 ; t > t a g e _ i m _ m o n a t [ s ] [ i ] ; i ++){ t −= tage_im_monat [ s ] [ i ] ; } ∗ monat = i ; ∗tag = t ; return ; } i n t main ( i n t a r g c , char ∗ a r g v [ ] ) { i n t j a h r , monat , t a g ; / / B e r e c h n e d a s Datum i f ( argc == 3){ j a h r = a t o i ( argv [ 1 ] ) ; int t = a t o i ( argv [ 2 ] ) ; i f ( gueltiges_datum ( jahr , t )){ d a t u m _ d e s _ t a g e s ( j a h r , t , & t a g , & monat ) ; c o u t < < " Der " < < t < < " . Tag d e s J a h r e s " << j a h r < < " i s t der " << t a g < < " . " < < monat < < " . " < < e n d l ; } else c o u t < < " U n g u e l t i g e s Datum " < < e n d l ; } / / B e r e c h n e den Tag d e s J a h r e s else i f ( argc == 4){ j a h r = a t o i ( argv [ 1 ] ) ; monat = a t o i ( a r g v [ 2 ] ) ; tag = a t o i ( argv [ 3 ] ) ; i f ( g u e l t i g e s _ d a t u m ( j a h r , monat , t a g ) ) c o u t < < " Der " < < t a g < < " . " < < monat < < " . " < < j a h r < < " war d e r " < < t a g _ d e s _ j a h r e s ( j a h r , monat , t a g ) < < " . Tag d e s J a h r e s . " < < e n d l ; else c o u t < < " U n g u e l t i g e s Datum " < < e n d l ; } / / Eingabe n i c h t v e r s t a n d e n else { c o u t < < " E i n g a b e : \ t ’ J a h r ’ ’ Monat ’ ’ Tag ’ \ t o d e r " < < e n d l < < " \ t ’ J a h r ’ ’ Tag ’ " < < e n d l ; } } 10