L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom...

43
Universit¨ at Regensburg Fakult¨ at Physik IT-Ausbildung osungen zu den Aufgaben des C/C++ Kurses Die hier aufgef¨ uhrten L¨ osungen zu den Aufgaben sind als Vorschl¨ age gedacht, wobei auf eine kurze und knappe Probleml¨ osung Wert gelegt wurde. Oft gibt es Alternativl¨ osungen zu den Aufgaben, sowohl in C als auch in C++. Bei den angegebenen L¨ osungen wird C++ und C- Code 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¨ ußt. Verwenden Sie sowohl printf bzw. scanf als auch cout und cin. Erweitern Sie dazu das in Kapitel 1 abgedruckte Hello world‘-Programm. I osung: (ANSI-C) 1 #include <stdio.h> 2 3 int main(void) 4 { 5 char name[30]; 6 7 printf("Name eingeben: "); 8 scanf("%s", name); 9 printf("Hallo %s!\n", name); 10 } I osung: (C++) 1 #include <iostream> 2 3 using namespace std; 4 5 int main(void) 6 { 7 char name[30]; 8 9 cout << "Name eingeben: "; 10 cin >> name; 11 cout << "Hallo " << name << "!" << endl; 12 }

Transcript of L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom...

Page 1: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Universitat Regensburg

Fakultat Physik IT-Ausbildung

Losungen zu den Aufgaben des C/C++ Kurses

Die hier aufgefuhrten Losungen zu den Aufgaben sind als Vorschlage gedacht, wobei auf einekurze und knappe Problemlosung Wert gelegt wurde. Oft gibt es Alternativlosungen zu denAufgaben, sowohl in C als auch in C++. Bei den angegebenen Losungen wird C++ und C-Code 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 seinemNamen begrußt. Verwenden Sie sowohl printf bzw. scanf als auch cout und cin. ErweiternSie dazu das in Kapitel 1 abgedruckte

’Hello world‘-Programm.

I Losung: (ANSI-C)

1 #include <stdio.h>2

3 int main(void)4 {5 char name [30];6

7 printf ("Name eingeben: ");8 scanf ("%s", name);9 printf (" Hallo %s!\n", name);

10 }

I Losung: (C++)

1 #include <iostream >2

3 using namespace std;4

5 int main(void)6 {7 char name [30];8

9 cout << "Name eingeben: ";10 cin >> name;11 cout << "Hallo " << name << "!" << endl;12 }

Page 2: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 2

Lesen Sie mit scanf und cin ein Wort, ein Zeichen und eine Fließkommazahl ein und gebenSie die Inhalte mit printf und cout wieder aus.

I Losung:

1 #include <stdio.h>2 #include <iostream >3

4 using namespace std;5

6 int main(void)7 {8 char wort [30];9 char c;

10 float x;11

12 printf ("Wort , Zeichen und Zahl eingeben: ");13 scanf ("%s %c %f", wort , &c, &x);14 printf (" Eingegeben wurde: %s, %c, %f\n", wort , c, x);15

16 cout << "Wort , Zeichen und Zahl eingeben: ";17 cin >> wort >> c >> x;18 cout <<" Eingegeben wurde: "<<wort <<", "<<c<<", "<<x<<endl;19 }

Aufgabe 3

Lesen Sie zwei ganze Zahlen ein und geben Sie deren Summe, Produkt, Differenz und Quoti-enten aus. Achten Sie beim Teilen auf die Richtigkeit des Ergebnisses!

I Losung:

1 #include <stdio.h>2

3 int main(void)4 {5 int n, m;6

7 printf ("2 Zahlen eingeben: ");8 scanf ("%d %d", &n, &m);9 printf ("%d + %d = %d\n", n, m, n+m);

10 printf ("%d - %d = %d\n", n, m, n-m);11 printf ("%d * %d = %d\n", n, m, n*m);12 printf ("%d / %d = %f\n", n, m, (float)n/m);13 }

Page 3: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 4

Geben Sie mithilfe des Modulo-Operators % die letzte Ziffer einer vom Benutzer eingegebenenGanzzahl (int) aus.

I Losung:

1 #include <stdio.h>2

3 int main(void)4 {5 int zahl;6

7 printf ("Zahl eingeben: ");8 scanf ("%d", &zahl);9 printf ("Die letzte Ziffer von %d ist %d\n", zahl , zahl %10);

10 }

Aufgabe 5

Ein Zeichen soll eingelesen und dann wieder ausgegeben werden. Dabei soll die Ausgabe sowohlals Zeichen als auch als Dezimal- bzw. Hexadezimalwert erfolgen (z.B.: z → z 122 0x7A).Verwenden Sie sowohl scanf als auch cin fur die Eingabe, bei der Ausgabe probieren Siecout und printf aus.

I Losung:

1 #include <stdio.h>2 #include <iostream >3

4 using namespace std;5

6 int main(void)7 {8 char z;9 cout << "\nEin Zeichen eingeben: ";

10 cin >> z;11 cout <<"Das Zeichen war: "<<z<<", dezimal: "<<int(z)12 <<", hex: 0x"<<hex <<int(z);13 printf ("\ nDas Zeichen war: %c, dezimal: %d, hex: 0x%x\n",z,z,z);14 }

Page 4: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 6

Erstellen Sie ein Programm, das mithilfe einer for-Schleife alle durch 7 teilbaren Zahlenzwischen zwei zuvor eingegebenen Grenzen ausgibt.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int main(void)6 {7 int a, b;8

9 cout << "Untergrenze: "; cin >> a;10 cout << "Obergrenze: "; cin >> b;11

12 for (int i=a; i<=b; i=i+1)13 if (i%7==0) cout << i << " ";14 }

Aufgabe 7

Schreiben Sie ein Programm, das zu einem gegebenen Anfangskapital bei einem vorgegebe-nem jahrlichen Zinssatz berechnet, wie viele Jahre benotigt werden, damit das Kapital einebestimmte Zielsumme uberschreitet.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int main(void)6 {7 int jahre =0;8 double kapital , zins , endkapital;9

10 cout << "Anfangskapital: ";11 cin >> kapital;12 cout << "Zinssatz in %: ";13 cin >> zins;14 cout << "Angestrebtes Endkapital: ";15 cin >> endkapital;16

17

18 while (kapital <endkapital)19 {20 jahre ++;21 kapital += kapital *(zins /100);22 }23

24 cout << "Es dauert " << jahre << " Jahre!" << endl;25 }

Page 5: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 8

Erweitern Sie das in Kapitel 3.3 abgedruckte Programm so, dass ein Schachbrettmuster aufdem Bildschirm erscheint.

I Losung:

1 #include <stdio.h>2

3 int main(void)4 {5 int zeile , n, m;6

7 for (zeile =1; zeile <=4; zeile=zeile +1)8 {9 for (m=1; m<=2; m=m+1)

10 {11 for (n=1; n<=4; n=n+1)12 printf ("*** ");13 printf ("\n");14 }15

16 for (m=1; m<=2; m=m+1)17 {18 for (n=1; n<=4; n=n+1)19 printf (" ***");20 printf ("\n");21 }22 }23 }

Aufgabe 9

Schreiben Sie ein Programm, das das kleine Einmaleins berechnet und in Tabellenform aufdem Bildschirm ausgibt.

I Losung:

1 # include <stdio.h>2

3 int main(void)4 {5 int i,j;6

7 printf (" | 1 2 3 4 5 6 7 8 9 10\n");8

9 printf("---+----------------------------------------\n");10

11 for (i=1; i <=10; i++)12 {13 printf ("%2d | ", i);14 for (j=1; j <=10; j++) printf ("%3d ", i*j);15 printf ("\n");16 }17 }

Page 6: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 10

Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus.Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int main(void)6 {7 int zahl , teiler , limit;8

9 cout << "Obergrenze eingeben: ";10 cin >> limit;11 cout << "\ nPrimzahlen bis " << limit << ":\n";12

13 for (zahl =2; zahl <limit; zahl ++)14 {15 teiler = 2;16 while (zahl%teiler != 0) teiler ++;17 if (teiler == zahl) cout << zahl << " ";18 }19 }

Aufgabe 11

Geben Sie einen’Christbaum‘ durch Ausdruck entsprechend vieler Leerzeichen und Sterne auf

dem Bildschirm aus.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int main(void)6 {7 int blzahl =20, sternzahl=1, i, zeile;8

9 for (zeile =0; zeile <10; zeile ++)10 {11 for (i=0; i<blzahl; i++) cout << ’ ’;12 for (i=0; i<sternzahl; i++) cout << ’*’;13 blzahl --; sternzahl +=2;14 cout << ’\n’;15 }16 }

Page 7: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 12

In unserem Kalender sind zum Ausgleich der astronomischen und kalendarischen Jahreslange inregelmaßigen Abstanden Schaltjahre eingebaut. Zur exakten Festlegung der Schaltjahre dienendie folgenden Regeln:

◦ Ist die Jahreszahl durch 4 teilbar, so ist das Jahr ein Schaltjahr. Diese Regel hat allerdingseine Ausnahme:

◦ Ist die Jahreszahl durch 100 teilbar, so ist das Jahr kein Schaltjahr. Diese Ausnahme hatwiederum 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 einSchaltjahr bezeichnet oder nicht.

I Losung:

1 #include <stdio.h>2

3 int main()4 {5 int jahr;6

7 printf (" Geben Sie ein Jahr ein: ");8 scanf ("%d",&jahr);9

10 if (jahr %4==0)11 if(jahr %100==0)12 if(jahr %400==0)13 printf (" Schaltjahr !\n");14 else15 printf ("Kein Schaltjahr !\n");16 else17 printf (" Schaltjahr !\n");18 else19 printf ("Kein Schaltjahr !\n");20 }

Page 8: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

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 dieeingegebene 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 Losung:

1 #include <stdio.h>2 #include <time.h>3 #include <stdlib.h>4

5 int main(void)6 {7 int zahl , rat , versuche =0;8

9 srand(time(NULL ));10 zahl = rand ()%100 + 1;11

12 do13 {14 printf ("Zahl eingeben: ");15 scanf ("%d", &rat);16 if (rat >zahl) printf ("Zu gross!\n");17 if (rat <zahl) printf ("Zu klein!\n");18 versuche ++;19 }20 while (rat!=zahl && versuche <6);21

22 if (rat==zahl) printf (" Erraten !\n");23 else printf (" Verloren! Die gesuchte Zahl war %d\n", zahl);24 }

Page 9: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 14 (fakultativ)

Losen Sie die quadratische Gleichung ax2 + bx + c = 0 fur vom Benutzer eingegebene Para-meter a, b und c. Falls Ihnen komplexe Zahlen gelaufig sind, sollen auch komplexe Losungenausgegeben werden.

Tipp: Die Losungsformel fur die quadratische Gleichung lautet: x1/2 =−b±

√b2 − 4ac

2a.

Die Funktion float sqrt(float) zur Berechnung der Wurzel einer positiven Zahl ist in math.h deklariert.

Zum Testen des Programms konnen Sie folgende Parametersatze verwenden:

4, -36, 81 → 4.5; 2, 2, -12 → 2, 3; 1, -2, 2 → 1+ −i.

I Losung:

1 #include <iostream >2 #include <math.h>3

4 using namespace std;5

6 int main(void)7 {8 float a,b,c,D; //a*x*x + b*x + c = 09

10 cout << "\ nKoeffizienten a b c: ";11 cin >> a >> b >> c;12

13 D=b*b-4*a*c;14 if (D==0) cout << "x = " << -b/(2*a) << endl;15 if (D>0) cout << "x = " << (-b+sqrt(D))/(2*a) << " und x = "16 << (-b-sqrt(D))/(2*a) << endl;17 if (D<0) cout << "x = " << -b/(2*a) << "+-"18 << sqrt(-D)/(2*a) << "*i" << endl;19 }

Page 10: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 15

Programmieren Sie mithilfe der switch-case Anweisung einen Mini-Taschenrechner, der zweiZahlen und einen Operator (+, -, *, /) einliest und das Ergebnis ausgibt. Eine eventuelleDivision durch 0 soll abgefangen werden.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int main(void)6 {7 float z1,z2;8 char op;9 cout << "2 Zahlen mit Operator dazwischen [+ -*/]: ";

10 cin >> z1 >> op >> z2;11 cout << z1 << op << z2 << "=";12 switch (op)13 {14 case ’+’:15 cout << z1+z2 << ’\n’;16 break;17 case ’-’:18 cout << z1 -z2 << ’\n’;19 break;20 case ’*’:21 cout << z1*z2 << ’\n’;22 break;23 case ’/’:24 if (z2==0)25 cout << " Div durch 0 geht nicht\n";26 else27 cout << z1/z2 << ’\n’;28 break;29 default:30 cout << " Den Operator kenne ich nicht\n";31 }32 }

Page 11: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

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 Bildschirmausgegeben und gleichzeitig alle Vielfachen dieser Zahl im Array auf 0 gesetzt d.h. aus derListe gestrichen. Anschliessend wird die nachste Zahl 6= 0 im Array bearbeitet.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int main(void)6 {7 int a[100] ,i,j;8

9 for (i=0; i <100; i++) a[i]=i;10 cout << "\nDie Ersten Primzahlen ...\n";11 for (i=2; i <100; i++)12 {13 if (a[i]>0)14 {15 cout << a[i] << ’ ’;16 for (j=2*i; j <100; j+=i) a[j]=0;17 }18 }19 }

Page 12: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 17

Lesen Sie eine Integerzahl ein und geben Sie deren Bitmuster aus (z.B.: 23 → 00010111).

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int main(void)6 {7 short int n;8 unsigned short int maske =0x80;9

10 cout << "8-Bit -Integer eingeben: ";11 cin >> n;12 cout << "dezimal: " << n << " binaer: ";13 while (maske)14 {15 if ((n & maske) > 0)16 cout << ’1’;17 else18 cout << ’0’;19 maske >>=1;20 }21 }

Page 13: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 18

Bestimmen Sie die Primfaktorzerlegung einer eingegebenen Zahl (z.B.: 200 = 2*2*2*5*5).

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int main(void)6 {7 int zahl , i, anz=0;8

9 cout << "Gib Integerzahl ein: ";10 cin >> zahl;11 cout << "Zerlegung: ";12 for (i=2; i<=zahl; i++)13 while (zahl%i == 0)14 {15 if (anz ==0)16 cout << i;17 else18 cout << ’*’ << i;19 anz ++;20 zahl/=i;21 }22 }

Page 14: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 19

Sortieren Sie ein mit Zufallszahlen belegtes Array beliebiger Große mit dem Bubble-Sort-Verfahren: jeweils zwei benachbarte Feldelemente werden vertauscht, wenn sie in der falschenReihenfolge sind.

I Losung:

1 #include <iostream >2 #include <stdlib.h>3

4 using namespace std;5

6 int main(void)7 {8 int a[10], i, zw , change;9

10 cout << "unsortiert: ";11 for (i=0; i<10; i++)12 {13 a[i]=rand ()%100;14 cout << a[i] << ’ ’;15 }16

17 // sortieren (und dabei ausgeben ...)18 do19 {20 cout << "\ nZwischenschritt: ";21 change =0; // keine Vertauschung noetig22 for (i=0; i<9; i++)23 if (a[i]>a[i+1])24 {25 zw=a[i]; a[i]=a[i+1]; a[i+1]=zw;26 change =1; // Vertauschung27 }28 for (i=0; i<10; i++) cout << a[i] << ’ ’;29 }30 while (change );31 }

Page 15: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 20

Schreiben Sie ein Sortierprogramm, das nach dem Selection-Sort Algorithmus arbeitet: 1.suche das kleinste/großte Element des Arrays, 2. vertausche dieses mit dem ersten Elementdes Arrays, 3. gehe wieder zu Schritt 1, jetzt aber mit dem verkurzten Array. Wieso ist diesesVerfahren effizienter als Bubble-Sort?

I Losung:

1 #include <iostream >2 #include <stdlib.h>3

4 using namespace std;5

6 int main(void)7 {8 int a[10], i, k, zw , min , stelle;9

10 cout << "unsortiert: ";11 for (i=0; i<10; i++)12 {13 a[i]=rand ()%100;14 cout << a[i] << ’ ’;15 }16

17 for (k=0; k<10; k++)18 {19 cout << "\ nZwischenschritt: ";20 min=a[k];21 stelle=k;22 for (i=k; i<10; i++) /* suche kleinstes Element */23 if (a[i]<min)24 {25 min=a[i];26 stelle=i;27 }28 zw=a[stelle ]; a[stelle ]=a[k]; a[k]=zw;29 for (i=0; i<10; i++) cout << a[i] << ’ ’;30 }31 }

Page 16: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 21 (fakultativ)

Familie Muller ist zu einer Geburtstagsfeier eingeladen. Leider konnen sich die Familienmit-glieder (Anton, Berta, Claus und Doris) nicht einigen, wer hingeht und wer nicht. In einergemeinsamen Diskussion kann man sich jedoch auf die folgenden Grundsatze verstandigen:

◦ 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 Muller, indem Sie ein Programm erstellen, das alle Gruppierungen ermittelt,in denen Familie Muller zur Feier gehen konnte.

Tipp: Erstellen Sie alle denkbaren Kombinationen und prufen Sie jede darauf, ob sie alle obigen Grundsatze

erfullt.

I Losung:

1 # include <stdio.h>2 # include <stdlib.h>3

4 int main(void)5 {6 unsigned char a, b, c, d;7 unsigned char gehen;8 unsigned char z=0;9

10 printf (" Folgende Personen koennen zusammen gehen: \n\n");11

12 /*Dabei heisst z.B. a == 1, dass Anton mitgehen moechte ,*/13 for ( a = 0; a <= 1; a = a + 1)14 for ( b = 0; b <= 1; b = b + 1)15 for ( c = 0; c <= 1; c = c + 1)16 for ( d = 0; d <= 1; d = d + 1)17 {18 //EINE Moeglichkeit der Implementierung19 gehen = ( ( a || b || c || d )20 && ( !d || !a )21 && ( !b || c )22 && ((!(a && c)) || !b)23 && ( a || ( d || c )));24

25 if (gehen == 1)26 {27 printf (" %d. ", z = z+1);28 if (a) printf (" Anton ");29 if (b) printf (" Berta ");30 if (c) printf (" Claus ");31 if (d) printf (" Doris ");32 printf ("\n");33 }34 }35 }

Page 17: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

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 Mittedes Intervalls werden bestimmt. Dann wird das Intervall immer wieder halbiert, bis genugendGenauigkeit 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 Losung:

1 #include <iostream >2 #include <math.h>3

4 using namespace std;5

6 int main(void)7 {8 int i=1; /* Zahl der Iterationen */9 float a,b,c; /* linker und rechter x-Wert , Mitte */

10 float fa,fc; /* Funktionswerte */11

12 cout << "Linke und rechte Grenze: ";13 cin >> a >> b;14

15 do16 {17 c=(a+b)/2.0;18 fa=a*a*a-a*a-a+0.04;19 fc=c*c*c-c*c-c+0.04;20 cout << "Iteriere: Nr="<<i<<"x="<<c<<", f(x)="<<fc <<’\n’;21 if (fc*fa > 0)22 a=c;23 else24 b=c;25 i++;26 }27 while ( (fabs(b-a) > 1e-7) && (i<10) );28

29 }

Page 18: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 23

Freunden Sie sich zunachst einmal mit Unterprogrammen an. Im Skript sind folgende Pro-grammfragmente zu finden:

◦ Berechnung von nm: Funktion mypow

◦ Naherung fur exp(x): Funktion myexp

◦ Einfache Rekursion: Funktion fak

◦ Turme von Hanoi: Funktion hanoi

Machen Sie daraus jeweils ein lauffahiges Programm.

I Losung: (Potenz und Exponentialfunktion)

1 #include <stdio.h>2

3 long int mypow(int n, int m);4 double myexp(double x, int k);5

6 int main(void)7 {8 int n=2, m=10;9 double x=3.0;

10

11 printf ("%d hoch %d ist %ld\n", n, m, mypow(n,m));12 printf ("exp(%lf) ist etwa %lf\n", x, myexp(x, 1000));13 }14

15 long int mypow(int n, int m)16 {17 int i;18 long int erg =1;19

20 for(i=1; i<=m; i++)21 erg*=n;22 return erg;23 }24

25 double myexp(double x, int k)26 {27 int n;28 double summand =1.0, sum =1.0;29

30 for (n=1; n<=k; n++)31 {32 summand *= x/n;33 sum += summand;34 }35 return sum;36 }

Page 19: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

I Losung: (Fakultat, rekursiv)

1 #include <stdio.h>2

3 long fak(int wert);4

5 int main(void)6 {7 int m=10;8

9 printf ("%d! = %ld\n", m, fak(m));10 }11

12 long fak(int wert)13 {14 if (wert ==1) return 1;15 else return (wert*fak(wert -1));16 }

I Losung: (Turme von Hanoi, rekursiv)

1 #include <stdio.h>2

3 void hanoi(int , int , int);4

5 int main(void)6 {7 hanoi (5,1,2);8 }9

10 void hanoi(int n, int p1 , int p2)11 {12 int parkplatz;13

14 if (n>1)15 {16 parkplatz = 6-p1-p2;17 hanoi(n-1, p1, parkplatz );18 }19

20 printf ("1 Scheibe von %d nach %d\n", p1 , p2);21

22 if (n>1) hanoi(n-1, parkplatz , p2);23 }

Page 20: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 24

Schreiben Sie das Programm zur Primzahlzerlegung (Aufgabe 18) so um, dass das Einlesender Zahl von einer Funktion eingabe erledigt wird und die Berechnung und Ausgabe der Prim-faktoren von einer anderen Funktion zerlegung. Uberlegen Sie zuerst, welche Variablentypendie Funktionen erhalten und zuruckliefern sollen!

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int eingabe(void);6 void zerlegung(int zahl);7

8 int main(void)9 {

10 zerlegung(eingabe ());11 }12

13 int eingabe(void)14 {15 int z;16

17 do18 {19 cout << "Gib Integerzahl ein: ";20 cin >> z;21 }22 while (z<2);23

24 return z;25 }26

27 void zerlegung(int zahl)28 {29 int i, anz=0;30

31 cout << zahl << " = ";32 for (i=2; i<=zahl; i++)33 {34 while (zahl%i == 0)35 {36 if (!anz) cout << i;37 else cout << ’*’ << i;38 anz ++;39 zahl/=i;40 }41 }42 }

Page 21: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 25

Erstellen Sie ein Programm zur numerischen Integration einer Funktion mit der Rechtecks-Methode. 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 Flache derRechtecke unter dem Funktionsgraphen berechnet werden und die Gesamtflache zuruckgeliefertwerden.

Tipp: Zum Testen Ihres Programms konnen Sie

∫ 1

0

exp(−x2)dx ≈ 0.746824 benutzen.

I Losung:

1 #include <iostream >2 #include <math.h>3

4 using namespace std;5

6 double f(double x);7 double integral(double a, double b, int n);8

9 int main(void)10 {11 double a,b; int n;12 cout << "Grenze links , rechts und Intervallzahl: ";13 cin >> a >> b >> n;14 cout << "Ergebnis: " << integral(a,b,n) << ’\n’ ;15 return 0;16 }17

18 double f(double x)19 {20 return exp(-x*x);21 }22

23 double integral(double a, double b, int n)24 {25 double flaeche=0,h;26 int i;27

28 h=(b-a)/n;29 for (i=0; i<n; i++)30 flaeche = flaeche + h*f(a+i*h);31 return flaeche;32 }

Page 22: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 26

Schreiben Sie eine Funktion int palin(char *c, int erstes, int letztes), die rekur-siv prufen soll, ob ein gegebenes Wort oder ein Satz ein Palindromi ist. Ihr wird das Wort oderder Satz in einem char-Array c sowie die Stelle des ersten und letzten Zeichens als int uber-geben. Stimmen beide Zeichen uberein, so kann man mit dem Prufen des verkurzten Wortesoder Satzes fortfahren.

Tipp: Die Funktion strlen(text) liefert die Lange des Textes char text[]. Sie ist in string.h deklariert.

Uberlegen Sie sich auch, wie Sie Leerzeichen behandeln (siehe Bsp. in der Fussnote). Beachten Sie bitte die

Schreibweise . . .palin(char *c. . . zur Ubergabe des char-Arrays.

I Losung:

1 #include <stdio.h>2 #include <string.h>3

4 int palin(char*, int , int);5

6 int main(void)7 {8 char wort []=" derfreibierfred ";9 char unwort []=" derfreibiersepp ";

10 char satz []=" Ein Schwarzer mit Gazelle zagt im Regen nie";11

12 if (palin(wort , 0, strlen(wort)-1) == 1)13 printf ("\"%s\" ist ein Palindrom\n", wort);14 else printf ("\"%s\" ist kein Palindrom\n", wort);15

16 if (palin(unwort , 0, strlen(unwort )-1) == 1)17 printf ("\"%s\" ist ein Palindrom\n", unwort );18 else printf ("\"%s\" ist kein Palindrom\n", unwort );19

20 if (palin(satz , 0, strlen(satz)-1) == 1)21 printf ("\"%s\" ist ein Palindrom\n", satz);22 else printf ("\"%s\" ist kein Palindrom\n", satz);23 }24

25 int palin(char *c, int erstes , int letztes)26 {27 while (c[erstes] == ’ ’ && letztes -erstes > 2)28 erstes ++;29 while (c[letztes] == ’ ’ && letztes -erstes > 2)30 letztes --;31 if (!( c[erstes ]==c[letztes]32 || c[erstes ]==c[letztes ]+3233 || c[erstes ]==c[letztes ]-32))34 return 0;35 else36 {37 if (letztes -erstes <= 2)38 return 1;39 return palin(c, erstes+1, letztes -1);40 }41 }

ivorwarts ! ruckwarts z.B.:’anna‘,

’otto‘,

’ein schwarzer mit gazelle zagt im regen nie‘. Danke an dieser Stelle

an Hr. De Muirier von der DLR, der mich darauf hingewiesen hat, dass das im Original-Palindrom verwendete Wortheutzutage

”rassistisch und stark pejorativ ist“. (Zitat)

Page 23: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 27

Das Treppenproblem: Sie konnen bei einer Treppe entweder genau eine Stufe pro Schrittnehmen, oder, falls sie sportlich und durchtrainiert sind, 2 Stufen auf einmal. Damit haben siemehrere Moglichkeiten eine mehrstufige Treppe zu uberwinden (z.B.: 1 Stufe→ 1 Moglichkeit,2 Stufen → 2 Moglichkeiten, 3 Stufen → 3 Moglichkeiten, 4 Stufen → 5 Moglichkeiten, . . .).Schreiben Sie ein Programm, welches Ihnen rekursiv die Anzahl der Moglichkeiten berechnet,eine Treppe T mit n Stufen zu erklimmen:

Tn =

{n fur n < 3T(n−1) + T(n−2) fur n ≥ 3

Berechnen Sie dann die Anzahl der Moglichkeiten fur n=25. Wieso und wie mussen Sie ihrProgramm modifizieren, damit dieses auch die Anzahl der Moglichkeiten fur n=768 (UlmerMunster) und n=1860 (Empire State Building) berechnen kann?

Tipp: Bei der Treppe zur Physik-Bibliothek (n=25) haben Sie 121.393 Moglichkeiten, beim Ulmer Munster

etwa 23 x 10159 Moglichkeiten und beim Empire State Building immerhin etwa 37 x 10387 Moglichkeiten.

I Losung: (rekursiv)

1 #include <stdio.h>2

3 int treppe(int);4

5 int main(void)6 {7 int stufen;8

9 printf ("\n\nAnzahl der Stufen ?: ");10 scanf ("%d", &stufen );11 printf ("Bei %d Stufen haben Sie %d Moeglichkeiten\n",12 stufen , treppe(stufen ));13 }14

15 int treppe(int stufen)16 {17 if(stufen <= 2)18 return stufen;19 else20 return treppe(stufen -1) + treppe(stufen -2);21 }

I Losung: (additiv)

1 #include <stdio.h>2

3 void treppe(int);4

5 int main(void)6 {7 int stufen;8

9 printf ("\n\nAnzahl der Stufen ?: ");10 scanf ("%d", &stufen );11 printf ("Bei %d Stufen haben Sie ", stufen );12 treppe(stufen );13 printf (" Moeglichkeiten ");14 }15

16 void treppe(int stufen)17 {

Page 24: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

18 int letztes [1000] , vletztes [1000] , ergebnis [1000];19 int result=0, carry =0;20 int z, index , lastindex =999, treffer =0;21

22 for(z=0; z <1000; z++)23 vletztes[z]= letztes[z]= ergebnis[z]=0;24

25 letztes [0]=2;26 vletztes [0]=1;27

28 if(stufen < 3)29 ergebnis [0] = stufen;30

31 while (stufen -- > 2)32 {33 for(z=0; z <1000; z++)34 {35 result = vletztes[z] + letztes[z] + carry;36 if(result >= 10)37 {38 ergebnis[z] = result - 10;39 carry = 1;40 }41 else42 {43 ergebnis[z] = result;44 carry = 0;45 }46 }47

48 for(z=0; z <1000; z++)49 {50 vletztes[z] = letztes[z];51 letztes[z] = ergebnis[z];52 }53 }54

55 while (treffer != 1)56 if (ergebnis[lastindex] == 0)57 lastindex --;58 else59 treffer = 1;60 index = lastindex;61 while (index >= 0)62 {63 if (index != 0 && index % 3 == 0)64 printf ("%d.",ergebnis[index --]);65 else66 printf ("%d",ergebnis[index --]);67 }68 if (lastindex >= 9)69 printf (" (=%d,%de%d)", ergebnis[lastindex],70 ergebnis[lastindex - 1],71 lastindex );72 }

Page 25: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 28 (fakultativ)

Zur Berechnung der Wurzel einer Zahl gibt es ein rekursives Verfahren. Die Rekursionsformellautet:

w(n, x) =

{12

[w(n− 1, x) + x

w(n−1,x)

]fur n ≥ 1

1 fur n = 0

Schreiben Sie eine Funktion double wurzel(int n, double x), die rekursiv die Wurzeleiner eingegebenen Zahl x berechnet. Die Zahl n gibt die Rekursionstiefe an. Vergleichen Siedas Ergebnis mit dem exakten Wert.

I Losung:

1 #include <stdio.h>2 #include <math.h>3

4 double wurzel(int n, double x)5 {6 if (n==0) return 1;7 else return 0.5*( wurzel(n-1, x)+x/wurzel(n-1, x));8 }9

10 int main(void)11 {12 double x;13 int n;14

15 printf ("Zahl eingeben: ");16 scanf ("%lf", &x);17 printf (" Anzahl der Rekursionen: ");18 scanf ("%d", &n);19 printf ("Die Wurzel von %f ist etwa %1.12f, exakt %1.12f\n",20 x, wurzel(n, x), sqrt(x));21 }

Page 26: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 29

Man berechne fur kleine ganze Zahlen m,n (m ≤ 3, n ≤ 8) die Ackermann-Funktion a(m,n):

a(m,n) :=

n+ 1 falls m = 0a(m− 1, 1) falls n = 0a(m− 1, a(m,n− 1)) sonst

Tipp: Zum Testen Ihres Programms konnen Sie a(1, 1) = 3, a(3, 3) = 61, a(3, 8) = 2045 benutzen.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int acker(int m, int n);6

7 int main(void)8 {9 int a,b;

10

11 cout << "2 Zahlen: ";12 cin >> a >> b;13 cout << "a(" << a << ", " << b << ") = "14 << acker(a,b) << endl;15 }16

17 int acker(int m, int n)18 {19 if (m==0) return n+1;20 else21 {22 if (n==0) return acker(m-1,1);23 else return acker(m-1, acker(m,n -1));24 }25 }

Page 27: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 30

Erstellen Sie ein Programm mit einer Struktur namens person, die einige Daten (Name,Vorname, Alter, Schuhgroße,. . .) einer Person speichert. Eine Funktion eingabe soll einenDatensatz einlesen und zuruckliefern. Das Programm soll dann mithilfe von eingabe die Datenzweier Personen aufnehmen und den Namen des Alteren ausgeben.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 typedef struct6 {7 char name [20], vname [20];8 int alter , schuhgroesse;9 }person;

10

11 person einlesen(void);12

13 int main(void)14 {15 person p1 , p2;16

17 p1 = einlesen ();18 cout << endl;19 p2 = einlesen ();20

21 if (p1.alter > p2.alter)22 cout << p1.vname << " " << p1.name23 << " ist der aeltere ." << endl;24 else25 cout << p2.vname << " " << p2.name26 << " koennte der aeltere sein." << endl;27 }28

29 person einlesen(void)30 {31 person p;32

33 cout << "Vorname: ";34 cin >> p.vname;35 cout << "Name: ";36 cin >> p.name;37 cout << "Alter: ";38 cin >> p.alter;39 cout << "Schuhgroesse: ";40 cin >> p.schuhgroesse;41

42 return p;43 }

Page 28: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 31

Im Sript finden Sie ein Beispielprogramm zur Dateibearbeitung. Versuchen Sie, es zu verstehen,und experimentieren Sie damit.

I Losung:

Hier hilft nun wirklich nur noch lesen, verstehen und abtippen!

Fur die Losungen der Aufgaben 32–34 werden die folgenden Textdateien im jeweils aktuellenVerzeichnis vorausgesetzt:demo.txt

1 Hallo , das ist eine Testdatei!2 Hier steht die zweite Zeile.3 Und schon ist ’s wieder zu Ende ...

text.txt

1 In diesem Text sind2 viel zu viele Leerzeichen3 vorhanden ,4 die entfernt werden muessen.

Aufgabe 32

Erstellen Sie ein Programm, das einen Text aus einer Datei einliest und auf dem Bildschirmausgibt, wobei Groß- in Kleinbuchstaben verwandelt werden sollen und umgekehrt.

I Losung:

1 #include <iostream >2 #include <fstream >3

4 using namespace std;5

6 int main(void)7 {8 char c;9 ifstream datei;

10

11 datei.open("demo.txt", ios::in);12 if (! datei)13 {14 cout << "Datei nicht gefunden !\n";15 return 1;16 }17

18 while (datei.get(c))19 {20 if (c>=’a’ && c<=’z’) c=c+(’A’-’a’);21 else if (c>=’A’ && c<=’Z’) c=c-(’A’-’a’);22 cout << c;23 }24 datei.close ();25 }

Page 29: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 33

Schreiben Sie ein Programm, das einen Text aus einer Datei und einen Buchstaben einliestund ermittelt, wie oft der Buchstabe in dem Text vorkommt.

I Losung:

1 #include <iostream >2 #include <fstream >3

4 using namespace std;5

6 int main(void)7 {8 char c, buchst;9 int anzahl =0;

10 ifstream datei;11

12 cout << "Zeichen eingeben: ";13 cin >> buchst;14

15 cout << "Der Text\n";16

17 datei.open("demo.txt", ios::in);18 while(datei.get(c))19 {20 if (c== buchst) anzahl ++;21 cout << c;22 }23 datei.close ();24 cout << "\ nenthaelt " << anzahl << "mal das Zeichen "25 << buchst << endl;26 }

Aufgabe 34

Schreiben Sie ein Programm, das aus einem Text in einer Datei alle mehrfach vorkommendenLeerzeichen entfernt und den Text auf dem Bildschirm ausgibt.

I Losung:

1 #include <iostream >2 #include <fstream >3

4 using namespace std;5

6 int main(void)7 {8 char c, voriges=’a’;9 ifstream datei;

10

11 datei.open("text.txt", ios::in);12

13 while (datei.get(c))14 {15 if (!( voriges==’ ’ && c==’ ’))16 cout << c;17 voriges=c;18 }19 datei.close ();20 }

Page 30: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 35

Es ist feld ein int-Array und p ein int-Zeiger. Welche der folgenden Zuweisungen sindzulassig, welche nicht? (Ggf. ausprobieren!)

◦ p = feld;

◦ feld = p;

◦ p = &feld[3];

◦ feld[2] = p[5];

I Losung:

Alle Zuweisungen sind zulassig ausser der Zweiten da feld eine Zeigerkonstante ist und dieAdresse der Elemente enthalt, welche durch die Definition von feld reserviert wurden. DieseAdresse kann nicht geandert werden. Der Zeigervariablen p durfen beliebige Adressen zuge-wiesen werden. Die erste und dritte Zuweisung sind daher korrekt, weil auch die Ausdrucke zurBerechnung 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, wasformal richtig ist.

Aufgabe 36

Es seien p1 und p2 zwei int-Zeiger und i eine int-Variable. Welche Zuweisungen wird derCompiler akzeptieren, welche nicht? (Ggf. ausprobieren!)

◦ p1 = p2 + i;

◦ p1 = i + p2;

◦ i = p1 * p2;

◦ i = p1 - p2;

◦ i = p1 + p2;

I Losung:

Die erste Zuweisung wird vom Compiler akzeptiert. Hier wird zu einer Adresse eine ganzeZahl addiert. Das Resultat ist ein um einen konstanten Wert (i*sizeof(int)) verschobenerZeiger. Die meisten Compiler akzeptieren auch die zweite Zuweisung, da das Vertauschen derOperanden bei

’+‘durchaus erlaubt ist. Die dritte Zuweisung ist volliger Blodsinn. Bei der

vierten Zuweisung wird die Entfernung der Elemente (in sizeof(int)) ermittelt, auf die dieZeigervariablen p1 und p2 zeigen. Die letzte Zuweisung ist wiederum keine sinnvolle Operation.

Page 31: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 37

Schreiben Sie ein bestehendes Programm (z.B. Losung der quadratischen Gleichung) so um,dass die Benutzereingabe von einer Funktion eingabe erledigt wird, der man die Variablenubergeben muss (Pointer!).

I Losung:

1 #include <iostream >2 #include <math.h>3

4 using namespace std;5

6 void eingabe(double*, double*, double *);7

8 int main(void)9 {

10 double a,b,c,D;11

12 eingabe (&a, &b, &c);13 D=b*b-4*a*c;14 if (D==0) cout << "x = " << -b/(2*a) << endl;15 if (D>0) cout << "x = " << (-b+sqrt(D))/(2*a)16 << " und x = " << (-b-sqrt(D))/(2*a) << endl;17 if (D<0) cout << "x = " << -b/(2*a) << "+-"18 << sqrt(-D)/(2*a) << "*i" << endl;19 }20

21 void eingabe(double *a, double *b, double *c)22 {23 cout << "Die Parameter a, b und c eingeben: ";24 cin >> *a >> *b >> *c;25 }

Page 32: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 38

Schreiben Sie eine Funktion stringlength, an die ein char-Array ubergeben wird, und diedie Lange dieser Zeichenkette zuruckliefert.

Tipp: Das Ende einer Zeichenkette ist durch ’\0’ (ASCII: 0) gekennzeichnet.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int stringlength(char *w);6

7 int main(void)8 {9 char wort [50];

10

11 cout << "Wort eingeben: ";12 cin >> wort;13 cout << "Das Wort " << wort <<" hat "14 << stringlength(wort) << " Zeichen ." << endl;15 }16

17 int stringlength(char *w)18 {19 int i=0;20

21 while (w[i]!=’\0’) i++;22 return i;23 }

Page 33: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 39

Der Benutzer soll ein Wort und ein Zeichen eingeben. Es soll das Wort, das um dieses Zeichenverlangert worden ist, ausgegeben werden (z.B.: Hall + o→ Hallo). Verwenden Sie dazu dievorher (Aufgabe 38) definierte Funktion stringlength, um die Stelle des letzten Zeichenszu ermitteln.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 int strlen(char *w);6

7 int main(void)8 {9 char wort [50], c;

10 int j,l;11

12 cout << "Wort eingeben: ";13 cin >> wort;14 cout << "Buchstaben eingeben: ";15 cin >> c;16

17 l=stringlength(wort);18 wort[l]=c;19 wort[l+1]= ’\0 ’;20 cout << wort << endl;21 }22

23 int stringlength(char *w)24 {25 int i=0;26

27 while (w[i]!=’\0’) i++;28 return i;29 }

Page 34: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 40

Schreiben Sie das Bubble-Sort-Programm (Aufgabe 19) so um, dass das Sortieren in einerFunktion geschieht, der man den Zeiger auf das Array ubergibt.

I Losung:

1 #include <iostream >2 #include <stdlib.h>3

4 using namespace std;5

6 void sortiere(int *);7

8 int main(void)9 {

10 int a[10], i;11

12 cout << "\ nUnsortiertes Array: \n";13 for (i=0; i<10; i++)14 {15 a[i]=rand ()%100;16 cout << a[i] << " ";17 }18 sortiere(a);19 cout << "\ nSortiertes Array: \n";20 for (i=0; i<10; i++)21 cout << a[i] << " ";22 cout << endl;23 }24

25 void sortiere(int *x)26 {27 int i, ablage , change;28

29 do30 {31 change = 0;32 for (i=0; i<9; i++)33 if (x[i]>x[i+1])34 {35 ablage=x[i];36 x[i]=x[i+1];37 x[i+1]= ablage;38 change = 1;39 }40 }41 while (change );42 }

Page 35: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 41

Schreiben Sie ein Programm, das eine Funktion prosumo enthalt. Dieser Funktion wird einVektor ubergeben; sie liefert die Summe und das Produkt der Vektorelemente zuruck.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 void prosumo(int , float*, float*, float *);6

7 int main(void)8 {9 float f[]={1.0 ,2.0 ,3.0 ,7.0} ,ergp ,ergs;

10

11 prosumo(4,f,&ergp ,&ergs);12 cout << "Produkt: " << ergp13 << ", Summe: " << ergs << ’\n’ ;14 }15

16 void prosumo(int n, float *F, float *x, float *y)17 {18 int i; *x=1.0; *y=0.0;19 for (i=0; i<n; i++)20 {21 *x*=F[i];22 *y+=F[i];23 }24 }

Page 36: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 42

Schreiben Sie das Integrations-Programm (Aufgabe 25) so um, dass die zu integrierende Funk-tion f(x) der Funktion integral als Pointer ubergeben wird.

I Losung:

1 #include <iostream >2 #include <math.h>3

4 using namespace std;5

6 double gauss(double x);7 double parabel(double x);8 double integral(double (*)( double), double , double , int);9

10 int main(void)11 {12 double a,b;13 int n;14

15 cout << "Grenze oben , unten und Intervallzahl: ";16 cin >> a >> b >> n;17 cout << "Ergebnis (Gauss): "18 << integral(gauss ,a,b,n) << ’\n’;19 cout << "Ergebnis (Parabel ): "20 << integral(parabel ,a,b,n) << ’\n’;21

22 return 0;23 }24

25 double gauss(double x)26 {27 return exp(-x*x);28 }29

30 double parabel(double x)31 {32 return x*x;33 }34

35 double integral(double (*f)( double x), double a, double b, int n)36 {37 double flaeche=0,h;38 int i;39

40 h=(b-a)/n;41 for (i=0; i<n; i++)42 flaeche = flaeche + h*f(a+i*h+h/2);43 return flaeche;44 }

Page 37: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 43

Erzeugen Sie dynamisch Speicherplatz fur n double-Zahlen, lesen Sie sie ein und bestimmenSie das Maximum und die Summe. Wie sieht die Speicheralloziierung in reinem C und in C++aus?

I Losung: (ANSI-C)

1 #include <stdio.h>2 #include <stdlib.h>3

4

5 int main(void)6 {7 int SIZE , i;8 float *v, sum , *max;9

10 printf (" Laenge des Vekors eingeben: ");11 scanf ("%d",&SIZE);12

13 v = (float*) malloc(SIZE*sizeof(float ));14

15 if (v == NULL) return 1;16

17 printf ("%d Float -Zahlen eingeben: ", SIZE);18 for (i=0; i<SIZE; i++)19 scanf ("%f", v+i);20

21 max = v;22 sum = 0.0;23

24 for (i=0; i<SIZE; i++)25 {26 sum += v[i];27 if (v[i] > *max) max = v+i;28 }29

30 printf ("\ nSumme: %f, Maximum: %f\n", sum , *max);31

32 free(v);33 }

I Losung: (C++)

1 #include <iostream >2

3 using namespace std;4

5 int main(void)6 {7 int SIZE , i;8 float *v, sum , *max;9

10 cout << "Laenge des Vekors eingeben: ";11 cin >> SIZE;12

13 v = new float[SIZE];14

15 if (v == NULL) return 1;16

17 cout << SIZE << " Float -Zahlen eingeben: ";18 for (i=0; i<SIZE; i++)19 cin >> v[i];20

Page 38: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

21 max = v;22 sum = 0.0;23

24 for (i=0; i<SIZE; i++)25 {26 sum += v[i];27 if (v[i] > *max) max = v+i;28 }29

30 cout << "Summe: " << sum << ", Maximum: "31 << *max << endl;32

33 delete v;34 }

Page 39: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 44

Erstellen Sie eine Funktion zur Sortierung eines Arrays von int-Zahlen. Ubergeben Sie derSortierfunktion als Parameter eine Funktion zum Vergleich zweier Zahlen. Erzeugen Sie unter-schiedliche Sortierungen (aufsteigend, absteigend, nach letzter Ziffer, nach der Quersumme,. . .),indem Sie unterschiedliche Vergleichsfunktionen an die Sortierfunktion ubergeben.

I Losung:

1 #include <iostream >2

3 using namespace std;4

5 void Ausgabe(int *);6

7 int auf(const int , const int);8 int ab(const int , const int);9 int lziffer(const int , const int);

10 int rueckw(const int , const int);11 int qsumme(const int , const int);12

13 void sort(int*, int , int (*)( const int , const int ));14

15 int main(void)16 {17 int Zahlen []={10 ,5 ,78 ,3 ,34 ,76 ,33 ,1352 ,56 ,85};18

19 cout << "Unsortiertes Array:\n";20 Ausgabe(Zahlen );21 sort(Zahlen , 10, auf);22 cout << "aufsteigend sortiert :\n";23 Ausgabe(Zahlen );24 sort(Zahlen , 10, ab);25 cout << "absteigend sortiert :\n";26 Ausgabe(Zahlen );27 sort(Zahlen , 10, lziffer );28 cout << "nach letzter Ziffer sortiert :\n";29 Ausgabe(Zahlen );30 sort(Zahlen , 10, qsumme );31 cout << "nach der Quersumme sortiert :\n";32 Ausgabe(Zahlen );33 }34

35 void Ausgabe(int *z)36 {37 for (int i=0; i<10; i++) cout << z[i] << " ";38 cout << endl << endl;39 }40

41 void sort(int *z, int size , int (*comp)( const int , const int))42 {43 int ablage;44

45 for(int i=0; i<size -1; i++)46 for(int j=i+1; j<size; j++)47 {48 if (comp(z[i],z[j])==0)49 {50 ablage=z[i];51 z[i]=z[j];52 z[j]= ablage;53 }54 }

Page 40: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

55 }56

57

58 int auf(const int a, const int b)59 {60 if (a<b) return 1;61 else return 0;62 }63

64 int ab(const int a, const int b)65 {66 if (a>b) return 1;67 else return 0;68 }69

70 int lziffer(const int a, const int b)71 {72 if (a%10 < b%10) return 1;73 else return 0;74 }75

76 int qsumme(const int a, const int b)77 {78 int x=0, y=0, z;79 z=a;80 while (z!=0)81 {82 x+=z%10;83 z=z/10;84 }85 z=b;86 while (z!=0)87 {88 y+=z%10;89 z=z/10;90 }91 if(x<y) return 1;92 else return 0;93 }

Page 41: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

Aufgabe 45

Schreiben Sie ein Programm zur Verwaltung einer verketteten Liste. Als’Nutzinhalt‘der Liste

wahlen Sie eine char-Variable, in der Sie genau ein Zeichen speichern konnen. Fullen Sie dieKette in einer Funktion fangan mit den Kleinbuchstaben des Alphabets. Mit einer Funktiongibaus konnen 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-malden Buchstaben ’X’ einfugt. Vergessen Sie nicht eine Funktion loesche zu implementieren, mitder Teile der Liste geloscht werden konnen. Eine weitere Ausbaumoglichkeit ist eine Funktionersetze, 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 droseln Sie Element fur Element und Pointer

fur Pointer auf. Vergessen Sie dabei nicht, dass auch Pointervariablen ganz einfache, lokale Variablen sein

konnen. . .

I Losung:

1 #include <iostream >2 #include <stdlib.h>3 #include <string.h>4

5 using namespace std;6

7 typedef struct slink8 {9 char zeichen;

10 struct slink *next;11 } link;12

13 link* fangan(void);14 void gibaus(link *);15 void fuegein(link*, int , int , char);16 void loesche(link*, int , int);17 void ersetze(link*, char *);18

19 int main(void)20 {21 link *anfang;22

23 cout <<"Unser Alphabet als verkettete Liste ...\n";24 gibaus(anfang=fangan ());25 cout <<"\n\nFuege 5 ’X’ nach der 8. Stelle ein\n";26 fuegein(anfang , 8, 5, ’X’);27 gibaus(anfang );28 cout <<"\n\nLoesche 10 Zeichen nach der 7. Stelle\n";29 loesche(anfang , 7, 10);30 gibaus(anfang );31 cout <<"\n\nErsetze a,e,u,v,w,z durch Grossbuchstaben\n";32 ersetze(anfang , "aeuvwz ");33 gibaus(anfang );34

35 delete(anfang );36 }37

38

39 link* fangan(void)40 {41 link *anfang , *kette , *hilf;

iioder Espresso, je nach Tageszeit

Page 42: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

42

43 if (!( anfang = kette = new link))44 exit (1);45 anfang ->zeichen = ’a’;46 anfang ->next = NULL;47

48 for(int i=1; i <=25; i++)49 {50 if (!( hilf=new link))51 exit (1);52 hilf ->zeichen = ’a’+i;53 hilf ->next = NULL;54 kette ->next = hilf;55 kette = hilf;56 }57

58 return anfang;59 }60

61 void gibaus(link *kette)62 {63 cout << "Inhalt der Kette: ";64 while(kette != NULL)65 {66 cout << kette ->zeichen;67 kette = kette ->next;68 }69 }70

71 void fuegein(link *kette , int stelle , int anzahl , char zeichen)72 {73 link *hilf , *next;74

75 for(int i=1; i<stelle; i++)76 {77 if(kette ->next==NULL)78 break;79 kette=kette ->next;80 }81 next=kette ->next;82

83 for(int j=1; j<= anzahl; j++)84 {85 if (!( hilf=new link))86 exit (1);87 hilf ->zeichen = zeichen;88 hilf ->next = next;89 kette ->next = hilf;90 kette = hilf;91 }92 }93

94 void loesche(link *kette , int stelle , int anzahl)95 {96 link *hilf;97 if(stelle < 2)98 return;99

100 for(int i=1; i<stelle; i++)101 {102 if(kette ->next==NULL)103 break;104 kette=kette ->next;

Page 43: L osungen zu den Aufgaben des C/C++ Kurses 10 Geben Sie alle Primzahlen zwischen 2 und einer vom Benutzer einzugebenen Obergrenze aus. Bestimmen Sie die Primzahlen mittels Ganzzahldivision.

105 }106

107 for(int j=1; j<= anzahl; j++)108 {109 hilf = kette ->next;110 if(hilf==NULL)111 break;112 kette ->next = kette ->next ->next;113 delete(hilf);114 }115 }116

117 void ersetze(link *kette , char *zeichen)118 {119 while(kette != NULL)120 {121 for(int i=0; i<strlen(zeichen ); i++)122 if(kette ->zeichen == zeichen[i])123 kette ->zeichen -=32;124 kette = kette ->next;125 }126 }

D. Schuh et al. August 2015 �