Vektoren Problem: Beispiel: viele Variablen vom gleichen Typ abspeichern Text ( = viele char-variablen), Ergebnisse einer Meßreihe ( = viele int-variablen) hierfür: Vektoren ( = Arrays = Feld ) = Ansammlung von Objekten gleichen Typs alle Objekte haben einen gemeinsamen Namen = Name des Vektors die Objekte werden hintereinander im Speicher abgelegt die Objekte sind nummeriert, beginnend mit 0,1,2,... jedes Objekt wird durch seine Nummer ausgewählt die Nummer wird in eckigen Klammern angegeben Beispiel: objekt[14] 1 / 18 Gi_Vorlesung_06_2016
Deklaration von Vektoren a) Normalfall: Anzahl der Elemente explizit angeben char text[100]; reserviert Speicherplatz für 100 char Variablen int messreihe[1000]; b) Anfangswerte angeben, der Compiler berechnet daraus die Größe des Vektors char text[] = "Hallo"; int messreihe[] = {1, 2, 3, 4, 5}; auch erlaubt int messreihe[5] = {1, 2, 3, 4, 5}; Zahl muß stimmen! und int messreihe[5] = {0}; = alle Elemente auf 0 setzen 2 / 18 Gi_Vorlesung_06_2016
Zugriff auf Vektorelemente Beispiel: int wert[100]; wert[0] = 22; wert[1] = 33; printf("%d",wert[55]); wichtig: das erste Element hat den Index 0 das letzte Element hat den Index n-1 (n = Anzahl der Elemente) hier: 99 Anwendung in Schleifen: for (index = 0; index < 100; index++) { wert[index] = index; printf(" %d ",wert[index]); } in der eckigen Klammer kann auch eine Variable stehen! 3 / 18 Gi_Vorlesung_06_2016
ÜBUNG Aufgabe: Schreiben Sie ein Programm, das einen Integer-Vektor mit 100 Elementen anlegt. In die Elemente sollen die Zahlen von 100 bis 199 geschrieben werden (for - Schleife verwenden). In einer zweiten Schleife sollen danach der Index jedes Vektorelements und der Inhalt jedes Vektorelements ausgegeben werden. 4 / 18 Gi_Vorlesung_06_2016
Zeichenketten Zeichenkette ( = String ) = Vektor vom Typ char Besonderheit: es gibt spezielle Funktionen z.b. um ganze Zeichenketten auszugeben, zu kopieren etc (siehe später: Stringoperationen) wichtig: diese Funktionen erwarten, dass das letzte Zeichen einer Zeichenkette das String-Ende-Zeichen (Nullzeichen) '\0' ist! um einen 4 Zeichen langen String abzuspeichern sind 5 char Variablen nötig Beispiel: char text[5]; text[0] = 'T'; text[1] = 'E'; text[2] = 'S'; text[3] = 'T'; text[4] = '\0'; Hinweis: das String-Ende-Zeichen entspricht der Dezimalzahl 0 (d.h. Bitkombination 00000000) text[4] = 0; ist auch erlaubt 5 / 18 Gi_Vorlesung_06_2016
Ein- und Ausgabe von Zeichenketten Platzhalter in Formatangaben: %s (string) a) Ausgabe einer Zeichenkette: char text[] = "TEST"; printf("%s",text); falls kein Nullzeichen im String: Ausgabe endet erst wenn zufällig '\0' gefunden wird. b) Einlesen einer Zeichenkette: scanf("%s",text); ist erlaubt, aber nicht empfehlenswert!!! Problem: es werden Zeichen eingelesen, bis die Eingabe Taste gedrückt wird. möglicherweise mehr als Speicherplatz vorhanden ist ( buffer overflow ). dann evtl. Programmabsturz! 6 / 18 Gi_Vorlesung_06_2016
ÜBUNG Aufgabe: Geben Sie das Beispielprogramm ein und testen Sie es: #include <stdio.h> main() { char text[] = "\nquadratzahl\0n von 0 bis 10:"; int index, zahl[11]; printf("%s\n\n",text); for(index = 0; index < 11; index++) { zahl[index] = index * index; printf(" %d ",zahl[index]); } while(1); } Wie viele Elemente hat der Vektor text? (Steuerzeichen belegen ein Byte) Wo steht das String-Ende-Zeichen? a) Fügen Sie nun vor der ersten printf - Anweisung folgende Zeile ein: text[12] = e ; Was bewirkt das? Erklärung? b) Ändern Sie diese Zeile ab in : text[9] = 0; Was bewirkt das? Erklärung? 7 / 18 Gi_Vorlesung_06_2016
Die Funktion getchar() Die Funktion getchar() liest ein Zeichen aus dem Tastaturpuffer des Betriebssystems get character = lies ein Zeichen Prinzip: - Tastendrücke werden vom Betriebssystem gesammelt, bis die Eingabetaste gedrückt wird. Die Zeichencodes werden in einem Speicher ( = Tastaturpuffer) zwischengespeichert. - Eingabefunktionen (getchar(), scanf() lesen danach den Tastaturpuffer aus) Beispiel: es wurde 1, 2, 3, <Eingabe> getippt. zeichen = getchar(); liest den Zeichencode des Zeichens 1 scanf("%d",&zahl); liest die Zahl 123 scanf("%c",&zeichen); liest den Zeichencode des Zeichens 1 scanf("%s", text); liest die drei Zeichencodes der Zeichen 1, 2 und 3 Unterschied: getchar() liest immer ein Zeichen, scanf() kann mehrere Zeichen lesen und auch z.b. in das Binärformat einer Zahl umwandeln oder in ein Textarray schreiben. 8 / 18 Gi_Vorlesung_06_2016
Eine elementare Möglichkeit einen String einzulesen: in einer Schleife zeichenweise einlesen und Zeichen zählen: ein Zeichen einlesen Eingabetaste? ja nein Vektor voll? ja nein Eingabe beenden 9 / 18 Gi_Vorlesung_06_2016
C-Programmcode: int ende = 0; int index = 0; char text[20]; do { text[index] = getchar(); Die Funktion getchar() liest ein Zeichen aus dem Tastaturpuffer des Betriebssystems ein Zeichen in den Vektor einlesen if ( text[index] == 10 ) das ist der ASCII-Code { der Eingabe-Taste ('\n' = 10) ende = 1; } else { index++; } if ( index == 19 ) der Vektor ist voll (Index geht von 0 bis 19) { ende = 1; } } while ( ende == 0 ); text[index] = '\0'; String-Ende-Zeichen einfügen 10 / 18 Gi_Vorlesung_06_2016
Weitere Möglichkeiten einen String einzulesen: a) Begrenzung der Anzahl der einzulesenden Zeichen mittels Formatangabe: scanf("%20s",text); es werden maximal 20 Zeichen eingelesen (inklusive String-Ende-Zeichen) Hinweis: scanf() liest keine Leerzeichen ein. Leerzeichen beenden die Eingabe. Beispiel: Eingabe von Das ist ein Text Leerzeichen Gespeichert wird Das String-Ende 11 / 18 Gi_Vorlesung_06_2016
b) Optimal: Speicherplatz und Anzahl einzulesender Zeichen an einer Stelle definieren: #define ANZAHL 20 char text[anzahl]; Es wird eine Textkonstante mit Namen ANZAHL definiert, die beim Übersetzen durch die Zahl 20 ersetzt wird fgets(text, ANZAHL, stdin); Vorteile: - Speicherplatz und Anzahl einzulesender Zeichen stimmen immer überein. - Es werden auch Leerzeichen eingelesen. fgets() ( get string from file ) liest eine Zeichenkette aus einer Datei. Es werden maximal ANZAHL Zeichen im Vektor text gespeichert. Es wird immer ein New Line (\n) und ein String-Ende-Zeichen (\0) gespeichert. Der Eingabepuffer des Betriebssystems (stdin) wird wie eine Datei behandelt. fgets() und stdin sind in der stdio.h deklariert ( #include stdio.h ) 12 / 18 Gi_Vorlesung_06_2016
ÜBUNG Aufgabe: Schreiben Sie ein Programm, das maximal 10 Zeichen von der Tastatur einliest. Die Eingabe soll beendet werden, wenn der Buchstabe e eingegeben wird. Verwenden Sie zum Einlesen der Zeichen die Funktion getchar() (siehe Vorlesung). Nach Ende der Eingabe soll der String ausgegeben werden. Wie viele Bytes braucht man um einen String mit 10 Buchstaben abzuspeichern? Hinweis 1: Beim Testen Ihres Programms müssen Sie die Eingabe mit der Eingabe -Taste beenden. Dies wird von der Funktion getchar() so verlangt. Hinweis 2: Orientieren Sie sich bei der Lösung dieser Aufgabe an dem Beispielprogramm, das in der Vorlesung besprochen wurde. 13 / 18 Gi_Vorlesung_06_2016
Zusammenfassung: Vektoren - Vektoren bzw. Arrays: falls viele Variablen eines Typs nötig - Größe explizit angeben oder durch Initialisierung vorgeben - Zugriff über Elementnummer (Index) - kleinster Index = 0 - größter Index = n - 1 (n = Zahl der Elemente) - Zeichenketten bzw. Strings = Character-Array - Platzhalter bei Ausgabe: %s - wichtig: String Ende Zeichen '\0' 14 / 18 Gi_Vorlesung_06_2016
Speicherzugriff unter C - kleinste Speichereinheit: 1 Byte - jedes Byte hat eine Adresse ( Hausnummer ) im Speicher Adresse 100 101 102 103 Inhalt 12 00 33-126 Variablenname zeichen index zahl... - normalerweise: statt der Adresse wird ein symbolischer Name (Variablenname) verwendet im Bild: char-variablen belegen ein Byte Speicherplatz 15 / 18 Gi_Vorlesung_06_2016
Speicherung von Vektoren (Arrays) Die Elemente werden in aufeinanderfolgenden Speicherzellen abgelegt char - Array int - Array 1 Kästchen ist 1 Byte Speicher 'T' 'E' 'S' 'T' 0 text[0] text[1] text[2] text[3] text[4] zahl[0] zahl[1] Integer-Zahl benötigt 4 Byte Speicherplatz (32 Bit) 16 / 18 Gi_Vorlesung_06_2016
Algorithmus: kleinste und größte Zahl Aufgabe: Schreiben Sie ein Schreiben Sie ein Programm, das den kleinsten und den größten Wert der Daten in dem Array daten berechnet und auf dem Bildschirm ausgibt: int daten[] = {54,10,36,20,72,30,31,40,2,50}; Algorithmus: - je eine Variable für die Speicherung der kleinsten und der grössten Zahl deklarieren - Die Variablen mit dem Inhalt des ersten Array-Elements beschreiben ( Startwert ) - Eine Schleife programmieren, die nacheinander die Array-Elemente mit den Inhalten der beiden Variablen vergleicht: Ist ein Array-Element grösser als die bisher grösste Zahl? Ist ein Array-Element kleiner als die bisher kleinste Zahl? - Ergebnis ausgeben 17 / 18 Gi_Vorlesung_06_2016
Algorithmus: Sortieren Aufgabe: Schreiben Sie ein Schreiben Sie ein Programm, das die Inhalte des Arrays daten sortiert und auf dem Bildschirm ausgibt. Die kleinste Zahl soll zuerst ausgegeben werden: int daten[] = {54,10,36,20,72,30,31,40,2,50}; Algorithmus: - Das erste Array-Element mit allen anderen Elementen vergleichen. Falls es ein kleineres Element gibt, wird dieses mit dem ersten Array-Element vertauscht. -Für den Tausch wird eine Hilfsvariable benötigt - Dann das zweite Array-Element mit dem dritten und allen folgenden Elementen vertauschen... usw... Es werden zwei ineinander geschachtelte Schleifen benötigt 18 / 18 Gi_Vorlesung_06_2016