1 Lösungen Kapitel 1 Aufgabe 1.1: Nassi-Shneiderman-Diagramm quadratzahlen Vervollständigen Sie das unten angegebene Nassi-Shneiderman-Diagramm für ein Programm, welches in einer (äußeren) Schleife Integer-Zahlen in eine Variable n einliest. Ist die eingelesene Zahl n größer als Null, so soll ausgegeben werden: Zahl Quadratzahl 1 1 2 4...... n n*n Ist die eingelesene Zahl n kleiner als Null, so soll ausgegeben werden: Negative Zahl Ist die eingegebene Integer-Zahl n gleich Null, so soll das Programm die äußere Schleife abbrechen. quadratzahlen TRUE solange n!= 0 i = 0 Ausgabe von Zahl Quadratzahl solange i <= n Ausgabe von i Ausgabe von i * i i = i +1 einlesen n > 0? TRUE Ausgabe Negative Zahl FALSE n < 0? FALSE
2 Lösungen Kapitel 5 Aufgabe 5.1: Initialisierung von lokalen Variablen Erstellen Sie ein Programm, in dem jeweils eine lokale Variable der Typen int, float, double, short, long und char definiert, aber nicht initialisiert wird. Geben Sie den Inhalt der Variablen aus. Beobachten Sie das Ergebnis und beantworten Sie, weshalb Variablen immer initialisiert werden sollten. Nichtinitialisierte Variablen besitzen einen undefinierten Wert. Aufgabe 5.2: Initialisierung von globalen Variablen Ändern Sie das vorherige Programm, indem Sie die lokalen Variablen zu globalen machen. Beobachten Sie erneut das Ergebnis. Was ist festzustellen? Der Wert der Variablen ist immer 0.
3 Lösungen Kapitel 6 Aufgabe 6.2: Arrays a) Überlegen Sie, was das folgende Programm ausgibt. Überzeugen Sie sich durch einen Programmlauf. int i, ar [100]; printf ("\n\n\n"); for (i = 0; i < 100; i = i + 1) ar[i] = 1; ar[11] = -5; ar[12] = ar[12] + 1; ar[13] = ar[0] + ar[11] + 4; for (i = 10; i <= 14; i = i + 1) printf ("ar[%2d] = %4d\n", i, ar[i]); Ausgabe: ar[10]= 1 ar[11]= -5 ar[12]= 2 ar[13]= 0 ar[14]= 1
4 Lösungen Kapitel 7 Aufgabe 7.6: Der Subtraktions-Zuweisungsoperator Erläutern Sie, was das folgende Programm tut. Überzeugen Sie sich durch einen Programmlauf. int a; int b; printf ("Gib zwei ganze positive Zahlen ein: "); scanf ("%d %d", &a, &b); while (a >= b) a -= b; printf ("\n??????? ist : %d\n", a); Es wird a modulo b (in C-Notation: a % b) berechnet. Aufgabe 7.8: Gebrauch verschiedener Operatoren Gegeben sei: int a = 2, b = 1; /* Diese Anweisungen sind Grundlage */ int * ptr = &b; /* fuer jede der Aufgaben a) bis o) */ Finden Sie ohne C-Compiler heraus, welcher Wert der Variablen a in den einzelnen Anweisungen a) bis o) zugewiesen wird. Beachten Sie dabei genau die Priorität der entsprechenden Operatoren. Erläutern Sie, wie Sie auf das Ergebnis kommen. Verifizieren Sie ihr theoretisch ermitteltes Ergebnis gegebenenfalls durch einen Programmlauf. a) a = b = 2; b) a = 5 * 3 + 2; c) a = 5 * ( 3 + 2); d) a *= 5 + 5; e) a %= 2 * 3; f) a =!(--b == 0); g) a = 0 && 0 + 2; h) a = b++ * 2; i) a = - 5-5; j) a = -(+b++); k) a = 5 == 5 && 0 1; l) a = (((((( b + b) * 2) + b) && b b )) == b); m) a = b? 5-3 : b; n) a = 5 ** ptr; o) a = b + (++b);
Einführung in Pointer und Arrays 5 Ergebnis: a) a = 2 b) a = 17 c) a = 25 d) a = 20 e) a = 2 f) a = 0 g) a = 0 h) a = 2 i) a = -10 j) a = -1 k) a = 1 l) a = 1 m) a = 2 n) a = 5 o) a = 4
6 Lösungen Kapitel 9 Aufgabe 9.1: Blöcke Welche Zahlenwerte werden von dem folgenden Programm ausgegeben? Analysieren Sie das Programm und ersetzen Sie die? in der im Folgenden dargestellten Ausgabe durch die entsprechenden Ausgabewerte. Starten Sie das Programm erst nach Ihrer Analyse. main - der Wert von x ist? f2 - der Wert von x ist? f1 - der Wert von x ist? main - der Wert von x ist? Hier das Programm: int x = 5; void f1 (int * u) int x = 4; *u = 6; printf ("\nf1 void f2 (int x) printf ("\nf2 - der Wert von x ist %d", x); - der Wert von x ist %d", x); printf ("\n\nmain - der Wert von x ist %d", x); f2 (7); f1 (&x); printf ("\nmain - der Wert von x ist %d", x); Die Ausgabe ist: main - der Wert von x ist 5 f2 - der Wert von x ist 7 f1 - der Wert von x ist 4 main - der Wert von x ist 6
Lösungen Kapitel 6 7 Aufgabe 9.2: Rekursion Welche Ausgabe erwarten Sie von dem folgenden Programm, wenn Sie 123<RETURN> eingeben. Was wird auf dem Stack abgelegt? Testen Sie anschließend das Programm. void spiegle (void) int c; c = getchar(); /* Einlesen eines Zeichens */ if (c!= '\n') spiegle(); /* Rekursiver Aufruf, falls c!= '\n' putchar(c); /* Ausgabe eines Zeichens printf ("\n\n\n"); spiegle(); Die Ausgabe ist: 321 3 2 Stack 1
8 Lösungen Kapitel 10 Aufgabe 10.4: Pointer und Arrays bei Zeichenketten Ergänzte Teile sind fett markiert /* strcpy1(): t nach s kopieren; Version mit Vektorindex */ void strcpy1 (char * s, char * t) int i = 0; while ((s[i] = t [i])!= '\0') i++; /* Anmerkung: das i-te Element von t wird an das i-te Element von */ /* s zugewiesen. Dann wird geprueft, ob der Inhalt dieses */ /* Elementes gleich '\0' ist. Solange diese Bedingung nicht */ /* erfuellt ist, wird i hochgezaehlt. */ /* strcpy2(): t nach s kopieren; Version mit Pointern */ void strcpy2 (char * s, char * t) while ((*s = *t)!= '\0') s++; t++; /* Anmerkung: in der Bedingung wird nun das Objekt, auf das */ /* der Pointer s und der Pointer t zeigt, verwendet. Uebergeben */ /* wird beim Aufruf der Pointer auf das 0-te Element. Das 0-te */ /* Element von t wird nun an das 0-te Element von s zugewiesen, */ /* und es wird ueberprueft, ob das Element gleich '\0'ist. Ist */ /* dies nicht der Fall, so werden die Pointer s und t jeweils um */ /* 1 erhoeht. Aufgabe 10.9: Zeichenketten aneinander fügen a) Warum darf der Anwender Ihres Programms keine beliebig lange Zeichenkette eingeben? Fehlende Feldgrenzenüberwachung führte zum Überschreiben anderer Variablen.
9 Lösungen Kapitel 14 Aufgabe 14.7: Dateien, Strukturen und Arrays a) Wozu dienen die zwei Typ-Attribute const beim zweiten Parameter? Der erste const stellt sicher, dass keine Änderungen an dem Artikel art vorgenommen werden können. Der zweite const stellt sicher, dass der Zeiger nicht in der Funktion verschoben/geändert wird und somit ein falscher Artikel ausgegeben wird. b) Wie kann mit Hilfe des sizeof-operators das gefährliche Festlegen der Anzahl der Elemente im Array a durch die literale Konstante 3 vermieden werden? artikel_printarray(stdout, a, sizeof(a)/sizeof(artikeltyp) );
10 Lösungen Kapitel 16 Aufgabe 16.1: malloc() Überlegen Sie sich, was die folgenden Programme durchführen. Machen Sie im Anschluss an Ihre Überlegungen einen Probelauf. c) #include <stdlib.h> #include <string.h> void pointer_auf_int (void); printf ("\nhier ist main"); pointer_auf_int(); void pointer_auf_int (void) int * ptr; ptr = malloc (sizeof(int)); *ptr = 3; printf ("\nder Wert des Objektes *ptr ist %d", (*ptr)); Ein int-objekt wird auf dem Heap angelegt und initialisiert. d) #include <stdlib.h> #include <string.h> void pointer_auf_record (void); struct struktur int recordnummer; char inhalt[10]; ; printf ("\nhier ist main"); pointer_auf_record(); void pointer_auf_record (void)
Lösungen Kapitel 16 11 struct struktur * ptr; ptr = malloc (sizeof(struct struktur)); ptr->recordnummer = 3; strcpy (ptr->inhalt, "hallo"); printf ("\ndie Recordnummer ist %d", (*ptr).recordnummer); printf ("\nder Inhalt ist %s", ptr->inhalt); Eine Strukturvariable wird auf dem Heap angelegt und initialisiert.