#29 Arrays Flashcards
Was sind Arrays ,deren Anwendungsbereiche und Syntax?
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;
Nenne Bedingungen die erfüllt sein müssen bei der Erzeugung von Arrays und was pasiert bei der Erzeugung.
- 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.
Was ist zum Speicherbedarf von Arrays zu sagen?
-Elemente werden geordnet, direkt hintereinander im Speicher abgelegt
- 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).
Nenne die Verbindung von Zeichenketten zu 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)
Wie werden Zeichenfolgen Dargestellt?
- 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.
- Beispiel („Hallo“ im Speicher):
- 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).
Wie werden lokale und Globale Arrays initialisiert?
- 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
Was ist zu beachten bei der Initialisierung von Arrays?
- Listenwerte dürfen Literale und Variablen sein
- 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. - 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.
Was ist bei dem Zugriff auf Array-Elemente zu beachten?
- 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.
Erläutere die Prüfung von Bereichsgrenzen bei Arrays.
- 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
- lesend: Programm arbeitet mit falschen Werten. Die Fehlerquelle schwer
Was passiert im Hintergrund bei den Arrays?(Stichwort: Zeiger)
- 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.
- Beispiel:
int vektor[5], s; - folgende Ausdrücke sind gleichbedeutend:
s = vektor[3];
s = *(vektor+3);
Was ist bei Übergabe von Arrays als Funktionsparameter zu beachten?
- 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);
__________________
Was ist bei der Übergabe von Arrays an Funktionen als Funktionsparameter mit unterschiedlicher Größe zu beachten?
- 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):
______________________________________________________
void vektor_add(int v1[], int v2[], int result[])
______________________________________________________ - Vorsicht: Gefahr ungültiger Speicherzugriffe!
- Größe des Feldes unter Umständen in der Funktion nicht bekannt, muss dann als separater
Parameter übergeben werden
______________________________________________________
void vektor_add(int v1[], int v2[], int result[], int size)
______________________________________________________
- Größe des Feldes unter Umständen in der Funktion nicht bekannt, muss dann als separater
Wie kann man Arrays NICHT Vergleichen und Zuweisen?
-Vergleich von Arrays mit == ist nicht möglich (damit würden nur die Startadressen der Felder verglichen)
-Gleiches gilt für die Zuweisung der Inhalte von einem Array in das andere mit
dem =-Operator (damit würden nur die Startadressen der Felder zugewiesen)
Wie kann man Arrays Vergleichen?
- 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
- Parameter: die zu vergleichenden Arrays, sowie die Anzahl von Bytes, die
Welche Funktion wird genutzt 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
____________________________________
#include <string.h></string.h>
int v1[3] = {1,2,3}, v2[3];
memcpy(v2, v1, 3 * sizeof(int));
____________________________________
Was ist grundlegend zu Mehrdimensinalen Arrays zu sagen? Syntax(Def und Zugriff),Initialisierung
- 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];
v
Initialisierung:
- Initialisierung analog zu eindimensionalen Arrays.
- Sowohl Zeilen als auch Spalten dürfen unvollständig sein.
- Arraygröße muss nicht angegeben werden.
- Beispiel:
____________________________________
int matrix[3][5] =
{ { 6,-4, 6, 2,-1},
{ 2, 3,-1, 9,-3},
{-1, 4,-8, 0, 3} };
____________________________________
Was ist bei den Funktionsparameter als Mehrdimensionaler Array zu beachten?
- 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.
Was ist bei der Deklaration von Arrays zu beachten?
- C90 Standard
- Breite Unterstützung, nahezu alle C Compiler
- Größe eines Arrays muss zum Zeitpunkt der Übersetzung feststehen.
- Folgendes Beispiel geht nach diesem Standard nicht, da die Größe erst zur
Laufzeit bestimmt wird:
____________________________________
int size;
scanf(“%d”, &size);
double a[size];
____________________________________
- C99 Standard
- Lokale Arrays dürfen mit Variable deklariert werden, d.h. obiges Beispiel wäre gültig.
Wie können wir die Elemenzanzahl eines Arrays bestimmen?
sizeof Operator bei Arrays:
- sizeof Operator liefert auch bei Arrays den belegten Platz in Byte, dividiert
durch die Größe eines Elements erhält man so die Elementanzahl
- Beispiel:
________________________________________________________________________
double b[1000];
printf(“b hat %d Elemente\n”, sizeof(b) / sizeof(double));
________________________________________________________________________
- Aber Vorsicht, das funktioniert nicht immer:
________________________________________________________________________
void test(double c[])
{
printf(“c hat %d Elemente\n”, sizeof(c) / sizeof(double));
}
________________________________________________________________________
- Abhilfe: Feldgröße als zusätzlichen Parameter übergeben.