Adok's Way to C
Teil 2

+++ Einleitung +++

Hallo und herzlich willkommen zur zweiten Folge meines C-Kurses!  Diesmal geht
es,  wie  bereits  in  der  letzten  Folge  angekndigt, um Variablen und ihre
Brderchen und Schwesterleins.

+++ Datentypen +++

In C gibt es nur wenige Datentypen, und zwar:

 signed short int: Das  short  kann in  Real-Mode-DOS auch weggelassen werden.
                   Bei  short int handelt es sich um Ganzzahlen von -32768 bis
                   +32767. Der Datentyp belegt 16 Bit.
 signed long int:  Das  long  kann in  32-Bit-Betriebssystemen wie Windows und
                   den  aktuellen  UNIX-Versionen  sowie in Protected-Mode-DOS
                   auch  weggelassen  werden. Eine  Variable  dieses Typs kann
                   ganze Zahlen von -2147483648 bis einschlielich +2147483647
                   enthalten. Dafr belegt sie aber auch 32 Bit.
 signed char:      Eigentlich auch eine Integervariable, die von -128 bis +127
                   reicht  und dafr auch nur 8  Bit belegt. Aber sie hat noch
                   andere  Bedeutungen!  (Dieses  Geheimnis  werden  wir  BALD
                   lften...)

UNTERBRECHUNG!  Eine wichtige Meldung zu  den Integer-Datentypen: Es gibt auch
"unsigned"-Datentypen,  und  zwar unsigned short,  unsigned  long und unsigned
char.   Diese  verbrauchen  genauso  viel  Speicherplatz,  knnen  aber  keine
negativen Werte darstellen. Dafr sind sie in der positiven "Richtung" doppelt
so  lang!  Beispielsweise reicht ein unsigned short  von  0 bis 65535. Und nun
weiter...

 float:        Fliekommazahlen mit 8 Stellen Genauigkeit. Belegt 32 Bit.
 double:       Fliekommazahlen mit 15 Stellen Genauigkeit. Belegt 64 Bit.

Wie  ihr seht, hat C nur sehr wenige Datentypen! Nicht einmal ein Datentyp fr
Zeichenketten  (Strings)  ist  vorhanden! Das  hat  einen einfachen Grund: Der
Computer selbst kennt ja auch keine Strings. Wozu gibt es denn den ASCII-Code?
Richtig,  damit der Computer die  Zeichen in Integer-Variablen speichern kann!
Diejenigen,  die die Zeichen erkennen,  sind erst die Textausgaberoutinen. Sie
sehen nach, welches Zeichen zu dem ASCII-Code gehrt, und geben es dann aus.

Habt  ihr schon berlegt, warum der Datentyp char so heit, wie er heit? Ganz
einfach:  Er  kann  genau 256 Werte annehmen  (signed  char von -128 bis +127,
unsigned char von 0 bis 255), und der von PCs verwendete ASCII-Code codiert ja
auch 256 verscheidene Zeichen. Somit eignet sich ein unsigned char bestens zur
Speicherung  von Zeichen. Und Strings erhlt man einfach durch einen Array von
char-Variablen.  Ich  sehe,  ihr seid ganz hei  auf  das Thema, ja, ihr wollt
schon  mit  Strings herumjonglieren... doch STOP!  Zuerst mu ich euch zeigen,
wie man Variablen definiert!

+++ Variablendefinitionen +++

Eine Variablendefinition sieht so aus:

 Typ Bezeichner;

Mehr  nicht!  Um  eine unsigned-char-Variable  namens  zeichen  zu definieren,
schreibt man also einfach:

 unsigned char zeichen;

Wenn  man mehrere Variablen von ein und demselben Datentyp definieren will, so
kann man auch die Variablennamen durch Beistriche trennen. Statt

 int multiplikand;
 int multiplikator;
 int produkt;

tippt man dann

 int multiplikand, multiplikator, produkt;

Da  C  eine  formatfreie  Sprache ist und  man  an  beliebigen Stellen - auer
natrlich  in  Strings  oder  Bezeichnern  -  Leerzeichen  und  Zeilenumbrche
einfgen kann, geht es auch bersichtlicher:

 int multiplikand,
     multiplikator,
     produkt;

Auerdem ist es mglich, Variablen bei ihrer Definition auch Werte zuzuweisen.
Etwa so:

 int multiplikand=99,
     multiplikator=111,
     produkt=0;           /* Hm, neunundneunzig mal einhundertelf macht...
                             hhh... :-) */

+++ Zuweisung +++

Die Zuweisung erfolgt in C mit dem Operator =. Beispiel:

 var=10;

Damit wird der Variablen var der Wert 10 zugewiesen.

Bei Variablen des Integer-Stamms gibt es noch eine zweite Mglichkeit:

 var='C';

Damit  wird  der  Variablen  var der  ASCII-Code  des  Zeichens  C zugewiesen.
Familir ausgedrckt, kann man sagen: Ein einzelnes Zeichen mu in C immer von
zwei   Hochkommas  bedrngt  werden,  damit   diese  den  ASCII-Code  aus  ihm
'rausquetschen.

Eine Eigenheit von C liegt darin, da die Zuweisung ein Operator ist, genau so
wie + oder -. Genauso, wie man

 a=b+c;

schreiben kann, kann man also auch

 a=b=c;

schreiben.  Damit  wird der Variablen b der  Inhalt  von c zugewiesen, und der
Variablen  a  wird das Ergebnis der  Zuweisung zugewiesen. Und dieses Ergebnis
ist...  nichts anderes als... der Inhalt der  Variablen c! Wir merken uns: Das
Ergebnis  einer  Zuweisung  ist immer der  Wert,  der rechts von der Zuweisung
steht. Wir htten also auch Folgendes schreiben knnen:

 b=c;
 a=b;

Wir  wollen uns als Nchstes mit Strings beschftigen und auf diese Weise auch
die  Funktionsweise  von Arrays erlutern. Dazu  aber  wre es recht ntzlich,
einige wichtige Funktionen fr die Ein-/Ausgabe von Zeichen zu kennen.

+++ getch +++

Diese  Funktion wurde bereits in Teil 1 ausreichend besprochen; was folgt, ist
deshalb   nur  Wiederholung.  Um  das   Programm  zu  veranlassen,  auf  einen
Tastendruck des Benutzers zu warten, schreiben wir:

 getch();

Wollen  wir  den  ASCII-Code  des Zeichens,  das  der  Benutzer eingab, zwecks
Weiterverarbeitung in der Variablen zeichen speichern, schreiben wir:

 zeichen=getch();

zeichen sollte den Datentyp char haben.

+++ putchar +++

putchar,  in stdio.h deklariert, dient zur  Ausgabe eines Zeichens. Dieses mu
als Parameter angegeben werden.

+++ Beispielprogram: getch und putchar +++

 // getch und putchar

 #include <stdio.h>
 #include <conio.h>

 void main(void)
 {
   char zeichen;

   printf("Gib ein Zeichen ein! ");
   zeichen=getch();
   printf("\nDu gabst folgendes Zeichen ein: ");
   putchar(zeichen);
   printf("\n");
 }

Der Vollstndigkeit halber noch zwei verwandte Funktionen aus stdio.h:

+++ getc +++

getc   funktioniert  genauso  wie  getch,  nur   wartet  es  nicht  auf  einen
Tastendruck,  sondern  fragt den Tastaturpuffer  direkt  ab. Wenn dieser nicht
leer  ist,  gibt getc den aktuellen  Wert  im Tastaturpuffers zurck, ohne den
Tastaturpuffer zu ndern.

+++ getchar +++

getchar  ist beinahe identisch mit getch. Aber zustzlich wird die Eingabe auf
dem  Bildschirm angezeigt, und der Benutzer  mu sie mit ENTER besttigen. Fr
die Praxis ist getchar meines Ermessens nach eher von geringer Bedeutung.

+++ Arrays und Strings +++

Arrays  sind  Felder,  also  eine endliche  Anzahl  von  Variablen,  die unter
demselben  Bezeichner zusammengefat sind. In  C wird ein Array folgendermaen
definiert:

 Typ Bezeichner[Anzahl_Elemente];

Beispiel:

 int a[3];

definiert  einen Array vom Datentyp int mit drei Elementen. Auf diese Elemente
kann  in  Zuweisungen,  arithmetischen  Operationen  und Funktionsaufrufen als
a[0], a[1] und a[2] zugegriffen werden. Ein Beispiel:

 a[0] = 3;
 a[1] = a[0] + 2;

weist a[0] den Wert 3 und anschlieend a[1] den Wert 3 + 2, also 5, zu.

Strings  sind nichts anderes als Arrays vom Typ char - mit einer Besonderheit:
Ihr  letztes Element ist das Null-Byte, in  C auch '\0' geschrieben. Man nennt
diese Strings deshalb auch nullterminiert. Die Nullterminierung ist notwendig,
damit  die  Stringbearbeitungsfunktionen das Ende  des  Strings erkennen. Denn
tatschlich kennt keine Funktion die Anzahl der Elemente eines Arrays, der ihr
als  Parameter  bergeben  wird  - auer,  man  gibt  diese als einen weiteren
Parameter extra an.

Um  einen String mit dem Namen zeichenkette  und einer Lnge von 80 Zeichen zu
definieren, schreibt man also:

 char zeichenkette[81];

+++ Einige Funktionen zur Stringbearbeitung +++

+++ strcpy +++

Deklariert  in  string.h. Als Parameter mu  zuerst  der Name des Ziel-Strings
(also  der  Name, der bei der  Definition des char-Arrays angegeben wurde) und
dann der Quell-String angegeben werden. Beispiel:

 char begruessung[12];
 strcpy(begruessung,"HALLO DU!!!");

+++ gets +++

Analog  zu getchar dient gets der Eingabe von Strings. Der Name des Arrays, in
dem  die  Zeichenkette  abgespeichert  werden  soll,  mu  dabei als Parameter
angegeben   werden.  Nach  der  Eingabe  wird  ein  Zeilenumbruch  ausgegeben.
Beispiel:

 char zeichenkette[101];

 .
 .
 .

 gets(zeichenkette);

Die Deklaration befindet sich in stdio.h.

+++ puts +++

Diese  Funktion  gibt  den  String  wieder  auf  den  Bildschirm  sowie  einen
Zeilenvorschub  aus. Ansonsten ist sie genauso wie putchar aufzurufen und auch
in stdio.h deklariert.

+++ Beispielprogram: gets und puts +++

 // gets und puts

 #include <stdio.h>

 void main(void)
 {
   char name[81];              /* Hoffentlich gibt es keinen Namen, der
                                  lnger ist als 80 Zeichen! :-) */
   printf("Wie heit du? ");
   gets(name);
   printf("Aha, du heit also ");
   puts(name);
   printf("Sei gegrt!\n");
 }

+++ strcmp +++

Die  Vergleichsoperatoren, die wir in Teil 3 kennenlernen werden, gelten nicht
fr  Strings. Wir bentigen stattdessen die  Funktion strcmp aus string.h. Als
Parameter mssen dabei die Variablennamen der beiden zu vergleichenden Strings
angegeben werden. Der Rckgabewert von strcmp kann danach von der if-Anweisung
ausgewertet werden. Nheres erfahrt ihr in Teil 3.

+++ strlen +++

Diese  Funktion aus string.h liefert die  Anzahl der Zeichen des als Parameter
angegebenen Strings zurck. Die Stringendekennung wird NICHT dazugezhlt!

+++ strcat +++

Und damit lassen sich zwei Strings aneinanderhngen! Der erste  Parameter  ist
der Ursprungstring, an den der zweite Parameter angehngt wird. Beispiel:

 char stringy[81]="Park";     /* Auch bei Strings kann schon whrend der
                                 Definition eine Zuweisung erfolgen! Dies
                                 ist allerdings der einzige Fall, wo man
                                 strcpy nicht verwenden mu. */
 strcat(stringy,"bank");

strcat ist ebenfalls in string.h deklariert.

Um  das  Gelernte  noch  einmal zu  wiederholen,  folgt  abschlieend noch ein
Beispielprogramm:

 // String-Beispielprogramm

 #include <stdio.h>
 #include <string.h>

 void main(void)
 {
   char vor[21],
        nach[21],
        name[42];

   printf("Hallo, Typ!\nWie lautet dein Vorname? ");
   gets(vor);
   printf("Und dein Nachname? ");
   gets(nach);

   strcpy(name,vor);
   strcat(name," ");
   strcat(name,nach);

   printf("Du heit also ");
   puts(name);
 }

So, Folks, machen wir hier fr heute Schlu.  In der nchsten Folge kommt dann
einiges  mehr  ber  die  Variablen.  Wir  werden  uns  auch  ansehen,  welche
Mglichkeiten  es  gibt,  Verzweigungen  in  C  zu  machen.  Viel Spa bis zur
nchsten Folge (und dann hoffentlich noch immer)!
