5

Click here to load reader

Blatt1neu_56324

  • Upload
    rudiali

  • View
    66

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Blatt1neu_56324

Labor Informatik 2 Beck, Dausmann, Warendorf

Blatt 1 Seite 1 Version 1.1 vom 10.3.2006

Blatt 1 Programme aus mehreren Dateien, Speicherklassen

Aufgabe 1.1 Programme aus mehreren Dateien.

Schreiben Sie ein Programm, welches 2 float-Zahlen a und b mit der Funktioneinlesen()einliest, und dann mit der Funktion average() den Durchschnitt, mit derFunktion quotient() den Quotienten, mit der Funktion produkt() das Produkt, mit derFunktion summe() die Summe und mit der Funktion differ()die Differenz berechnet. AlleFunktionen sollen in main() aufgerufen werden. Jede Funktion steht in einer eigenen Datei.Der Dateiname bildet sich aus dem jeweiligen Funktionsnamen und der Endung .c .

Die Zahl a soll eine globale Variable sein und in der Datei main.c definiert sein. Die Zahl bsoll über die Parameterliste übergeben werden. Die Ergebnisse der arithmetischenOperationen sollen bei average(), quotient() und produkt() über die Parameterliste,bei summe() und differ() als Rückgabewert übergeben werden.

Hier die Datei main.c:#include <stdio.h>extern void einlesen (float *, float *);extern void average (float, float *);extern void quotient (float, float *);extern void produkt (float, float *);extern float summe (float);extern float differ (float);

float a;

int main (void){ float b; float mittel, quot, prod, summ, diff;

einlesen (&a, &b); average (b, &mittel); quotient (b, &quot); produkt (b, &prod);

summ = summe (b); diff = differ (b); printf ("\n a = %6.2f, b = %6.2f", a,b); printf ("\n der Mittelwert von a und b ist %6.2f", mittel); printf ("\n das Produkt a*b ist %6.2f", prod); printf ("\n der Quotient a/b ist %6.2f", quot); printf ("\n die Summe a + b ist %6.2f", summ); printf ("\n die Differenz ist %6.2f", diff); return 0;}

Page 2: Blatt1neu_56324

Labor Informatik 2 Beck, Dausmann, Warendorf

Blatt 1 Seite 2 Version 1.1 vom 10.3.2006

Aufgabe 1.2 Statische lokale Variablen

Schreiben Sie ein Programm aus den Funktionen main(), eingabe() und zaehl-routine(). Die Funktion eingabe() soll einen ganzzahligen Wert N einlesen und an dasHauptprogramm übergeben (über die Parameterliste, nicht über globale Variablen). DasHauptprogramm soll in einer Schleife die Funktion zaehlroutine() N-mal aufrufen.

Die Funktion zaehlroutine() soll mitzählen, wie oft sie aufgerufen wurde und soll beijedem Aufruf in die Datei ZAEHL.TXT mit Hilfe von fprintf() ausgeben:

function zaehlroutine() wurde jetzt zum x-ten Mal aufgerufen.

Dabei muss x der aktuellen Anzahl der Aufrufe entsprechen.

Hinweis: Wenn Sie als Dateiname bei der Funktion fopen() einen String wie etwa"ZAEHL.TXT" angeben, wird die Datei im aktuellen Arbeitsverzeichnis abgelegt. Was dasgerade ist, hängt davon ab, wie Sie Ihr Programm starten, welche Entwicklungsumgebung Siebenutzen, etc. Suchen Sie die Datei mit dem Windows-Explorer, damit Sie wissen, wo solcheDateien abgelegt werden.

Aufgabe 1.3 Modularisierung, Headerdateien

Schreiben Sie ein Programm, das von der Standardeingabe zeichenweise einliest und prüft, oballe darin vorkommenden Klammern - also (), [] und {} -paarig und richtig geschachtelt sind.Da die Klammern beliebig tief geschachtelt sein können, benötigt man zur Lösung derAufgabe einen Stack. Dieser Stack ist als eigenes Modul mit Header- und C-Datei zurealisieren.

Ein Stack (von Zeichen) benötigt mindestens folgende Funktionen void push(char) undchar pop() zum Ablegen bzw. Abholen eines Zeichens (hier einer Klammer). Darüberhinaus sind nützliche Funktionen: int is_empty() und void reset() um zu prüfen, obder Stack leer ist bzw. um ihn ggf. komplett zu leeren. Einen Stack kann man mit Hilfe einesArrays realisieren, die Anzahl der Elemente ist dann fest als Konstante vorgegeben.Stackoverflow (push bei vollem Stack) und Stackunderflow (pop bei leerem Stack) führen zueiner Fehlermeldung und Programmabbruch. Der Stackpointer ist ein Index für dieses Array,der auf das nächste freie Element zeigt. Bei leerem Stack hat der Stackpointer den Wert 0.

Die Prüfung der Klammerung funktioniert mit diesem Stack folgendermaßen: Jede öffnendeKlammer wird auf den Stack gelegt. Trifft man auf eine schließende Klammer in der Eingabe,darf der Stack nicht leer sein und als oberstes Zeichen muss auf dem Stack die entsprechendeöffnende Klammer sein. Am Ende der Eingabe (EOF) muss auch der Stack leer sein.

Hinweis zur zeichenweise Eingabe:

Der einfachste Eingabemechanismus besteht darin, ein einzelnes Zeichen von derStandard-Eingabe, normalerweise von der Tastatur, mit Hilfe von getchar() zu lesen.

Page 3: Blatt1neu_56324

Labor Informatik 2 Beck, Dausmann, Warendorf

Blatt 1 Seite 3 Version 1.1 vom 10.3.2006

Die Syntax von getchar() ist:

int getchar (void)

getchar() dient zum Einlesen einzelner Zeichen von der Standardeingabe (in derRegel der Tastatur). Die Standardeingabe ist zeilengepuffert, d.h. getchar() wartet,bis eine Zeile mit der Return-Taste abgeschlossen wird. Der Rückgabewert ist nichtvom Typ char, sondern vom Typ int.

Beispiel:

int c;

/* hiermit wird c das eingelesene Zeichen zugewiesen */c = getchar ();

Tritt ein Fehler auf oder wird das Dateiende erreicht, so liefert getchar() den WertEOF. EOF ist eine ganze Zahl, die in <stdio.h> vereinbart ist und steht für "End OfFile". Die Variable c ist vom Typ int. Damit kann c auch negative Werte aufnehmen.Die Konstante EOF hat in der Regel den Wert -1. Wird von der DOS-Eingabeaufforderung aus per Tastatur eingegeben (das ist für Sie bis jetzt derNormalfall, da Sie Console-Projekte anlegen) so kann EOF durch das Eingeben vonStrg-Z mit anschließender Eingabe eines Wagenrücklaufes (Return-Zeichen) in einereinzelnen Zeile eingegeben werden. Generell ist es so, dass getchar() erst dann einZeichen an c zuweist, wenn Return-Zeichen eingegeben wird. Erst dann werden allebisher in der Zeile eingegebenen Zeichen, einschließlich des Return-Zeichens ('\n'),in einem Tastaturpuffer abgelegt, aus dem dann mit jedem Aufruf von c =getchar() ein weiteres Zeichen (von links nach rechts) entnommen wird, bis derTastaturpuffer geleert ist. Dann wird wieder gewartet, bis eine Zeile, beendet durch einReturn, eingegeben wird.

Der eigentliche Hintergrund von EOF ist der: Es wird dann zugewiesen, wenn aus einerDatei gelesen wird und man beim Lesen an deren Ende angekommen ist. Ende derDatei eben. Das können Sie testen, in dem Sie Ihr Programm nicht aus derProgrammierumgebung heraus aufrufen sondern aus einer DOS-Eingabeaufforderung,die man mit "Start.Programme.DOS-Eingabeaufforderung" startet. Dort gehenSie zunächst auf das Z-Laufwerk und dann mit dem mit dem cd Befehl (changedirectory) in das Verzeichnis, in dem Ihr Programm steht:

z:

cd inf2\cc\bl1afg13\Debug

Dort können Sie – wenn Sie Aufgabe 1.3d fertig haben – zum Beispiel prüfen, ob dieKlammerung Ihrer C-Datei korrekt ist:

bl1afg13.exe < ..\bl1afg13.c

Page 4: Blatt1neu_56324

Labor Informatik 2 Beck, Dausmann, Warendorf

Blatt 1 Seite 4 Version 1.1 vom 10.3.2006

Dabei steht "<" für die Eingabeumleitung. Das heißt, Ihr Programm erwartet dieEingabe nicht mehr von der Tastatur, sondern von der Datei ..\bl1afg13.c. DieseDatei hat – wie jede andere Datei auch – das EOF an ihrem Ende.

a) Machen Sie sich zuerst anhand eines Bildes die Arbeitsweise des Stacks klar.

b) Zu erstellen sind die Dateien main.c, stack.h und stack.c. Welche Reihenfolgewählen Sie?

c) Programmieren Sie die Dateien main.c, stack.h und stack.c unter Beachtung derKriterien der Datenkapselung und des Information Hidings. Nutzen Sie in stack.c dieMöglichkeiten des Präprozessors zur Fehlermeldung und geben Sie außerdem dieFehlermeldung auf die Standardfehlerausgabe aus.

e) Testen Sie Ihr Programm wie gewohnt über die Standardeingabe.

f) Nutzen Sie den Hinweis und testen Sie nun Ihr Programm an verschiedenen Dateien,beispielsweise auch an C-Dateien. Ggf. ist beim Testen noch eine weitere Funktion imStackmodul hilfreich: print() zur Ausgabe des kompletten Stackinhalts.

Aufgabe 1.4 Modularisierung

a) Schreiben Sie eine Funktion zum Einlesen eines Integer-Arrays. Gegeben ist der folgendeunvollständige Prototyp:

/* Ein Integer-Array einlesen: */void scanArray( max, /* Maximale Anzahl Elemente in array (stets >0)*/ array, /* Zu fuellende Reihung */ n /* Anzahl der Elemente in Reihung */ );

Die Funktion scanArray() soll wie folgt einlesen: Es werden int-Werte von der Tastatureingelesen, bis entweder das Array komplett gefüllt ist (also max Elemente eingelesen sind)oder bis über die Tastatur etwas eingegeben wird, was scanf() nicht mit demFormatelement %i einlesen kann (erkennbar am Rückgabewert von scanf()).Beispielsweise kann die Eingabe des Buchstabens q zu einem solchen Verhalten führen. DieFunktion scanArray() gibt über den Parameter n die Anzahl der tasächlich gefülltenElemente des Arrays zurück (Anzahl korrekt gelesener Zahlen oder max).

b) Schreiben Sie eine Funktion zur Ausgabe eines Integer-Arrays (je 8 Zahlen auf eine Zeile,pro Zahl 6 Stellen). Gegeben ist der folgende unvollständige Prototyp:

Page 5: Blatt1neu_56324

Labor Informatik 2 Beck, Dausmann, Warendorf

Blatt 1 Seite 5 Version 1.1 vom 10.3.2006

/* Ein Integer-Array ausgeben: */void printArray( array, /* Zu druckende Reihung */ n /* Anzahl der Elemente in Reihung */ );

c) Schreiben Sie eine weitere Funktion fillArray() mit gleichem Parameterprofil wiescanArray, die das Array mit Zufallszahlen füllt. Der Parameter der die aktuelle Zahl dergefüllten Elemente angibt, soll hier ebenfalls durch den Zufallsgenerator bestimmt werden.Diese Zahl muss zwischen 0 und dem Parameter max liegen!

Hinweis: Ein Zufallsgenerator ist implementiert durch die Funktion rand() aus derBibliothek stdlib.h. Initialisiert wird dieser Zufallsgenerator durch die Funktionsrand(). Damit bei jeder Neuinitialisierung der Zufallsgenerator eine andere Zahlenfolgeliefert, wird er am besten jedesmal anders initialisiert. Dies geschieht am einfachsten mit deraktuellen Zeit. Die aktuelle Zeit liefert die Funktion time() aus der Bibliothek time.h.Lesen Sie die Hilfen zu diesen Funktionen durch, dort finden Sie auch Beispiele für dieAnwendung. Beachten Sie auch das Intervall, in dem die Zufallszahlen liegen: ggf. müssenSie die Ergebnisse von rand() noch Ihrer Anwendung anpassen!

d) Schreiben Sie ein Hauptprogramm, das ein Array mit Elementen füllt (mit scanArray()),es anschließend ausgibt, den Mittelwert berechnet und auch diesen ausgibt. Überlegen Sieeine nützliche Modularisierung der Funktionen. Erstellen Sie Header- und C-Dateien.

e) Ersetzen Sie in Ihrem Hauptprogramm den Aufruf von scanArray() durch den Aufrufvon fillArray() und testen Sie so auch diese Funktion.

Aufgabe 1.5 Schnittstellenvergleich

Vergleichen Sie die Lösungen der Aufgaben 1.3 und 1.4. Die Tatsache, dass in einem Fall einchar-Array im anderen Falle ein int-Array bearbeitet wird, ist hier unerheblich. Wobefinden sich die Daten? Erklären Sie die Unterschiede in den Parameterprofilen.