Programmier-Kurs "C" Teil 2

Im ersten Teil haben Sie den grundsätzlichen Aufbau eines C-Programms kennengelernt. Sie haben die Ausgabefunktion printf() und die Eingabefunktion scanf() in verschiedenen Programmen eingesetzt und haben dazu zwei wichtige Variablentypen, den Integer und den String bzw. Char, benutzt.

Ich hoffe, dass Sie die sechs Aufgaben am Schluß des Kurses lösen konnten. Wenn es Probleme gab, finden Sie auf der Spezial-Disk dieser Ausgabe im Ordner C_KURS\AUFGABEN.TL1 alle Lösungen des ersten Teils. Da in der letzten ATARI-Inside im Listingblock leider der Tabulator verrutscht ist, finden Sie im Ordner C-KURS\BElSPIEL.TL1 alle Listings noch einmal. Alle Dateien sind als Code und als lauffähiges TOS-Programm vorhanden. Sicherlich ist es Ihnen aufgefallen, dass in den Rechenprogrammen bei der Eingabe von sehr großen Zahlen in einigen Fällen kein richtiges Ergebnis auf dem Bildschirm ausgegeben wurde. Wie ich beschrieben habe, ist der Wertebereich der Integer auf die Ganzzahlen von -32768 bis 32767 beschränkt. Alles, was darunter oder darüber liegt muss zu Rechenfehlern führen, weil der zugeteilte Speicherplatz nicht mehr ausreicht. Weiterhin verlangte die letzte Aufgabe die Eingabe von Pfennigbeträgen. Da ein Integer keine Kommastellen berechnen kann, ist die Ein- und Ausgabe von DM-Beträgen natürlich nicht möglich. Deshalb gibt es noch weitere Datentypen: die Fließkomma- oder auch Realzahlen. Sie werden als "float" definiert. Das Besondere an diesem Datentyp ist nicht nur das Komma, sondern auch die höhere Wertigkeit. Diese geht von "3,4 hoch -38" bis "3.4 hoch 38". Das entspricht der Zahl 34 zzgl. achtunddreißig nullen! Vorerst sollte damit die oben beschriebene Tatsache behoben sein. Wenn Sie Ihre Programme umstellen wollen, beachten Sie unbedingt, dass in der Eingabe und Ausgabefunktion statt "%i" nun "%f" stehen muss.

Praxis

Tippen Sie nun das Listing 1 ein. Als float sind drei Variablen angemeldet, und in "prinff()" und "scanf()" steht jeweils "%f".
Weiterhin ist die Headerdatei "ext.h" neu. Hierdurch werden u.a. die Funktionen "getch()" und "putch()" mit eingebunden. Mit diesen Funktionen wird jeweils nur ein Zeichen eingelesen bzw. ausgegeben, ohne dass die Returntaste betätigt werden muss. Beachten Sie, dass ein Komma in einer Fließkommazahl als Punkt angegeben wird. Alles Weitere in diesem Listing sollte für Sie verständlich sein.

Lassen Sie das Programm laufen und beachten Sie die Ausgabe. Hinter dem Komma bzw. dem Punkt stehen sechs Stellen. Die Ausgabe der Nachkommastellen kann einfach formatiert werden. Durch Verwendung eines Punktes und einer Zahl werden die Stellen hinter dem Komma definiert. "%.2f" z.B. bedeutet zwei Stellen hinter dem Komma. Die Angabe "%4.lf" formatiert auch vor dem Komma. In diesem Fall ist die Ausgabe auf vier Stellen vor und eine Stelle nach dem Komma begrenzt. Versuchen Sie das Listing so abzuändern, dass die erste Ausgabe eine Stelle, die zweite zwei, die dritte vier und die letzte acht Stellen hinter dem Komma anzeigt.

Wenn alles läuft, tippen Sie das Listing 2 ab. Dieses sinnvolle Programm zeigt, wie int und float miteinander koordinieren können.

Sicher ist es Ihnen lästig geworden, dass die Programme nur einmal durchlaufen und dann erst wieder neu übersetzt werden müssen. Abhilfe schafft eine sogenannte Schleife, die eine Abbruchbedingung aufweist. Die "do-while-Schleife" wird in jedem Fall mindestens einmal durchlaufen. Am Schluß fragt sie ab, ob sie wiederholen oder abbrechen soll. Das Listing 3 zeigt, wie diese funktioniert.

Zu Beginn steht das Schlüsselwort "do". (Ein Schlüsselwort beschreibt eine feste Bedeutung für den Compiler). Gleich danach steht eine sich öffnende und am Ende eine schließende geschweifte Klammer. Alles was dazwischen steht, wird so lange wiederholt, wie das, was in den Klammern von "whileQ" steht, stimmt. Im Programm fragen wir "}while( ende !='q' )". Um das zu verstehen, muss man erst einmal wissen, was "!=" bedeutet.
Um zwei Werte miteinander zu vergleichen, gibt es beispielsweise:
"==" diese zwei Zeichen fragen nach "ist gleich?", "!=" das Ausrufungszeichen verneint eine Frage, heißt also "ist nicht gleich?". Wenn wir also ein "a" eingegeben haben, fragt while: "entspricht a nicht q?". "Ja, es stimmt", ist die richtige Antwort, und die Schleife beginnt von vorn. Geben wir ein "q" ein, fragt while: "entspricht q nicht q?". Die Antwort ist: "Nein, stimmt nicht, q ist gleich q" und die Schleife bricht ab.
Dieser Abfragevorgang muss erst einmal richtig verdaut werden, damit Fehler später vermieden werden. Wichtig ist aber auch, dass Verwechslungen mit dem einfachen (Werte zuweisen bzw. in eine Variable übergeben) vermieden werden müssen. Es sind zwei vollkommen verschiedene Dinge. Damit der Compiler zwischen Zahlen (zum Rechnen) und Zeichen unterscheiden kann, müssen Zeichen immer in Hochkomma angegeben werden. Ab jetzt können alle Programme von Ihnen so lange durchlaufen werden, wie Sie wollen.
Um alles zu verdeutlichen und zu üben, versuchen Sie (ohne auf auf das Listing 4 zu sehen) eine weitere Schleife in die Schleife einzubauen, die genau bis 10 zählen und ausgeben kann. Dazu eine wichtige Tastenkombination: Control-C bricht das laufende Programm ab. Beim Ausprobieren kann es schnell passieren, dass sich eine Schleife nicht beenden lässt und sich endlos wiederholt. Wenn Sie das geschafft haben, haben Sie einen großen Stolperstein aus dem Weg geräumt. Wichtig ist, dass die Variable (ich habe sie "zahl" genannt) vor jedem neuen Durchlauf auf 0 gesetzt wird und dann erst die neue Schleife beginnt. Sonst gibt es eine Warnung, denn es kann sein, dass zufällig eine nicht gewünschte Zahl in dieser Speicherstelle steht. Um sicher zu gehen, müssen solche Variablen immer auf einen Anfangswert gesetzt werden.

Das Listing 5 sollten Sie erst einmal mit dem Zeigefinger Zeile für Zeile durchgehen und versuchen zu verstehen, wie diese drei Schleifen funktionieren und sich die Inhalte der einzelnen Variablen ändern. Neu ist nur die Zeile, in der alle drei Integer gleichzeitig auf 0 ge setzt werden. Dann tippen Sie es ab und übersetzen es. Es werden 100 Zahlen in einem 10 mal 10-Block ausgegeben.

Das erste "richtige Programm"

Hat alles geklappt? Dann können wir ja endlich ein "richtiges" Programm schreiben. Dazu brauchen wir erst einmal eine Problemstellung. Diese ist z. B.: Sie sind Immobilienvermittler und müssen von verschiedenen Wohnungen die Quadratmetergröße errechnen. Die Daten, die Sie haben, sind Anzahl der Zimmer und deren Größe. Das Programm muss also fragen, wie viele Zimmer die zu berechnende Wohnung hat und dann die Länge und Breite der einzelnen Zimmer abfragen. Daß alle nötigen Werte eingegeben worden sind, soll das Programm selbständig erkennen und danach die Größe der gesamten Wohnung ausgeben. Natürlich muss es auch fragen, ob eine weitere Wohnung berechnet werden soll.

Sehen Sie sich das Listing 6 an. Es werden alle drei bisher bekannten Variablen verwendet. Sie müssen also nun besonders auf "%i" und "%f" und die Formatierung achten. Leider versteht C keine Umlaute (hier also "ä"), so dass aus dem Variablennamen "länge" leider "laenge" werden muss. Sicherheitshalber werden wieder zu Beginn alle Variablen auf 0 gesetzt. Dann wird die Anzahl der Zimmer abgefragt und in die Variable "zimmer" geschrieben. Die Schleife beginnt, und die nächste Zeile zeigt etwas Neues. "anzahl ++" bedeutet, dass die Variable um "1" erhöht wird. "anzahl = anzahl +1" bewirkt die gleiche Ausführung. Nun fragt das Programm nacheinander die Länge und Breite vom 1. Zimmer ab, denn "anzahl" steht auf "1". Es wird die Zimmergröße berechnet und in die Variable qm_gesamt geschrieben. Die Ausgabe über die Größe des Zimmers ist als Kontrolle gedacht. Jetzt kommt die entscheidende Abfrage. In "anzahl" steht "1" und in "zimmer" vielleicht "5". Die beiden Zahlen sind also nicht identisch und die Schleife beginnt von vorn. "anzahl" bekommt den Wert "2", und das 2. Zimmer kann eingegeben werden. Sind nacheinander alle Zimmer berechnet, steht in "anzahl" und "zimmer" derselbe Wert, und die Schleife wird beendet. Als Letztes wird der Wert, der in "qm_gesamt" gesammelt worden ist, ausgegeben.

So einfach ist das Programmieren. Ob Sie alles verstanden haben, können Sie selbst an den folgenden Aufgaben herausfinden. Denken Sie an die Tastenkombination "Control-C", denn sicherlich wird das eine oder andere Programm beim Testen etwas anderes ausgeben, als Sie sich erhofft haben.

Aufgaben

Aufgabe 1

Schreiben Sie das Programm der sechsten Aufgabe des ersten Kursteils so um, dass die Eingabe mit DM-Beträgen läuft. Die gefahrenen Kilometer sollen auf eine Stelle Genauigkeit und die verfahrenen Liter auf zwei Stellen hinter dem Komma ausgegeben werden.

Aufgabe 2

Schreiben Sie das Programm so um, dass zu Beginn einmalig Vorname, Autotyp und dessen Verbrauch eingegeben werden können und die Anzahl der zu berechnenden Tage, der Spritpreis und die jeweils täglich gefahrenen km wiederholend abgefragen und ausgegeben werden. Die abschließende Ausgabe soll lauten:
"Lieber Xxx, Du bist mit Deinem Xxx an Xx Tagen gefahren und hast dabei Du Xxx km zurückge legt. Das hat Dir, lieber Xxx zusammen Xxx.Xx DM gekostet. Xxx willst Du eine weitere Rech-nung von mir erstellen lassen? Drücke [beliebige Taste] für Ja oder [n] für Nein!"

Aufgabe 3

Ein Programm, dass folgende Ausgabe macht: 0123456789
123456789
23456789 usw.,
bis nur eine 9 auf der Zeile steht

Aufgabe 4

Ein Programm, dass die Fakultät von einer eingegebenen ganzen Zahl errechnet. Also: eine Eingabe von 3 wird 123 errechnet, und es wird als Ergebnis 6 ausgegeben.

Aufgabe 5

Erweitern Sie das Listing 6 dahingehend, dass nach jeder Eingabe eines Zimmers eine Kontrollausgabe gemacht wird: "Das X. Zimmer hat eine Größe von Xxx.Xx qm." "Bis jetzt kommen Xxxx.Xx qm zusammen."

Aufgabe 6

Sie haben als Immobilienmakler das Problem, dass einige Kunden kommen, die gleich mehrere verschiedene Wohnungen kaufen wollen. Sie haben aber nur die Größe der einzelnen Zimmer. Das Programm fragt also: "Wie viele Wohnungen sollen berechnet werden?" "Wie viele Zimmer hat die X. Wohnung?" usw.. Die Abschlußausgabe: "Die X Wohnungen haben zusammen Xx Zimmer mit zusammen XXXX.Xx qm." "Weitere Berechnung?" "[j] für Ja oder [beliebige Taste] für Nein!"

Zugegeben - die letzte Aufgabe ist nicht leicht. Nur nicht aufgeben! In der nächsten "ATARI inside" sind die Auflösungen wieder auf der Diskette zum vergleichen.

Download Listing 1 (0,8KB)
Download Listing 6 (1,3KB)


/* Listing 2*/

#include <stdio.h>
#include <ext.h>

main() {
int dollar;
flost kurs ,auszahlung;

printf("\nKleines Währungs-Programm\n\n"); 
printf("\nGeben Sie den heutigen Dollar-Kurs ein: "); 
scanf("%f", &kurs);
printf("\nWieviel Dollar vollen Sie kaufen?");
scanf ("%i", &dollar);

auszahlung = dollar * kurs;

printf("\nDer aktuelle Kurs ist %.3f.", kurs); 
printf("\n%i Dollar kosten heute %.2f DN.\n",dollar,auszahlung);

getch();
return 0;


/* Listing 3 */

#include <stdio.h>
#include <ext.h>

main() {
char ende;

printf("\nDie do-while schleife"):

do{                     /* Beginn der Schleife */
printf("\n\nDas Programm befindet sich in der Schleife\n');
printf("Mit Taste q werden Schleife und Programm beendet!\n");
ende=getch();
putch(ende);            /* Ausgabe eines Zeichens */
}while( ende !='q' );   /* Ende der Schleife */
                        /* != heisst "nicht g1eich" */
printf('\nDie Schleife wurde abgebrochen");
return 0;



/* Listing 4*/

#include <stdio.h>
#include <ext.h>

main() {
   char ende;
   int zahl;

printf ("\nDas ist das Program, das schon bis 10 zählen kann\n\n");
   do{
   /* Wertzuweisung eines Anfangswertes*/
     zahl=0;

     do{
       /* Zahl wird um 1 erhöht zugewiesen */
       zahl = zahl + 1;
       printf( "\n %i", zahl ); /* und ausgegeben */
     }while( zahl != 10);   /* solange Zahl nicht 10 entspricht */

printf("\n\nWollen Sie das Programm beenden? Drücken Sie q t\n"); 
     ende=getch();
  }while( ende !='q' );
  printf("\nDas Programm wurde beendet");
  return 0;
}
/* Listing 5*/

#include <stdio.h>
#include <ext.h>

main() {
   char ende;
   int zahl, spalte, zeile;

   printf("\nDas ist des Programm, das schon bis 100 zählen kann\n\n");

do{
  zahl = spalte = zeile = 0; /* Wertzuweisung von drei Variablen */
  do{
    zeile = zeile + 1;
	/* muss nach eines Durchlauf wieder 0 sein */
    spalte = 0;
    do{
      zahl = zahl + 1;
      spalte = spalte + 1;
      printf( " %3i", zahl ); /* ausgegeben ohne \n in 3 Stellen  */
   }while( spalte != 10 );    /* solange spalte nicht 10 entspricht*/
    printf( "\n" );            /* neue Zeile	*/
   }while( zeile != 10 );        /* solange zeile nicht 10 entspricht */

 printf("\n\nWollen Sie das Prograsse beenden? Drücken Sie q !\n\n"); 
 ende=getch();
  }while( ende !='q' );
  printf("\nDas Programm wurde beendet");
  return 0;
}

Klaus Sommer
Aus: Atari Inside 05 / 1996, Seite 43

Links

Copyright-Bestimmungen: siehe Über diese Seite