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