Lösungen zu den Aufgaben des C/C++ Kurses

Transcription

Lösungen zu den Aufgaben des C/C++ Kurses
Universität Regensburg
Fakultät Physik IT-Ausbildung
Lösungen zu den Aufgaben des C/C++ Kurses
Die hier aufgeführten Lösungen zu den Aufgaben sind als Vorschläge gedacht, wobei auf eine
kurze und knappe Problemlösung Wert gelegt wurde. Oft gibt es Alternativlösungen zu den
Aufgaben, sowohl in C als auch in C++. Bei den angegebenen Lösungen wird C++ und CCode bewußt gemischt, um die Transparenz zwischen den beiden Sprachen zu demonstrieren
(Ausnahme: Aufgaben 1, 43).
Aufgabe 1
Schreiben Sie ein Programm, das den Namen des Benutzers einliest und ihn dann mit seinem
Namen begrüßt. Verwenden Sie sowohl printf bzw. scanf als auch cout und cin. Erweitern
Sie dazu das in Kapitel 1 abgedruckte Hello world‘-Programm.
’
I Lösung: (ANSI-C)
1
# include < stdio .h >
2
3
4
5
int main ( void )
{
char name [30];
6
printf (" Name eingeben : ");
scanf ("% s " , name );
printf (" Hallo % s !\ n " , name );
7
8
9
10
}
I Lösung: (C++)
1
# include < iostream >
2
3
using namespace std ;
4
5
6
7
int main ( void )
{
char name [30];
8
cout << " Name eingeben : ";
cin >> name ;
cout << " Hallo " << name << "!" << endl ;
9
10
11
12
}
Aufgabe 2
Lesen Sie mit scanf und cin ein Wort, ein Zeichen und eine Fließkommazahl ein und geben
Sie die Inhalte mit printf und cout wieder aus.
I Lösung:
1
2
# include < stdio .h >
# include < iostream >
3
4
using namespace std ;
5
6
7
8
9
10
int main ( void )
{
char wort [30];
char c ;
float x ;
11
printf (" Wort , Zeichen und Zahl eingeben : ");
scanf ("% s % c % f " , wort , &c , & x );
printf (" Eingegeben wurde : %s , %c , % f \ n " , wort , c , x );
12
13
14
15
cout << " Wort , Zeichen und Zahl eingeben : ";
cin >> wort >> c >> x ;
cout < <" Eingegeben wurde : " < < wort < <" , " < <c < <" , " < <x < < endl ;
16
17
18
19
}
Aufgabe 3
Lesen Sie zwei ganze Zahlen ein und geben Sie deren Summe, Produkt, Differenz und Quotienten aus. Achten Sie beim Teilen auf die Richtigkeit des Ergebnisses!
I Lösung:
1
# include < stdio .h >
2
3
4
5
int main ( void )
{
int n , m ;
6
printf ("2 Zahlen eingeben : ");
scanf ("% d % d " , &n , & m );
printf ("% d + % d = % d \ n " , n , m ,
printf ("% d - % d = % d \ n " , n , m ,
printf ("% d * % d = % d \ n " , n , m ,
printf ("% d / % d = % f \ n " , n , m ,
7
8
9
10
11
12
13
}
n + m );
n - m );
n * m );
( float ) n / m );
Aufgabe 4
Geben Sie mithilfe des Modulo-Operators % die letzte Ziffer einer vom Benutzer eingegebenen
Ganzzahl (int) aus.
I Lösung:
1
# include < stdio .h >
2
3
4
5
int main ( void )
{
int zahl ;
6
printf (" Zahl eingeben : ");
scanf ("% d " , & zahl );
printf (" Die letzte Ziffer von % d ist % d \ n " , zahl , zahl %10);
7
8
9
10
}
Aufgabe 5
Ein Zeichen soll eingelesen und dann wieder ausgegeben werden. Dabei soll die Ausgabe sowohl
als Zeichen als auch als Dezimal- bzw. Hexadezimalwert erfolgen (z.B.: z → z 122 0x7A).
Verwenden Sie sowohl scanf als auch cin für die Eingabe, bei der Ausgabe probieren Sie
cout und printf aus.
I Lösung:
1
2
# include < stdio .h >
# include < iostream >
3
4
using namespace std ;
5
6
7
8
9
10
11
12
13
14
int main ( void )
{
char z ;
cout << "\ nEin Zeichen eingeben : ";
cin >> z ;
cout < <" Das Zeichen war : " < <z < <" , dezimal : " < < int ( z )
< <" , hex : 0 x " < < hex < < int ( z );
printf ("\ nDas Zeichen war : %c , dezimal : %d , hex : 0 x % x \ n " ,z ,z , z );
}
Aufgabe 6
Erstellen Sie ein Programm, das mithilfe einer for-Schleife alle durch 7 teilbaren Zahlen
zwischen zwei zuvor eingegebenen Grenzen ausgibt.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
6
7
int main ( void )
{
int a , b ;
8
cout << " Untergrenze :
cout << " Obergrenze :
9
10
"; cin >> a ;
"; cin >> b ;
11
for ( int i = a ; i <= b ; i = i +1)
if ( i %7==0) cout << i << "
12
13
14
";
}
Aufgabe 7
Schreiben Sie ein Programm, das zu einem gegebenen Anfangskapital bei einem vorgegebenem jährlichen Zinssatz berechnet, wie viele Jahre benötigt werden, damit das Kapital eine
bestimmte Zielsumme überschreitet.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
6
7
8
int main ( void )
{
int jahre =0;
double kapital , zins , endkapital ;
9
cout << " Anfangskapital : ";
cin >> kapital ;
cout << " Zinssatz in %: ";
cin >> zins ;
cout << " Angestrebtes Endkapital :
cin >> endkapital ;
10
11
12
13
14
15
";
16
17
while ( kapital < endkapital )
{
jahre ++;
kapital += kapital *( zins /100);
}
18
19
20
21
22
23
cout << " Es dauert " << jahre << " Jahre !" << endl ;
24
25
}
Aufgabe 8
Erweitern Sie das in Kapitel 3.3 abgedruckte Programm so, dass ein Schachbrettmuster auf
dem Bildschirm erscheint.
I Lösung:
1
# include < stdio .h >
2
3
4
5
int main ( void )
{
int zeile , n , m ;
6
for ( zeile =1; zeile <=4; zeile = zeile +1)
{
for ( m =1; m <=2; m = m +1)
{
for ( n =1; n <=4; n = n +1)
printf ("***
");
printf ("\ n ");
}
7
8
9
10
11
12
13
14
15
for ( m =1; m <=2; m = m +1)
{
for ( n =1; n <=4; n = n +1)
printf ("
***");
printf ("\ n ");
}
16
17
18
19
20
21
}
22
23
}
Aufgabe 9
Schreiben Sie ein Programm, das das kleine Einmaleins berechnet und in Tabellenform auf
dem Bildschirm ausgibt.
I Lösung:
1
# include < stdio .h >
2
3
4
5
int main ( void )
{
int i , j ;
6
printf ("
7
|
1
2
3
4
5
6
7
8
9
10\ n ");
8
printf (" - - -+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\ n ");
9
10
for ( i =1; i <=10; i ++)
{
printf ("%2 d | " , i );
for ( j =1; j <=10; j ++) printf ("%3 d " , i * j );
printf ("\ n ");
}
11
12
13
14
15
16
17
}
Aufgabe 10
Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus.
Bestimmen Sie die Primzahlen mittels Ganzzahldivision.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
6
7
int main ( void )
{
int zahl , teiler , limit ;
8
cout << " Obergrenze eingeben : ";
cin >> limit ;
cout << "\ nPrimzahlen bis " << limit << ":\ n ";
9
10
11
12
for ( zahl =2; zahl < limit ; zahl ++)
{
teiler = 2;
while ( zahl % teiler != 0) teiler ++;
if ( teiler == zahl ) cout << zahl << " ";
}
13
14
15
16
17
18
19
}
Aufgabe 11
Geben Sie einen Christbaum‘ durch Ausdruck entsprechend vieler Leerzeichen und Sterne auf
’
dem Bildschirm aus.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
6
7
int main ( void )
{
int blzahl =20 , sternzahl =1 , i , zeile ;
8
for ( zeile =0; zeile <10; zeile ++)
{
for ( i =0; i < blzahl ; i ++) cout << ’ ’;
for ( i =0; i < sternzahl ; i ++) cout << ’* ’;
blzahl - -; sternzahl +=2;
cout << ’\n ’;
}
9
10
11
12
13
14
15
16
}
Aufgabe 12
In unserem Kalender sind zum Ausgleich der astronomischen und kalendarischen Jahreslänge in
regelmäßigen Abständen Schaltjahre eingebaut. Zur exakten Festlegung der Schaltjahre dienen
die folgenden Regeln:
◦ Ist die Jahreszahl durch 4 teilbar, so ist das Jahr ein Schaltjahr. Diese Regel hat allerdings
eine Ausnahme:
◦ Ist die Jahreszahl durch 100 teilbar, so ist das Jahr kein Schaltjahr. Diese Ausnahme hat
wiederum eine Ausnahme:
◦ Ist die Jahreszahl durch 400 teilbar, so ist das Jahr doch ein Schaltjahr.
Erstellen Sie ein Programm, das berechnet, ob eine vom Benutzer eingegebene Jahreszahl ein
Schaltjahr bezeichnet oder nicht.
I Lösung:
1
# include < stdio .h >
2
3
4
5
int main ()
{
int jahr ;
6
printf (" Geben Sie ein Jahr ein : ");
scanf ("% d " ,& jahr );
7
8
9
if ( jahr %4==0)
if ( jahr %100==0)
if ( jahr %400==0)
printf (" Schaltjahr !\ n ");
else
printf (" Kein Schaltjahr !\ n ");
else
printf (" Schaltjahr !\ n ");
else
printf (" Kein Schaltjahr !\ n ");
10
11
12
13
14
15
16
17
18
19
20
}
Aufgabe 13
Programmieren Sie das Spiel Zahlenraten‘: Der Computer generiert eine Zufallszahl zwischen
’
1 und 100, die der Spieler erraten muß. Es wird bei jedem Durchgang mitgeteilt, ob die
eingegebene Zahl zu groß oder zu klein war.
Tipp: Zufallszahlen werden wie folgt generiert: Ein einmaliger Aufruf srand(time(NULL)) initialisiert den
Zufallszahlengenerator. Anschließend liefert jeder Aufruf von rand()%100 eine Zufallszahl zwischen 0 und 99.
Die Funktionen sind in stdlib.h bzw. time.h deklariert.
I Lösung:
1
2
3
# include < stdio .h >
# include < time .h >
# include < stdlib .h >
4
5
6
7
int main ( void )
{
int zahl , rat , versuche =0;
8
srand ( time ( NULL ));
zahl = rand ()%100 + 1;
9
10
11
do
12
{
13
printf (" Zahl eingeben : ");
scanf ("% d " , & rat );
if ( rat > zahl ) printf (" Zu gross !\ n ");
if ( rat < zahl ) printf (" Zu klein !\ n ");
versuche ++;
14
15
16
17
18
}
while ( rat != zahl && versuche <6);
19
20
21
if ( rat == zahl ) printf (" Erraten !\ n ");
else printf (" Verloren ! Die gesuchte Zahl war % d \ n " , zahl );
22
23
24
}
Aufgabe 14 (fakultativ)
Lösen Sie die quadratische Gleichung ax2 + bx + c = 0 für vom Benutzer eingegebene Parameter a, b und c. Falls Ihnen komplexe Zahlen geläufig sind, sollen auch komplexe Lösungen
ausgegeben werden.
√
b2 − 4ac
.
2a
Die Funktion float sqrt(float) zur Berechnung der Wurzel einer positiven Zahl ist in math.h deklariert.
Zum Testen des Programms können Sie folgende Parametersätze verwenden:
4, -36, 81 → 4.5; 2, 2, -12 → 2, 3; 1, -2, 2 → 1+ −i.
Tipp: Die Lösungsformel für die quadratische Gleichung lautet:
x1/2 =
−b ±
I Lösung:
1
2
# include < iostream >
# include < math .h >
3
4
using namespace std ;
5
6
7
8
int main ( void )
{
float a ,b ,c , D ;
// a * x * x + b * x + c = 0
9
cout << "\ nKoeffizienten a b c : ";
cin >> a >> b >> c ;
10
11
12
D = b *b -4* a * c ;
if ( D ==0) cout << " x = " << -b /(2* a ) << endl ;
if (D >0) cout << " x = " << ( - b + sqrt ( D ))/(2* a ) << " und x = "
<< ( -b - sqrt ( D ))/(2* a ) << endl ;
if (D <0) cout << " x = " << -b /(2* a ) << "+ -"
<< sqrt ( - D )/(2* a ) << "* i " << endl ;
13
14
15
16
17
18
19
}
Aufgabe 15
Programmieren Sie mithilfe der switch-case Anweisung einen Mini-Taschenrechner, der zwei
Zahlen und einen Operator (+, -, *, /) einliest und das Ergebnis ausgibt. Eine eventuelle
Division durch 0 soll abgefangen werden.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
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
int main ( void )
{
float z1 , z2 ;
char op ;
cout << "2 Zahlen mit Operator dazwischen [+ -*/]: ";
cin >> z1 >> op >> z2 ;
cout << z1 << op << z2 << "=";
switch ( op )
{
case ’+ ’:
cout << z1 + z2 << ’\n ’;
break ;
case ’ - ’:
cout << z1 - z2 << ’\n ’;
break ;
case ’* ’:
cout << z1 * z2 << ’\n ’;
break ;
case ’/ ’:
if ( z2 ==0)
cout << " Div durch 0 geht nicht \ n ";
else
cout << z1 / z2 << ’\n ’;
break ;
default :
cout << " Den Operator kenne ich nicht \ n ";
}
}
Aufgabe 16
Primzahlberechnung nach dem Sieb-Verfahren: Schreiben Sie alle Zahlen (z.B. von 2 bis 100)
in ein Array. Beginnend mit der kleinsten Zahl wird die Zahl als Primzahl auf dem Bildschirm
ausgegeben und gleichzeitig alle Vielfachen dieser Zahl im Array auf 0 gesetzt d.h. aus der
Liste gestrichen. Anschliessend wird die nächste Zahl 6= 0 im Array bearbeitet.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
6
7
int main ( void )
{
int a [100] , i , j ;
8
for ( i =0; i <100; i ++) a [ i ]= i ;
cout << "\ nDie Ersten Primzahlen ...\ n ";
for ( i =2; i <100; i ++)
{
if ( a [ i ] >0)
{
cout << a [ i ] << ’ ’;
for ( j =2* i ; j <100; j += i ) a [ j ]=0;
}
}
9
10
11
12
13
14
15
16
17
18
19
}
Aufgabe 17
Lesen Sie eine Integerzahl ein und geben Sie deren Bitmuster aus (z.B.: 23 → 00010111).
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
6
7
8
int main ( void )
{
short int n ;
unsigned short int maske =0 x80 ;
9
cout << "8 - Bit - Integer eingeben : ";
cin >> n ;
cout << " dezimal : " << n << "
binaer : ";
while ( maske )
{
if (( n & maske ) > 0)
cout << ’1 ’;
else
cout << ’0 ’;
maske > >=1;
}
10
11
12
13
14
15
16
17
18
19
20
21
}
Aufgabe 18
Bestimmen Sie die Primfaktorzerlegung einer eingegebenen Zahl (z.B.: 200 = 2*2*2*5*5).
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
6
7
int main ( void )
{
int zahl , i , anz =0;
8
cout << " Gib Integerzahl ein : ";
cin >> zahl ;
cout << " Zerlegung : ";
for ( i =2; i <= zahl ; i ++)
while ( zahl % i == 0)
{
if ( anz ==0)
cout << i ;
else
cout << ’* ’ << i ;
anz ++;
zahl /= i ;
}
9
10
11
12
13
14
15
16
17
18
19
20
21
22
}
Aufgabe 19
Sortieren Sie ein mit Zufallszahlen belegtes Array beliebiger Größe mit dem Bubble-SortVerfahren: jeweils zwei benachbarte Feldelemente werden vertauscht, wenn sie in der falschen
Reihenfolge sind.
I Lösung:
1
2
# include < iostream >
# include < stdlib .h >
3
4
using namespace std ;
5
6
7
8
int main ( void )
{
int a [10] , i , zw , change ;
9
cout << " unsortiert :
for ( i =0; i <10; i ++)
{
a [ i ]= rand ()%100;
cout << a [ i ] << ’ ’;
}
10
11
12
13
14
15
";
16
// sortieren ( und dabei ausgeben ...)
do
{
cout << "\ nZwischenschritt : ";
change =0;
// keine Vertauschung noetig
for ( i =0; i <9; i ++)
if ( a [ i ] > a [ i +1])
{
zw = a [ i ]; a [ i ]= a [ i +1]; a [ i +1]= zw ;
change =1;
// Vertauschung
}
for ( i =0; i <10; i ++) cout << a [ i ] << ’ ’;
}
while ( change );
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
}
Aufgabe 20
Schreiben Sie ein Sortierprogramm, das nach dem Selection-Sort Algorithmus arbeitet: 1.
suche das kleinste/größte Element des Arrays, 2. vertausche dieses mit dem ersten Element
des Arrays, 3. gehe wieder zu Schritt 1, jetzt aber mit dem verkürzten Array. Wieso ist dieses
Verfahren effizienter als Bubble-Sort?
I Lösung:
1
2
# include < iostream >
# include < stdlib .h >
3
4
using namespace std ;
5
6
7
8
int main ( void )
{
int a [10] , i , k , zw , min , stelle ;
9
cout << " unsortiert :
for ( i =0; i <10; i ++)
{
a [ i ]= rand ()%100;
cout << a [ i ] << ’ ’;
}
10
11
12
13
14
15
";
16
for ( k =0; k <10; k ++)
{
cout << "\ nZwischenschritt : ";
min = a [ k ];
stelle = k ;
for ( i = k ; i <10; i ++)
/* suche kleinstes Element */
if ( a [ i ] < min )
{
min = a [ i ];
stelle = i ;
}
zw = a [ stelle ]; a [ stelle ]= a [ k ]; a [ k ]= zw ;
for ( i =0; i <10; i ++) cout << a [ i ] << ’ ’;
}
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
}
Aufgabe 21 (fakultativ)
Familie Müller ist zu einer Geburtstagsfeier eingeladen. Leider können sich die Familienmitglieder (Anton, Berta, Claus und Doris) nicht einigen, wer hingeht und wer nicht. In einer
gemeinsamen Diskussion kann man sich jedoch auf die folgenden Grundsätze verständigen:
◦
◦
◦
◦
◦
Mindestens ein Familienmitglied geht zu der Feier.
Anton geht auf keinen Fall zusammen mit Doris.
Wenn Berta geht, dann geht Claus mit.
Wenn Anton und Claus gehen, dann bleibt Berta zu Hause.
Wenn Anton zu Hause bleibt, dann geht entweder(!) Doris oder Claus.
Helfen Sie Familie Müller, indem Sie ein Programm erstellen, das alle Gruppierungen ermittelt,
in denen Familie Müller zur Feier gehen könnte.
Tipp: Erstellen Sie alle denkbaren Kombinationen und prüfen Sie jede darauf, ob sie alle obigen Grundsätze
erfüllt.
I Lösung:
1
2
# include < stdio .h >
# include < stdlib .h >
3
4
5
6
7
8
int main ( void )
{
unsigned char a , b , c , d ;
unsigned char gehen ;
unsigned char z =0;
9
printf (" Folgende Personen koennen zusammen gehen : \ n \ n ");
10
11
/* Dabei heisst z . B . a == 1 , dass Anton mitgehen moechte ,*/
for ( a = 0; a <= 1; a = a + 1)
for ( b = 0; b <= 1; b = b + 1)
for ( c = 0; c <= 1; c = c + 1)
for ( d = 0; d <= 1; d = d + 1)
{
// EINE Moeglichkeit der Implementierung
gehen = ( ( a || b || c || d )
&& ( ! d || ! a )
&& ( ! b || c )
&& ((!( a && c )) || ! b )
&& ( a || ( d || c )));
12
13
14
15
16
17
18
19
20
21
22
23
24
if ( gehen == 1)
{
printf (" % d . " , z = z +1);
if ( a ) printf (" Anton ");
if ( b ) printf (" Berta ");
if ( c ) printf (" Claus ");
if ( d ) printf (" Doris ");
printf ("\ n ");
}
25
26
27
28
29
30
31
32
33
}
34
35
}
Aufgabe 22 (fakultativ)
Man berechne die Nullstellen einer Funktion mithilfe des sogenannten Bisektionsverfahrens:
eine linke und rechte Intervallgrenze wird eingelesen, die Funktionswerte hier und in der Mitte
des Intervalls werden bestimmt. Dann wird das Intervall immer wieder halbiert, bis genügend
Genauigkeit erreicht ist. Verwenden Sie als Beispiel die Funktion f (x) = x3 − x2 − x + 0.04.
Diese hat Nullstellen in den Intervallen [0,1], [-1,0] und [1,2].
I Lösung:
1
2
# include < iostream >
# include < math .h >
3
4
using namespace std ;
5
6
7
8
9
10
int main ( void )
{
int i =1;
float a ,b , c ;
float fa , fc ;
/* Zahl der Iterationen */
/* linker und rechter x - Wert , Mitte */
/* Funktionswerte */
11
cout << " Linke und rechte Grenze : ";
cin >> a >> b ;
12
13
14
do
{
15
16
c =( a + b )/2.0;
fa = a * a *a - a *a - a +0.04;
fc = c * c *c - c *c - c +0.04;
cout << " Iteriere : Nr =" < <i < <" x =" < <c < <" , f ( x )=" < < fc < < ’\n ’;
if ( fc * fa > 0)
a=c;
else
b=c;
i ++;
17
18
19
20
21
22
23
24
25
}
while ( ( fabs (b - a ) > 1e -7) && (i <10) );
26
27
28
29
}
Aufgabe 23
Freunden Sie sich zunächst einmal mit Unterprogrammen an. Im Skript sind folgende Programmfragmente zu finden:
◦
◦
◦
◦
Berechnung von nm : Funktion mypow
Näherung für exp(x): Funktion myexp
Einfache Rekursion: Funktion fak
Türme von Hanoi: Funktion hanoi
Machen Sie daraus jeweils ein lauffähiges Programm.
I Lösung: (Potenz und Exponentialfunktion)
1
# include < stdio .h >
2
3
4
long int mypow ( int n , int m );
double myexp ( double x , int k );
5
6
7
8
9
int main ( void )
{
int n =2 , m =10;
double x =3.0;
10
printf ("% d hoch % d ist % ld \ n " , n , m , mypow (n , m ));
printf (" exp (% lf ) ist etwa % lf \ n " , x , myexp (x , 1000));
11
12
13
}
14
15
16
17
18
long int mypow ( int n , int m )
{
int i ;
long int erg =1;
19
for ( i =1; i <= m ; i ++)
erg *= n ;
return erg ;
20
21
22
23
}
24
25
26
27
28
double myexp ( double x , int k )
{
int n ;
double summand =1.0 , sum =1.0;
29
for ( n =1; n <= k ; n ++)
{
summand *= x / n ;
sum += summand ;
}
return sum ;
30
31
32
33
34
35
36
}
I Lösung: (Fakultät, rekursiv)
1
# include < stdio .h >
2
3
long fak ( int wert );
4
5
6
7
int main ( void )
{
int m =10;
8
printf ("% d ! = % ld \ n " , m , fak ( m ));
9
10
}
11
12
13
14
15
16
long fak ( int wert )
{
if ( wert ==1) return 1;
else return ( wert * fak ( wert -1));
}
I Lösung: (Türme von Hanoi, rekursiv)
1
# include < stdio .h >
2
3
void hanoi ( int , int , int );
4
5
6
7
8
int main ( void )
{
hanoi (5 ,1 ,2);
}
9
10
11
12
void hanoi ( int n , int p1 , int p2 )
{
int parkplatz ;
13
if (n >1)
{
parkplatz = 6 - p1 - p2 ;
hanoi (n -1 , p1 , parkplatz );
}
14
15
16
17
18
19
printf ("1 Scheibe von % d nach % d \ n " , p1 , p2 );
20
21
if (n >1) hanoi (n -1 , parkplatz , p2 );
22
23
}
Aufgabe 24
Schreiben Sie das Programm zur Primzahlzerlegung (Aufgabe 18) so um, dass das Einlesen
der Zahl von einer Funktion eingabe erledigt wird und die Berechnung und Ausgabe der Primfaktoren von einer anderen Funktion zerlegung. Überlegen Sie zuerst, welche Variablentypen
die Funktionen erhalten und zurückliefern sollen!
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
6
int eingabe ( void );
void zerlegung ( int zahl );
7
8
9
10
11
int main ( void )
{
zerlegung ( eingabe ());
}
12
13
14
15
int eingabe ( void )
{
int z ;
16
do
17
{
18
cout << " Gib Integerzahl ein : ";
cin >> z ;
19
20
}
while (z <2);
21
22
23
return z ;
24
25
}
26
27
28
29
void zerlegung ( int zahl )
{
int i , anz =0;
30
cout << zahl << " = ";
for ( i =2; i <= zahl ; i ++)
{
while ( zahl % i == 0)
{
if (! anz ) cout << i ;
else cout << ’* ’ << i ;
anz ++;
zahl /= i ;
}
}
31
32
33
34
35
36
37
38
39
40
41
42
}
Aufgabe 25
Erstellen Sie ein Programm zur numerischen Integration einer Funktion mit der RechtecksMethode. Das Programm soll eine Funktion double f(double x) enthalten, die zu jedem x
einen Funktionswert liefert, sowie eine Funktion double integral(double a, double b,
int n). Darin soll das Intervall [a, b] in n kleine Intervalle aufgeteilt werden, die Fläche der
Rechtecke unter dem Funktionsgraphen berechnet werden und die Gesamtfläche zurückgeliefert
werden.
Z
1
exp(−x2 )dx ≈ 0.746824 benutzen.
Tipp: Zum Testen Ihres Programms können Sie
0
I Lösung:
1
2
# include < iostream >
# include < math .h >
3
4
using namespace std ;
5
6
7
double f ( double x );
double integral ( double a , double b , int n );
8
9
10
11
12
13
14
15
16
int main ( void )
{
double a , b ; int n ;
cout << " Grenze links , rechts und Intervallzahl : ";
cin >> a >> b >> n ;
cout << " Ergebnis : " << integral (a ,b , n ) << ’\n ’ ;
return 0;
}
17
18
19
20
21
double f ( double x )
{
return exp ( - x * x );
}
22
23
24
25
26
double integral ( double a , double b , int n )
{
double flaeche =0 , h ;
int i ;
27
h =( b - a )/ n ;
for ( i =0; i < n ; i ++)
flaeche = flaeche + h * f ( a + i * h );
return flaeche ;
28
29
30
31
32
}
Aufgabe 26
Schreiben Sie eine Funktion int palin(char *c, int erstes, int letztes), die rekursiv prüfen soll, ob ein gegebenes Wort oder ein Satz ein Palindromi ist. Ihr wird das Wort oder
der Satz in einem char-Array c sowie die Stelle des ersten und letzten Zeichens als int übergeben. Stimmen beide Zeichen überein, so kann man mit dem Prüfen des verkürzten Wortes
oder Satzes fortfahren.
Tipp: Die Funktion strlen(text) liefert die Länge des Textes char text[]. Sie ist in string.h deklariert.
Überlegen Sie sich auch, wie Sie Leerzeichen behandeln (siehe Bsp. in der Fussnote). Beachten Sie bitte die
Schreibweise . . .palin(char *c. . . zur Übergabe des char-Arrays.
I Lösung:
1
2
# include < stdio .h >
# include < string .h >
3
4
int palin ( char * , int , int );
5
6
7
8
9
10
int main ( void )
{
char wort []=" derfreibierfred ";
char unwort []=" derfreibiersepp ";
char satz []=" Ein Schwarzer mit Gazelle zagt im Regen nie ";
11
if ( palin ( wort , 0 , strlen ( wort ) -1) == 1)
printf ("\"% s \" ist ein Palindrom \ n " , wort );
else printf ("\"% s \" ist kein Palindrom \ n " , wort );
12
13
14
15
if ( palin ( unwort , 0 , strlen ( unwort ) -1) == 1)
printf ("\"% s \" ist ein Palindrom \ n " , unwort );
else printf ("\"% s \" ist kein Palindrom \ n " , unwort );
16
17
18
19
if ( palin ( satz , 0 , strlen ( satz ) -1) == 1)
printf ("\"% s \" ist ein Palindrom \ n " , satz );
else printf ("\"% s \" ist kein Palindrom \ n " , satz );
20
21
22
23
}
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int palin ( char *c , int erstes , int letztes )
{
while ( c [ erstes ] == ’ ’ && letztes - erstes > 2)
erstes ++;
while ( c [ letztes ] == ’ ’ && letztes - erstes > 2)
letztes - -;
if (!(
c [ erstes ]== c [ letztes ]
|| c [ erstes ]== c [ letztes ]+32
|| c [ erstes ]== c [ letztes ] -32))
return 0;
else
{
if ( letztes - erstes <= 2)
return 1;
return palin (c , erstes +1 , letztes -1);
}
}
i
vorwärts ! rückwärts z.B.:
an Hr. De Muirier von der DLR,
heutzutage rassistisch und stark
”
anna‘, otto‘, ein schwarzer mit gazelle zagt im regen nie‘. Danke an dieser Stelle
’der mich’ darauf
’ hingewiesen hat, dass das im Original-Palindrom verwendete Wort
pejorativ ist“. (Zitat)
Aufgabe 27
Das Treppenproblem: Sie können bei einer Treppe entweder genau eine Stufe pro Schritt
nehmen, oder, falls sie sportlich und durchtrainiert sind, 2 Stufen auf einmal. Damit haben sie
mehrere Möglichkeiten eine mehrstufige Treppe zu überwinden (z.B.: 1 Stufe → 1 Möglichkeit,
2 Stufen → 2 Möglichkeiten, 3 Stufen → 3 Möglichkeiten, 4 Stufen → 5 Möglichkeiten, . . .).
Schreiben Sie ein Programm, welches Ihnen rekursiv die Anzahl der Möglichkeiten berechnet,
eine Treppe T mit n Stufen zu erklimmen:
n
für n < 3
Tn =
T(n−1) + T(n−2) für n ≥ 3
Berechnen Sie dann die Anzahl der Möglichkeiten für n=25. Wieso und wie müssen Sie ihr
Programm modifizieren, damit dieses auch die Anzahl der Möglichkeiten für n=768 (Ulmer
Münster) und n=1860 (Empire State Building) berechnen kann?
Tipp: Bei der Treppe zur Physik-Bibliothek (n=25) haben Sie 121.393 Möglichkeiten, beim Ulmer Münster
etwa 23 x 10159 Möglichkeiten und beim Empire State Building immerhin etwa 37 x 10387 Möglichkeiten.
I Lösung: (rekursiv)
1
# include < stdio .h >
2
3
int treppe ( int );
4
5
6
7
int main ( void )
{
int stufen ;
8
printf ("\ n \ nAnzahl der Stufen ?: ");
scanf ("% d " , & stufen );
printf (" Bei % d Stufen haben Sie % d Moeglichkeiten \ n " ,
stufen , treppe ( stufen ));
9
10
11
12
13
}
14
15
16
17
18
19
20
21
int treppe ( int stufen )
{
if ( stufen <= 2)
return stufen ;
else
return treppe ( stufen -1) + treppe ( stufen -2);
}
I Lösung: (additiv)
1
# include < stdio .h >
2
3
void treppe ( int );
4
5
6
7
int main ( void )
{
int stufen ;
8
printf ("\ n \ nAnzahl der Stufen ?: ");
scanf ("% d " , & stufen );
printf (" Bei % d Stufen haben Sie " , stufen );
treppe ( stufen );
printf (" Moeglichkeiten ");
9
10
11
12
13
14
}
15
16
17
void treppe ( int stufen )
{
int letztes [1000] , vletztes [1000] , ergebnis [1000];
int result =0 , carry =0;
int z , index , lastindex =999 , treffer =0;
18
19
20
21
for ( z =0; z <1000; z ++)
vletztes [ z ]= letztes [ z ]= ergebnis [ z ]=0;
22
23
24
letztes [0]=2;
vletztes [0]=1;
25
26
27
if ( stufen < 3)
ergebnis [0] = stufen ;
28
29
30
while ( stufen - - > 2)
{
for ( z =0; z <1000; z ++)
{
result = vletztes [ z ] + letztes [ z ] + carry ;
if ( result >= 10)
{
ergebnis [ z ] = result - 10;
carry = 1;
}
else
{
ergebnis [ z ] = result ;
carry = 0;
}
}
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
for ( z =0; z <1000; z ++)
{
vletztes [ z ] = letztes [ z ];
letztes [ z ] = ergebnis [ z ];
}
48
49
50
51
52
}
53
54
while ( treffer != 1)
if ( ergebnis [ lastindex ] == 0)
lastindex - -;
else
treffer = 1;
index = lastindex ;
while ( index >= 0)
{
if ( index != 0 && index % 3 == 0)
printf ("% d ." , ergebnis [ index - -]);
else
printf ("% d " , ergebnis [ index - -]);
}
if ( lastindex >= 9)
printf (" (=% d ,% de % d )" , ergebnis [ lastindex ] ,
ergebnis [ lastindex - 1] ,
lastindex );
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
}
Aufgabe 28 (fakultativ)
Zur Berechnung der Wurzel einer Zahl gibt es ein rekursives Verfahren. Die Rekursionsformel
lautet:
( h
i
x
1
w(n
−
1,
x)
+
für n ≥ 1
2
w(n−1,x)
w(n, x) =
1
für n = 0
Schreiben Sie eine Funktion double wurzel(int n, double x), die rekursiv die Wurzel
einer eingegebenen Zahl x berechnet. Die Zahl n gibt die Rekursionstiefe an. Vergleichen Sie
das Ergebnis mit dem exakten Wert.
I Lösung:
1
2
# include < stdio .h >
# include < math .h >
3
4
5
6
7
8
double wurzel ( int n , double x )
{
if ( n ==0) return 1;
else return 0.5*( wurzel (n -1 , x )+ x / wurzel (n -1 , x ));
}
9
10
11
12
13
int main ( void )
{
double x ;
int n ;
14
printf (" Zahl eingeben : ");
scanf ("% lf " , & x );
printf (" Anzahl der Rekursionen : ");
scanf ("% d " , & n );
printf (" Die Wurzel von % f ist etwa %1.12 f , exakt %1.12 f \ n " ,
x , wurzel (n , x ) , sqrt ( x ));
15
16
17
18
19
20
21
}
Aufgabe 29
Man berechne für kleine ganze Zahlen m, n (m ≤ 3, n ≤ 8) die Ackermann-Funktion a(m, n):

falls m = 0
 n+1
a(m − 1, 1)
falls n = 0
a(m, n) :=

a(m − 1, a(m, n − 1)) sonst
Tipp: Zum Testen Ihres Programms können Sie a(1, 1) = 3, a(3, 3) = 61, a(3, 8) = 2045 benutzen.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
int acker ( int m , int n );
6
7
8
9
int main ( void )
{
int a , b ;
10
cout << "2 Zahlen : ";
cin >> a >> b ;
cout << " a (" << a << " , " << b << ") = "
<< acker (a , b ) << endl ;
11
12
13
14
15
}
16
17
18
19
20
21
22
23
24
25
int acker ( int m , int n )
{
if ( m ==0) return n +1;
else
{
if ( n ==0) return acker (m -1 ,1);
else return acker (m -1 , acker (m ,n -1));
}
}
Aufgabe 30
Erstellen Sie ein Programm mit einer Struktur namens person, die einige Daten (Name,
Vorname, Alter, Schuhgröße,. . .) einer Person speichert. Eine Funktion eingabe soll einen
Datensatz einlesen und zurückliefern. Das Programm soll dann mithilfe von eingabe die Daten
zweier Personen aufnehmen und den Namen des Älteren ausgeben.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
6
7
8
9
typedef struct
{
char name [20] , vname [20];
int alter , schuhgroesse ;
} person ;
10
11
person einlesen ( void );
12
13
14
15
int main ( void )
{
person p1 , p2 ;
16
p1 = einlesen ();
cout << endl ;
p2 = einlesen ();
17
18
19
20
if ( p1 . alter > p2 . alter )
cout << p1 . vname << " " << p1 . name
<< " ist der aeltere ." << endl ;
else
cout << p2 . vname << " " << p2 . name
<< " koennte der aeltere sein ." << endl ;
21
22
23
24
25
26
27
}
28
29
30
31
person einlesen ( void )
{
person p ;
32
cout << " Vorname : ";
cin >> p . vname ;
cout << " Name : ";
cin >> p . name ;
cout << " Alter : ";
cin >> p . alter ;
cout << " Schuhgroesse : ";
cin >> p . schuhgroesse ;
33
34
35
36
37
38
39
40
41
return p ;
42
43
}
Aufgabe 31
Im Sript finden Sie ein Beispielprogramm zur Dateibearbeitung. Versuchen Sie, es zu verstehen,
und experimentieren Sie damit.
I Lösung:
Hier hilft nun wirklich nur noch lesen, verstehen und abtippen!
Für die Lösungen der Aufgaben 32–34 werden die folgenden Textdateien im jeweils aktuellen
Verzeichnis vorausgesetzt:
demo.txt
1
2
3
Hallo , das ist eine Testdatei !
Hier steht die zweite Zeile .
Und schon ist ’ s wieder zu Ende ...
text.txt
1
2
3
4
In
diesem
Text
sind
viel
zu viele
Leerzeichen
vorhanden ,
die
entfernt werden
muessen .
Aufgabe 32
Erstellen Sie ein Programm, das einen Text aus einer Datei einliest und auf dem Bildschirm
ausgibt, wobei Groß- in Kleinbuchstaben verwandelt werden sollen und umgekehrt.
I Lösung:
1
2
# include < iostream >
# include < fstream >
3
4
using namespace std ;
5
6
7
8
9
int main ( void )
{
char c ;
ifstream datei ;
10
datei . open (" demo . txt " , ios :: in );
if (! datei )
{
cout << " Datei nicht gefunden !\ n ";
return 1;
}
11
12
13
14
15
16
17
while ( datei . get ( c ))
{
if (c >= ’a ’ && c <= ’z ’) c = c +( ’A ’ - ’a ’);
else if (c >= ’A ’ && c <= ’Z ’) c =c -( ’A ’ - ’a ’);
cout << c ;
}
datei . close ();
18
19
20
21
22
23
24
25
}
Aufgabe 33
Schreiben Sie ein Programm, das einen Text aus einer Datei und einen Buchstaben einliest
und ermittelt, wie oft der Buchstabe in dem Text vorkommt.
I Lösung:
1
2
# include < iostream >
# include < fstream >
3
4
using namespace std ;
5
6
7
8
9
10
int main ( void )
{
char c , buchst ;
int anzahl =0;
ifstream datei ;
11
cout << " Zeichen eingeben :
cin >> buchst ;
12
13
";
14
cout << " Der Text \ n ";
15
16
datei . open (" demo . txt " , ios :: in );
while ( datei . get ( c ))
{
if ( c == buchst ) anzahl ++;
cout << c ;
}
datei . close ();
cout << "\ nenthaelt " << anzahl << " mal das Zeichen "
<< buchst << endl ;
17
18
19
20
21
22
23
24
25
26
}
Aufgabe 34
Schreiben Sie ein Programm, das aus einem Text in einer Datei alle mehrfach vorkommenden
Leerzeichen entfernt und den Text auf dem Bildschirm ausgibt.
I Lösung:
1
2
# include < iostream >
# include < fstream >
3
4
using namespace std ;
5
6
7
8
9
int main ( void )
{
char c , voriges = ’a ’;
ifstream datei ;
10
datei . open (" text . txt " , ios :: in );
11
12
while ( datei . get ( c ))
{
if (!( voriges == ’ ’ && c == ’ ’))
cout << c ;
voriges = c ;
}
datei . close ();
13
14
15
16
17
18
19
20
}
Aufgabe 35
Es ist feld ein int-Array und p ein int-Zeiger. Welche der folgenden Zuweisungen sind
zulässig, welche nicht? (Ggf. ausprobieren!)
◦
◦
◦
◦
p = feld;
feld = p;
p = &feld[3];
feld[2] = p[5];
I Lösung:
Alle Zuweisungen sind zulässig ausser der Zweiten da feld eine Zeigerkonstante ist und die
Adresse der Elemente enthält, welche durch die Definition von feld reserviert wurden. Diese
Adresse kann nicht geändert werden. Der Zeigervariablen p dürfen beliebige Adressen zugewiesen werden. Die erste und dritte Zuweisung sind daher korrekt, weil auch die Ausdrücke zur
Berechnung dieser Adressen korrekt sind. In der letzten Zuweisung wird ein einzelner int-Wert
(evtl. unbekannter Herkunft, je nach Vorgeschichte) in ein Element von feld gespeichert, was
formal richtig ist.
Aufgabe 36
Es seien p1 und p2 zwei int-Zeiger und i eine int-Variable. Welche Zuweisungen wird der
Compiler akzeptieren, welche nicht? (Ggf. ausprobieren!)
◦
◦
◦
◦
◦
p1 = p2 + i;
p1 = i + p2;
i = p1 * p2;
i = p1 - p2;
i = p1 + p2;
I Lösung:
Die erste Zuweisung wird vom Compiler akzeptiert. Hier wird zu einer Adresse eine ganze
Zahl addiert. Das Resultat ist ein um einen konstanten Wert (i*sizeof(int)) verschobener
Zeiger. Die meisten Compiler akzeptieren auch die zweite Zuweisung, da das Vertauschen der
Operanden bei +‘durchaus erlaubt ist. Die dritte Zuweisung ist völliger Blödsinn. Bei der
’
vierten Zuweisung wird die Entfernung der Elemente (in sizeof(int)) ermittelt, auf die die
Zeigervariablen p1 und p2 zeigen. Die letzte Zuweisung ist wiederum keine sinnvolle Operation.
Aufgabe 37
Schreiben Sie ein bestehendes Programm (z.B. Lösung der quadratischen Gleichung) so um,
dass die Benutzereingabe von einer Funktion eingabe erledigt wird, der man die Variablen
übergeben muss (Pointer!).
I Lösung:
1
2
# include < iostream >
# include < math .h >
3
4
using namespace std ;
5
6
void eingabe ( double * , double * , double *);
7
8
9
10
int main ( void )
{
double a ,b ,c , D ;
11
eingabe (& a , &b , & c );
D = b *b -4* a * c ;
if ( D ==0) cout << " x = " << -b /(2* a ) << endl ;
if (D >0) cout << " x = " << ( - b + sqrt ( D ))/(2* a )
<< " und x = " << ( -b - sqrt ( D ))/(2* a ) << endl ;
if (D <0) cout << " x = " << -b /(2* a ) << "+ -"
<< sqrt ( - D )/(2* a ) << "* i " << endl ;
12
13
14
15
16
17
18
19
}
20
21
22
23
24
25
void eingabe ( double *a , double *b , double * c )
{
cout << " Die Parameter a , b und c eingeben :
cin >> * a >> * b >> * c ;
}
";
Aufgabe 38
Schreiben Sie eine Funktion stringlength, an die ein char-Array übergeben wird, und die
die Länge dieser Zeichenkette zurückliefert.
Tipp: Das Ende einer Zeichenkette ist durch ’\0’ (ASCII: 0) gekennzeichnet.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
int stringlength ( char * w );
6
7
8
9
int main ( void )
{
char wort [50];
10
cout << " Wort eingeben : ";
cin >> wort ;
cout << " Das Wort " << wort < <" hat "
<< stringlength ( wort ) << " Zeichen ." << endl ;
11
12
13
14
15
}
16
17
18
19
int stringlength ( char * w )
{
int i =0;
20
while ( w [ i ]!= ’\0 ’) i ++;
return i ;
21
22
23
}
Aufgabe 39
Der Benutzer soll ein Wort und ein Zeichen eingeben. Es soll das Wort, das um dieses Zeichen
verlängert worden ist, ausgegeben werden (z.B.: Hall + o → Hallo). Verwenden Sie dazu die
vorher (Aufgabe 38) definierte Funktion stringlength, um die Stelle des letzten Zeichens
zu ermitteln.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
int strlen ( char * w );
6
7
8
9
10
int main ( void )
{
char wort [50] , c ;
int j , l ;
11
cout << " Wort eingeben : ";
cin >> wort ;
cout << " Buchstaben eingeben : ";
cin >> c ;
12
13
14
15
16
l = stringlength ( wort );
wort [ l ]= c ;
wort [ l +1]= ’\0 ’;
cout << wort << endl ;
17
18
19
20
21
}
22
23
24
25
int stringlength ( char * w )
{
int i =0;
26
while ( w [ i ]!= ’\0 ’) i ++;
return i ;
27
28
29
}
Aufgabe 40
Schreiben Sie das Bubble-Sort-Programm (Aufgabe 19) so um, dass das Sortieren in einer
Funktion geschieht, der man den Zeiger auf das Array übergibt.
I Lösung:
1
2
# include < iostream >
# include < stdlib .h >
3
4
using namespace std ;
5
6
void sortiere ( int *);
7
8
9
10
int main ( void )
{
int a [10] , i ;
11
cout << "\ nUnsortiertes Array : \ n ";
for ( i =0; i <10; i ++)
{
a [ i ]= rand ()%100;
cout << a [ i ] << " ";
}
sortiere ( a );
cout << "\ nSortiertes Array : \ n ";
for ( i =0; i <10; i ++)
cout << a [ i ] << " ";
cout << endl ;
12
13
14
15
16
17
18
19
20
21
22
23
}
24
25
26
27
void sortiere ( int * x )
{
int i , ablage , change ;
28
do
{
29
30
change = 0;
for ( i =0; i <9; i ++)
if ( x [ i ] > x [ i +1])
{
ablage = x [ i ];
x [ i ]= x [ i +1];
x [ i +1]= ablage ;
change = 1;
}
31
32
33
34
35
36
37
38
39
}
while ( change );
40
41
42
}
Aufgabe 41
Schreiben Sie ein Programm, das eine Funktion prosumo enthält. Dieser Funktion wird ein
Vektor übergeben; sie liefert die Summe und das Produkt der Vektorelemente zurück.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
void prosumo ( int , float * , float * , float *);
6
7
8
9
int main ( void )
{
float f []={1.0 ,2.0 ,3.0 ,7.0} , ergp , ergs ;
10
prosumo (4 ,f ,& ergp ,& ergs );
cout << " Produkt : " << ergp
<< " , Summe : " << ergs << ’\n ’ ;
11
12
13
14
}
15
16
17
18
19
20
21
22
23
24
void prosumo ( int n , float *F , float *x , float * y )
{
int i ; * x =1.0; * y =0.0;
for ( i =0; i < n ; i ++)
{
* x *= F [ i ];
* y += F [ i ];
}
}
Aufgabe 42
Schreiben Sie das Integrations-Programm (Aufgabe 25) so um, dass die zu integrierende Funktion f(x) der Funktion integral als Pointer übergeben wird.
I Lösung:
1
2
# include < iostream >
# include < math .h >
3
4
using namespace std ;
5
6
7
8
double gauss ( double x );
double parabel ( double x );
double integral ( double (*)( double ) , double , double , int );
9
10
11
12
13
int main ( void )
{
double a , b ;
int n ;
14
cout << " Grenze oben , unten und Intervallzahl : ";
cin >> a >> b >> n ;
cout << " Ergebnis ( Gauss ): "
<< integral ( gauss ,a ,b , n ) << ’\n ’;
cout << " Ergebnis ( Parabel ): "
<< integral ( parabel ,a ,b , n ) << ’\n ’;
15
16
17
18
19
20
21
return 0;
22
23
}
24
25
26
27
28
double gauss ( double x )
{
return exp ( - x * x );
}
29
30
31
32
33
double parabel ( double x )
{
return x * x ;
}
34
35
36
37
38
double integral ( double (* f )( double x ) , double a , double b , int n )
{
double flaeche =0 , h ;
int i ;
39
h =( b - a )/ n ;
for ( i =0; i < n ; i ++)
flaeche = flaeche + h * f ( a + i * h + h /2);
return flaeche ;
40
41
42
43
44
}
Aufgabe 43
Erzeugen Sie dynamisch Speicherplatz für n double-Zahlen, lesen Sie sie ein und bestimmen
Sie das Maximum und die Summe. Wie sieht die Speicheralloziierung in reinem C und in C++
aus?
I Lösung: (ANSI-C)
1
2
# include < stdio .h >
# include < stdlib .h >
3
4
5
6
7
8
int main ( void )
{
int SIZE , i ;
float *v , sum , * max ;
9
printf (" Laenge des Vekors eingeben : ");
scanf ("% d " ,& SIZE );
10
11
12
v = ( float *) malloc ( SIZE * sizeof ( float ));
13
14
if ( v == NULL ) return 1;
15
16
printf ("% d Float - Zahlen eingeben : " , SIZE );
for ( i =0; i < SIZE ; i ++)
scanf ("% f " , v + i );
17
18
19
20
max = v ;
sum = 0.0;
21
22
23
for ( i =0; i < SIZE ; i ++)
{
sum += v [ i ];
if ( v [ i ] > * max ) max = v + i ;
}
24
25
26
27
28
29
printf ("\ nSumme : %f , Maximum : % f \ n " , sum , * max );
30
31
free ( v );
32
33
}
I Lösung: (C++)
1
# include < iostream >
2
3
using namespace std ;
4
5
6
7
8
int main ( void )
{
int SIZE , i ;
float *v , sum , * max ;
9
10
11
cout << " Laenge des Vekors eingeben : ";
cin >> SIZE ;
12
13
v = new float [ SIZE ];
14
15
if ( v == NULL ) return 1;
16
17
18
19
20
cout << SIZE << " Float - Zahlen eingeben : ";
for ( i =0; i < SIZE ; i ++)
cin >> v [ i ];
max = v ;
sum = 0.0;
21
22
23
for ( i =0; i < SIZE ; i ++)
{
sum += v [ i ];
if ( v [ i ] > * max ) max = v + i ;
}
24
25
26
27
28
29
cout << " Summe : " << sum << " , Maximum : "
<< * max << endl ;
30
31
32
delete v ;
33
34
}
Aufgabe 44
Erstellen Sie eine Funktion zur Sortierung eines Arrays von int-Zahlen. Übergeben Sie der
Sortierfunktion als Parameter eine Funktion zum Vergleich zweier Zahlen. Erzeugen Sie unterschiedliche Sortierungen (aufsteigend, absteigend, nach letzter Ziffer, nach der Quersumme,. . .),
indem Sie unterschiedliche Vergleichsfunktionen an die Sortierfunktion übergeben.
I Lösung:
1
# include < iostream >
2
3
using namespace std ;
4
5
void Ausgabe ( int *);
6
7
8
9
10
11
int
int
int
int
int
auf ( const int , const int );
ab ( const int , const int );
lziffer ( const int , const int );
rueckw ( const int , const int );
qsumme ( const int , const int );
12
13
void sort ( int * , int , int (*)( const int , const int ));
14
15
16
17
int main ( void )
{
int Zahlen []={10 ,5 ,78 ,3 ,34 ,76 ,33 ,1352 ,56 ,85};
18
cout << " Unsortiertes Array :\ n ";
Ausgabe ( Zahlen );
sort ( Zahlen , 10 , auf );
cout << " aufsteigend sortiert :\ n ";
Ausgabe ( Zahlen );
sort ( Zahlen , 10 , ab );
cout << " absteigend sortiert :\ n ";
Ausgabe ( Zahlen );
sort ( Zahlen , 10 , lziffer );
cout << " nach letzter Ziffer sortiert :\ n ";
Ausgabe ( Zahlen );
sort ( Zahlen , 10 , qsumme );
cout << " nach der Quersumme sortiert :\ n ";
Ausgabe ( Zahlen );
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
}
34
35
36
37
38
39
void Ausgabe ( int * z )
{
for ( int i =0; i <10; i ++) cout << z [ i ] << "
cout << endl << endl ;
}
";
40
41
42
43
void sort ( int *z , int size , int (* comp )( const int , const int ))
{
int ablage ;
44
45
46
47
48
49
50
51
52
53
54
for ( int i =0; i < size -1; i ++)
for ( int j = i +1; j < size ; j ++)
{
if ( comp ( z [ i ] , z [ j ])==0)
{
ablage = z [ i ];
z [ i ]= z [ j ];
z [ j ]= ablage ;
}
}
55
}
56
57
58
59
60
61
62
int auf ( const int a , const int b )
{
if (a < b ) return 1;
else return 0;
}
63
64
65
66
67
68
int ab ( const int a , const int b )
{
if (a > b ) return 1;
else return 0;
}
69
70
71
72
73
74
int lziffer ( const int a , const int b )
{
if ( a %10 < b %10) return 1;
else return 0;
}
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
int qsumme ( const int a , const int b )
{
int x =0 , y =0 , z ;
z=a;
while ( z !=0)
{
x += z %10;
z = z /10;
}
z=b;
while ( z !=0)
{
y += z %10;
z = z /10;
}
if (x < y ) return 1;
else return 0;
}
Aufgabe 45
Schreiben Sie ein Programm zur Verwaltung einer verketteten Liste. Als Nutzinhalt‘der Liste
’
wählen Sie eine char-Variable, in der Sie genau ein Zeichen speichern können. Füllen Sie die
Kette in einer Funktion fangan mit den Kleinbuchstaben des Alphabets. Mit einer Funktion
gibaus können Sie jeweils den Inhalt der gesamten Liste ausgeben. Experimentieren sie dann,
indem sie ihr Programm mit einer Funktion fuegein erweitern, die an beliebiger Stelle n-mal
den Buchstaben ’X’ einfügt. Vergessen Sie nicht eine Funktion loesche zu implementieren, mit
der Teile der Liste gelöscht werden können. Eine weitere Ausbaumöglichkeit ist eine Funktion
ersetze, die nach Wunsch beliebige Kleinbuchstaben durch Grossbuchstaben ersetzt.
Tipp: Lassen Sie sich durch verkettete Listen nicht abschrecken! Setzen Sie sich in aller Ruhe mit Bleistift,
Papier und einer guten Tasse Tee bzw. Capuccinoii hin und dröseln Sie Element für Element und Pointer
für Pointer auf. Vergessen Sie dabei nicht, dass auch Pointervariablen ganz einfache, lokale Variablen sein
können. . .
I Lösung:
1
2
3
# include < iostream >
# include < stdlib .h >
# include < string .h >
4
5
using namespace std ;
6
7
8
9
10
11
typedef struct slink
{
char zeichen ;
struct slink * next ;
} link ;
12
13
14
15
16
17
link * fangan ( void );
void gibaus ( link *);
void fuegein ( link * , int , int , char );
void loesche ( link * , int , int );
void ersetze ( link * , char *);
18
19
20
21
int main ( void )
{
link * anfang ;
22
cout < <" Unser Alphabet als verkettete Liste ...\ n ";
gibaus ( anfang = fangan ());
cout < <"\ n \ nFuege 5 ’X ’ nach der 8. Stelle ein \ n ";
fuegein ( anfang , 8 , 5 , ’X ’);
gibaus ( anfang );
cout < <"\ n \ nLoesche 10 Zeichen nach der 7. Stelle \ n ";
loesche ( anfang , 7 , 10);
gibaus ( anfang );
cout < <"\ n \ nErsetze a ,e ,u ,v ,w , z durch Grossbuchstaben \ n ";
ersetze ( anfang , " aeuvwz ");
gibaus ( anfang );
23
24
25
26
27
28
29
30
31
32
33
34
delete ( anfang );
35
36
}
37
38
39
40
41
ii
link * fangan ( void )
{
link * anfang , * kette , * hilf ;
oder Espresso, je nach Tageszeit
42
if (!( anfang = kette = new link ))
exit (1);
anfang - > zeichen = ’a ’;
anfang - > next = NULL ;
43
44
45
46
47
for ( int i =1; i <=25; i ++)
{
if (!( hilf = new link ))
exit (1);
hilf - > zeichen = ’a ’+ i ;
hilf - > next = NULL ;
kette - > next = hilf ;
kette = hilf ;
}
48
49
50
51
52
53
54
55
56
57
return anfang ;
58
59
}
60
61
62
63
64
65
66
67
68
69
void gibaus ( link * kette )
{
cout << " Inhalt der Kette : ";
while ( kette != NULL )
{
cout << kette - > zeichen ;
kette = kette - > next ;
}
}
70
71
72
73
void fuegein ( link * kette , int stelle , int anzahl , char zeichen )
{
link * hilf , * next ;
74
for ( int i =1; i < stelle ; i ++)
{
if ( kette - > next == NULL )
break ;
kette = kette - > next ;
}
next = kette - > next ;
75
76
77
78
79
80
81
82
for ( int j =1; j <= anzahl ; j ++)
{
if (!( hilf = new link ))
exit (1);
hilf - > zeichen = zeichen ;
hilf - > next = next ;
kette - > next = hilf ;
kette = hilf ;
}
83
84
85
86
87
88
89
90
91
92
}
93
94
95
96
97
98
void loesche ( link * kette , int stelle , int anzahl )
{
link * hilf ;
if ( stelle < 2)
return ;
99
100
101
102
103
104
for ( int i =1; i < stelle ; i ++)
{
if ( kette - > next == NULL )
break ;
kette = kette - > next ;
}
105
106
for ( int j =1; j <= anzahl ; j ++)
{
hilf = kette - > next ;
if ( hilf == NULL )
break ;
kette - > next = kette - > next - > next ;
delete ( hilf );
}
107
108
109
110
111
112
113
114
115
}
116
117
118
119
120
121
122
123
124
125
126
void ersetze ( link * kette , char * zeichen )
{
while ( kette != NULL )
{
for ( int i =0; i < strlen ( zeichen ); i ++)
if ( kette - > zeichen == zeichen [ i ])
kette - > zeichen -=32;
kette = kette - > next ;
}
}
D. Schuh
et al.
August 2015