^1The Real Adok's Way from QBasic to C Copyright by The Real Adok ^0Heute: Part 2 - Variablen, Strings & Co. ^1 +++ 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. ^1 +++ Datentypen +++ In C gibt es nur wenige Datentypen, und zwar: ^0 short int: Das short kann in DOS auch weggelassen werden. Bei short int ^0 handelt es sich um Ganzzahlen von -32768 bis +32767. Der Daten- ^0 typ belegt 16 Bit. ^0 long int: Das long kann in 32-Bit-Betriebssystemen auch weggelassen ^0 werden. Uhh, Ganzzahlen von -2 hoch irgendwas bis +2 hoch ^0 irgendwas lassen sich in einer long-int-Variablen speichern, ^0 auf jeden Fall sehr viel! Dafr belegt long int auch 32 Bit. ^0 char: Eigentlich auch eine Integervariable, die von -128 bis +127 ^0 reicht und dafr auch nur 8 Bit belegt. Aber sie hat noch ^0 andere Bedeutungen! (Dieses Geheimnis werden wir BALD ^0 lften...) UNTERBRECHUNG! Eine wichtige Meldung zu den Integer-Datentypen: Es gibt auch sogenannte unsigned-Datentypen, und zwar unsigned short, unsigned long und unsigned char. Diese verbrauchen genauso viel Speicherplatz, k”nnen 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... ^0 float: Flieákommazahlen mit 8 Stellen Genauigkeit. Belegt 32 Bit. ^0 double: Flieákommazahlen mit 15 Stellen Genauigkeit. Belegt 64 Bit. Wie ihr seht, hat C nur sehr wenige Datentypen! Nicht einmal Strings sind vorhanden! Das hat einen einfachen Grund: Der Computer selbst kennt ja auch keine Strings. Wozu gibt es denn den ASCII-Code? Richtig, damit der Compi 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 geh”rt, und printen es dann mit voller Wucht in den Screen rein! (Screen: Aua...) Hm, habt ihr schon einmal berlegt, warum der Datentyp char so heiát, wie er heiát? Ganz einfach: Er kann genau 256 Werte annehmen (von -128 bis +127, das ergibt 256 Werte!), und der ASCII-Code ist ja auch 256 Werte groá (von 0 bis 255). Somit eignet sich ein unsigned char bestens zur Speicherung von Zeichen! Und Strings erh„lt man einfach durch einen Array von char-Variablen. Ich sehe, ihr seid ganz heiá auf das Thema, ja, ihr wollt schon mit Strings herum- jonglieren... doch STOP! Zuerst muá ich euch zeigen, wie man Variablen definiert! ^1 +++ Variablendefinitionen +++ Also, eine Variablendefinition sieht schlicht und einfach so aus: ^0 Typ Variablenname; Mehr nicht! Um eine unsigned-char-Variable namens zeichen zu definieren, schreibt man also einfach ^0 unsigned char zeichen; Wenn man mehrere Variablen von ein und demselben Datentyp definieren will, so kann man auch die Variablennamen durch Beistriche trennen. Statt ^0 int multiplikand; ^0 int multiplikator; ^0 int produkt; tippt man dann ^0 int multiplikand, multiplikator, produkt; Da C im Gegensatz zu Basic eine formatfreie Sprache ist und man theoretisch alles berall schreiben kann, wo man will (der Layouter lebt!), geht es auch bersichtlicher: ^0 int multiplikand, ^0 multiplikator, ^0 produkt; Ja, und dann kann man in C noch die Variablen gleich bei der Definition mit einem Wertilein belegen! Das geht dann so: ^0 int multiplikand=99, ^0 multiplikator=111, ^0 produkt=0; /* Hm, neunundneunzig mal einhundertelf macht... ^0 „hhh... :-) */ Super, jetzt hab'n wir's! Nun k”nnen wir uns mal ein biáchen mit der Zuweisung besch„ftigen. ^1 +++ Zuweisung +++ Also, die Zuweisung ist doch sowieso urlogisch, das geht doch einfach mit 'nem Gleichheitszeichen! Ja, so isses: ^0 vary=10; Nun wird vary die Zahl 10 zugewiesen. Bei Variablen des Integer-Stammes gibt es noch eine zweite M”glichkeit: ^0 integervaryoderbessergleichcharvary='C'; Dann wird der Variablen mit dem endlos langem Namen der ASCII-Code des Zeichens C zugewiesen! Ein einzelnes Zeichen muá in C also immer von zwei Hochkommas bedr„ngt werden, die dann den ASCII-Code aus ihm rausquetschen. Jetzt k”nnten wir schon gleich mit der Stringbearbeitung in C anfangen, doch HALT! Zuerst kommt noch eine kleine Besonderheit der Zuweisung, die es nur, und wirklich nur in C gibt: Die Zuweisung ist ein Operator! Was soll das denn heiáen? Nun, ganz einfach: Genauso, wie man ^0 a=b+c; schreiben kann, gibt es auch ^0 a=b=c; Dann 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 h„tten also auch folgendes schreiben k”nnen: ^0 b=c; ^0 a=b; Aber lassen wir das, kommen wir lieber zum next-en Thema. Nein, es hat nichts mit dem Basic-Befehl NEXT zu tun, es ist was ganz anderes: Endlich kommen wir zur Stringbearbeitung! Doch fangen wir klitzeklein an und besprechen zuerst, wie es mit einzelnen Zeichen funktioniert. Die Zuweisung von Zeichen habe ich ja euch schon gezeigt, aber es gibt noch mehr - die Funktionen getch und putchar aus conio.h und stdio.h! ^1 +++ getch +++ Jau, damit l„át sich ein einzelnes Zeichen von dem Schlsselbrett (also dem Keyboard, der Tastatur) einlesen. Diese Funktion ist das, was in Basic INPUT$(1) heiát. Wollen wir also ein Zeichen von der Tasty einlesen und in der Vary zeichy abspeichern, schreiben wir ^0 zeichy=getch(); Hier zeigt sich auch erstmals der Vorteil, daá sich in C Funktionen genauso wie Prozeduren aufrufen lassen. Denn wenn wir nur wollen, daá der Benutzer eine Taste drckt, und uns egal ist, welche Taste er gedrckt hat, schreiben wir schlicht und einfach nur ^0 getch(); Fertig! Das spart Speicherplatz, weil wir nicht extra eine neue Variable ben”tigen, die die gedrckte Taste speichert. Und wie lassen sich die Zeichen wieder auf den Bildschirm hauen? ^1 +++ putchar +++ Richtig, putchar ist der Schl„gertyp, der Zeichen auf den Bildschirm haut! Als Parameter muá dabei das Zeichen angegeben werden, das gequ„lt (das Hauen ist auch eine Qu„lerei) werden soll. Ist doch logisch, sonst weiá putchar doch nicht, wer sein Opfer sein soll! Und hier ist ein kleines Beispielprogramm, das getch und putchar verwendet. 'tschuldigung, wenn es ein biáchen primitiv ist, aber mir ist gerade nichts Besseres eingefallen... ^0 // getch und putchar ^0 #include ^0 #include ^0 void main(void) ^0 { ^0 char zeichen; ^0 printf("Gib ein Zeichen ein! "); ^0 zeichen=getch(); ^0 printf("\nDu gabst folgendes Zeichen ein: "); ^0 putchar(zeichen); ^0 printf("\n"); ^0 } Wenn wir schon dabei sind, m”chte ich zur Vollst„ndigkeit noch zwei weitere Funktionen aus stdio.h kurz erw„hnen: ^1 +++ getc +++ getc funktioniert genauso wie getch, nur wartet es nicht auf einen Tasten- druck, sondern fragt die Tastatur direkt ab, ob in dem Moment eine Taste gedrckt wurde. getc entspricht also der Basic-Funktion INKEY$. ^1 +++ getchar +++ getchar ist beinahe identisch mit getch. Aber zus„tzlich wird die Eingabe auf dem Bildschirm angezeigt, und man muá sie mit ENTER best„tigen! Wozu das gut sein soll... ^1 +++ Arrays und Strings +++ So, jetzt kommen wir endlich zu den Strings! An ihnen l„át sich ja ganz sch”n zeigen, wie Arrays funktionieren. Denn Strings sind nichts anderes, als Arrays vom Typ char. Um einen String mit dem Namen stringilein und einer L„nge von 80 Zeichen zu definieren, schreibt man: ^0 char stringilein[81]; Was zwischen den eckigen Klammern steht, ist die Anzahl der Elemente, die das Array - also bei uns der String - haben soll. Bei einem String muá hierbei die Anzahl der Elemente um 1 gr”áer als die Anzahl der Zeichen sein, damit C auch die Stringendekennung reinpressen kann. Die Stringendekennung ist das Zeichen mit dem ASCII-Code 0 und dient dazu, das Ende des Strings zu kennzeichnen. (WAS DENN SONST?) Nur so nebenbei: Wenn wir einen Array namens feld haben, bei dem wir bei der Definition als Anzahl der Elemente 10 angegeben haben, k”nnen wir das erste Element ber die Variable feld[0] und das letzte Element ber die Variable feld[9] ansprechen. So kann man in einem String einzelne Zeichen ver„ndern, ohne so komplizierte Funktionen wie in Basic (MID$ und Co.) verwenden zu mssen. Und schon wieder haben wir einen neuen Vorteil von C entdeckt! Jetzt fehlen uns nur noch die Zuweisung und die String-Funktionen. Also, die Zuweisung ist ganz einfach! Man verwendet dazu die Funktion strcpy aus der Headerdatei string.h. ^1 +++ strcpy +++ 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: ^0 char begruessung[12]; ^0 strcpy(begruessung,"HALLO DU!!!"); Somit drfte endgltig die Hypothese falsifiziert sein, daá C eine komplizier- te Sprache w„re. Sie ist es nicht! Und auch nicht kompliziert zu erlernen, wie dieser Kurs meisterhaft beweist. Oder??? Falls ihr anderer Meinung seid, werft ruhig euren Computer aus dem Fenster! Aber ich glaube, ihr seid derselben Meinung wie ich. :-) Nun zu den Funktionen zur Stringbearbeitung: Da gibt es einige! Zun„chst einmal zu den Funktionen, die sich in stdio.h befinden. ^1 +++ gets +++ Jau, gets ist der Befehl, mit dem sich Zeichenketten eingeben lassen! Der Name der Variablen, in der die Zeichenkette abgespeichert werden soll, muá dabei als Parameter angegeben werden. Nach der Eingabe wird ein Zeilenumbruch ausgegeben. ^1 +++ puts +++ Diese Funktion gibt den String wieder auf den Bildschirm aus. Ansonsten funktioniert sie genauso wie putchar. Das einzige Dumme ist, daá automatisch ein Zeilenvorschub ausgegeben wird :-(! Doch wir werden schon bald eine M”glichkeit kennenlernen, mit der der Zeilenvorschub unterdrckt werden kann. Ja, ihr habt recht: Es ist eine neue Variante von printf, die wir in der n„chsten Folge kennenlernen werden! Bevor ich euch einige Funktionen der Headerdatei string.h (Nomen est Omen) verstellen werde, liefere ich noch ein Beispielprogramm zu gets und puts, damit jeder kapiert, wie diese Funktionen funktionieren. ^0 // gets und puts ^0 #include ^0 void main(void) ^0 { ^0 char name[81]; /* Hoffentlich gibt es keinen Namen, der ^0 l„nger ist als 80 Zeichen! :-) */ ^0 printf("Wie heiát du? "); ^0 gets(name); ^0 printf("Aha, du heiát also "); ^0 puts(name); ^0 printf("Sei gegrát!\n"); ^0 } Das war's! Zumindest DAS war's. Und auch DAS war's noch nicht, denn es fehlen noch die Funktionen aus der Headerdatei string.h! Also, hier sind sie! ^1 +++ strcmp +++ Tja, Strings lassen sich leider nicht mit dem Vergleichoperator (den wir in der n„chsten Folge kennenlernen werden) vergleichen! Stattdessen ben”tigen wir dazu die Funktion strcmp. 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. Wie bereits gesagt, genaueres erfahrt ihr in der n„chsten Folge! ^1 +++ strlen +++ Diese Funktion liefert die Anzahl der Zeichen des als Parameter angegebenen Strings zurck. Die Stringendekennung wird NICHT dazugez„hlt! ^1 +++ strcat +++ Und damit lassen sich zwei Strings aneinanderh„ngen! Der erste Parameter ist der Ursprungstring, an den der zweite Parameter angeh„ngt wird. Beispiel: ^0 char stringy[81]="Park"; /* Auch bei Strings kann schon w„hrend der ^0 Definition eine Zuweisung erfolgen! Dies ^0 ist allerdings der einzige Fall, wo man ^0 strcpy nicht verwenden muá. */ ^0 strcat(stringy,"bank"); Um das gelernte Zeug noch einmal zu wiederholen, folgt abschlieáend noch ein Beispielprogramm: ^0 // String-Beispielprogramm ^0 #include ^0 #include ^0 void main(void) ^0 { ^0 char vor[21], ^0 nach[21], ^0 name[42]; ^0 printf("Hallo, Typ!\nWie lautet dein Vorname? "); ^0 gets(vor); ^0 printf("Und dein Nachname? "); ^0 gets(nach); ^0 strcpy(name,vor); ^0 strcat(name," "); ^0 strcat(name,nach); ^0 printf("Du heiát also "); ^0 puts(name); ^0 } So, Folks, machen wir hier fr heute Schluá. In der n„chsten Folge kommt dann einiges mehr ber die Variablen. Wir werden uns auch ansehen, welche M”glichkeiten es gibt, Verzweigungen in C zu machen. Viel Spaá bis zur n„chsten Folge (und dann hoffentlich noch immer)! Euer The Real Adok. ^3PS: Diese und die vorige Folge erschienen bereits im Diskmag Digital Chat, in ^3 dem der C-Kurs ursprnglich exklusiv erscheinen sollte. Da jedoch einige ^3 Leser den Kurs auch im Hugi lesen wollten, erscheint er also dennoch hier. ^3 Und da die DC zugrunde gegangen ist, hat sich sowieso alles erbrigt. ^3 Folge 3 und ein Teil von Folge 4 des Kurses habe ich bereits vor einiger ^3 Zeit geschrieben, danach werde ich den Kurs in einem anderen Stil ^3 fortsetzen - siehe ASM-Kurs.