Vorlesung 9 Flashcards
Arrays
- Arrays (Felder, Vektoren) dienen zum Speichern einer festen Anzahl von
Werten gleichen Typs. - Anwendungsbeispiele:
- Vektoren, Matrizen
- Liste von Namen
- Syntax (Definition eines Arrays):
Datentyp Bezeichner[Elementanzahl]; - Beispiel:
float vektor[3];
short int a, b[10], c; - Die Elementanzahl muss positiv sein.
- Ungeeignet, wenn die Anzahl der Daten unbekannt ist, dann muss
dynamische Speicherverwaltung verwendet werden. - Durch die Definition eines Arrays werden so viele Variablen erzeugt, wie das
Array Elemente hat. - int b[10] erzeugt:
- Variablenname b für Zugriff auf das gesamte Array
- Variablennamen für Zugriff auf die einzelnen Elemente:
b[0], b[1], …, b[9] - Die Indizierung beginnt immer bei 0.
Arrays im Speicher
Elemente werden geordnet, direkt hintereinander im Speicher abgelegt.
Speicherbedarf von Arrays
- Speicherbedarf: Elementanzahl · Größe des Datentyps
- Beispiele:
- int wert[250]; braucht z.B. 4 · 250 = 1000 Byte
- double wert[1000]; braucht z.B. 8 · 1000 = 8000 Byte
- Vorsicht:
- Der gesamte Speicher für die Arrays wird erst zur Laufzeit angefordert.
- Bei zu großen Arrays oder lokal definierte Arrays kann es
Probleme geben (siehe Stack, später).
Zeichenketten als char-Arrays
- Eine der wichtigsten Anwendungen von Arrays ist die Darstellung und
Verarbeitung von Zeichenfolgen (Strings / Text). - Zeichenfolgen treten meist auf bei
- Ein- und Ausgabe (Benutzerschnittstellen)
- Verarbeitung von Text-Dateien
- In C gibt es keinen Datentyp String, stattdessen werden
char-Arrays verwendet. - Die Standardbibliotheken von C enthalten eine Menge Funktionen für
Zeichenketten (später mehr dazu).
Darstellung von Zeichenfolgen
Eine String-Literal wird intern als char-Array dargestellt.
● Die Länge ist um 1 größer als die Anzahl der Zeichen in der
Stringkonstanten.
● Zusatzfeld für die Speicherung von des Null-Zeichens ‘\0’, welches das
Ende des Strings anzeigt
- Wenn man eine Zeichenfolge bearbeitet, muss man immer prüfen, ob das
aktuelle Zeichen das ‘\0’-Zeichen ist. - Vorsicht: Fehler, wenn das Null-Zeichen mitten in einem String vorkommt
(z.B. bei der Konkatenation zweier Strings).
Initialisierung von Arrays
- Automatische Initialisierung wie bei Variablen:
- globale Arrays werden mit 0 initialisiert
- lokale Arrays werden nicht automatisch initialisiert
- Manuelle Initialisierung erfolgt durch Anhängen einer Liste
von Werten
int vector1[5] = {6, -4, 6, 2, -1};
int vector2[5] = {6, -6, 2};
int vector3[] = {3, -5, 7, 2, -1};
char hello[6] = {‘h’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\0’};
char str[] = “hello world\n”;
- Listenwerte dürfen Literale und Variablen sein.
int vector1[5] = {6, -4, 6, 2, -1}; - Es dürfen auch weniger Elemente in der Liste stehen als die angegebene
Elementenanzahl, die übrigen Elemente bleiben uninitialisiert, bzw. werden
bei globalen Variablen mit 0 initialisiert.
int vector2[5] = {6, -6, 2}; - Implizite Längenbestimmung:
- Die Größe des Feldes wird der Anzahl der Initialisierungswerte gleichgesetzt.
- Häufigste Verwendung ist das Initialisieren von Stringkonstanten
wie im Beispiel str.
int vector3[] = {3, -5, 7, 2, -1};
Zugriff auf Array-Elemente
- Syntax: name [arrayindex];
- arrayindex kann ein beliebiger nichtnegativer Ausdruck sein, der zur Laufzeit
ausgewertet wird, z.B. Laufvariablen einer Schleife - Die Indizierung beginnt immer bei 0.
- Beispiel:
int a, v[] = {1,2,3};
a = v[1]; «_space;a wird zu 2
Prüfung von Bereichsgrenzen
- Keine Prüfung, ob arrayindex in den zugelassenen Grenzen liegt! Zugriffe auf
beliebige Speicherinhalte möglich (Speicherorganisation) - Zugriff auf Werte außerhalb der Grenzen:
- lesend: Programm arbeitet mit falschen Werten. Die Fehlerquelle schwer
lokalisierbar, evtl. Programmabsturz durch Speicherschutz des Betriebssystems. - schreibend: Wenn die Abweichung groß ist, wird ggfs. Programmcode
überschrieben. Bei Betriebssystemen ohne Speicherschutz führt dies zum
Crash, bei UNIX-Rechnern wird der Absturz verhindert (Segmentation fault,
eigenes Programm wird beendet, andere laufen weiter), ebenso auf
Windows-Systemen
Arrays backstage
- Die Variable für den gesamten Array ist intern nichts anderes als ein Zeiger.
- Der Zugriff auf ein Element des Arrays wird über die
Adressarithmetik gesteuert. - folgende Ausdrücke sind gleichbedeutend:
s = vektor[3];
s = *(vektor+3);
Arrays als Funktionsparameter
● Bei der Parameterübergabe eines Arrays wird lediglich die Startadresse des
Feldes übergeben (Zeigerübergabe).
● Änderungen der Elemente des Arrays sind daher auch in der aufrufenden
Umgebung sichtbar.
● Beispiel: Bei scanf wird nicht die Adresse des char-Arrays übergeben,
sondern die Array-Variable selbst:
char str[100];
scanf(“%s”, str);
int i;
scanf(“%d”, &i);
● Häufig soll eine Funktion mit Feldern unterschiedlicher Größe
korrekt arbeiten.
● Daher: Bei Funktionsdefinition braucht die Größe nicht angegeben werden
(für mehrdimensionale Felder stimmt dies nicht, folgt später):
● Vorsicht: Gefahr ungültiger Speicherzugriffe!
* Größe des Feldes unter Umständen in der Funktion nicht bekannt, muss dann
als separater Parameter übergeben werden
Funktion zum Vergleich von Arrays
include <string.h></string.h>
- Vergleich mittels der Funktion memcmp aus string.h
(schneller als manuell) - Parameter: die zu vergleichenden Arrays, sowie die Anzahl von Bytes, die
verglichen werden sollen - Ergebnis: 0, wenn Arrays gleich sind
…
int v1[3] = {1,2,3}, v2[3] = {4,5,6};
if(0 == memcmp(v1, v2, 3 * sizeof(int)))
printf(“v1 gleich v2\n”);
else
printf(“v1 nicht gleich v2\n”);
Funktion zum Kopieren von Arrays
- Zuweisung mittels der Funktion memcpy aus string.h
(schneller als manuell) - Parameter: Ziel-Array, Quell-Array, sowie die Anzahl von Bytes,
die zugewiesen werden sollen
beispiel:
#include <string.h>
...
int v1[3] = {1,2,3}, v2[3];
memcpy(v2, v1, 3 * sizeof(int));</string.h>
Mehrdimensionale Arrays
- Mehrdimensionale Arrays dienen zum Aufbau von Tabellen, Matrizen und
ähnlichen Strukturen. - Syntax der Definition:
- Datentyp Bezeichner[Anzahl 1][Anzahl 2]…;
- Beispiel (Matrix mit 2 Zeilen und 3 Spalten):
short int matrix[2][3]; - Syntax des Zugriffs:
Name[Array-Index 1][Array-Index 2]…; - Beispiel (Zugriff):
x = matrix[1][2];
Initialisierung von mehrdimensionalen Arrays
- Initialisierung analog zu eindimensionalen Arrays.
- Sowohl Zeilen als auch Spalten dürfen unvollständig sein.
- Arraygröße muss nicht angegeben werden.
int matrix[3][5] = { { 6,-4, 6, 2,-1},
{ 2, 3,-1, 9,-3},
{-1, 4,-8, 0, 3} };
Mehrdimensionale Arrays als Funktionsparameter
● Bei Funktionsdefinition braucht die erste Dimension nicht angegeben werden,
die anderen müssen angegeben werden.
void drucke_namen(char namen[][256], int count)
● Mit Zeigern kann aber auch dies umgangen werden.