Sie sind auf Seite 1von 12

7.

3 Vektoren (Arrays, Felder)

Vektoren = eindimensionale Arrays

Sind in der Lage, mehrere Werte eines Datentyps (!) unter einem Bezeichner
zu speichern

Datentyp Bezeichner [Dimension]

Bsp.: Vektor mit 10 Elementen statt 10 einzelne Variablen

float BerechneNeuenKontostand (float AlterStand,


float Ueberweisung [10])
{
float summe = 0.0;

for (int i=0; i<10; i++)


summe += Ueberweisung [i];  Elemente
Ueb…[0] … Ueb [9]
return (AlterStand + summe);
}

7. Zeiger und Vektoren 87 Programmierung I

Arrayelemente und Initialisierung

Der Zugriff auf Arrayelemente erfolgt über den Arrayindex von 0 bis „n-1“

int a[5]; // Array aus 5 Elementen des Typs int


char b[5]; // Array aus 5 Elementen des Typs char

float c[5] = {0.1, 0.2, 0.3, .4, .5}; // Initialisierung

float c[] = {0.1, 0.2, 0.3, .4, .5}; // ohne Feldgrenzen

a[0] = 1; // Zuweisung

int a[]; // Unbestimmte Arrays in C nicht erlaubt!!

7. Zeiger und Vektoren 88 Programmierung I


Zeichenketten

„strings“ = Vektoren vom Typ char

interner Abschluss mit dem Zeichen '\0' („Null-terminiert“)

Manipulation / Auswertung mit strcpy, strlen, …

char Vorlesung [] = "Prog 1"; // Def. + Initialisierung


// Größe 7 (incl. 0)

Initialisierung: Zwei Varianten

char Text1 [] = "Ich bin eine Zeile";


char *Text2 = "Ich bin eine andere";

Text1 ist ein Vektor. Text2 ist ein Zeiger.


Größe für Zeichen und '\0'. Zeigt auf konstante Zeichenkette.
Einzelne Zeichen änderbar. Einzelne Zeichen nicht änderbar.
Speicherplatz fest. (Resultat undefiniert)
Zeiger kann an andere Stelle umgelenkt werden.

Text1: Ich bin eine Zeile\0 Text2: Ich bin eine andere\0

7. Zeiger und Vektoren 89 Programmierung I

Zuweisung im Programm nur durch z.B. strcpy oder sprintf möglich

char Vorlesung [] = "Prog 1"; // Def. + Initialisierung

Vorlesung = "WebPro"; // Syntaxfehler

strcpy (Vorlesung, "Web"); // richtig. Größe beachten!!


sprintf (Vorlesung, "Pro %d", 3); // richtig

Vorlesung [5] = '2'; // richtig

7. Zeiger und Vektoren 90 Programmierung I


Funktionen zur Verarbeitung von Zeichenketten

#include "string.h"

char* strcpy (char* ziel, const char* quelle);

size_t strlen (const char* string); // size_t == unsigned long

char* strcat (char* ziel, const char* str2);

int strcmp (const char* str1, const char* str2);

int strncmp (const char* str1, const char* str2, const size_t len);

7. Zeiger und Vektoren 91 Programmierung I

Mehrdimensionale Arrays

Jede Dimension muss in eckigen Klammern angegeben werden.

Datentyp Bezeichner [Dimension1] [Dimension2] ...


Zeilenanzahl Spaltenanzahl

float Array [3] [4] // 3 Zeilen, 4 Spalten


// array ist kein Schlüsselwort!

Initialisierung mehrdimensionaler Arrays

int Zahlen [3][4] = {{1,2,3,4}, {5,6,7,8}, {9,8,7,6}};

ist gleichwertig mit…


int Zahlen [3][4] = {1,2,3,4, 5,6,7,8, 9,8,7,6};

 Organisation im Speicher: a00, a01, a02, ..., a10, ...

int Zahlen [][4] = {{1,2,3,4}, {5,6,7,8}, {9,8,7,6}}; // richtig


int Zahlen [3][] = {{1,2,3,4}, {5,6,7,8}, {9,8,7,6}}; // falsch

7. Zeiger und Vektoren 92 Programmierung I


7.4 Beziehungen zwischen Zeigern und Feldern

Beispiel: int a [10];

Index: 0 1 2 3 4 5 6 7 8 9
a[0]... a[5]...

Bytes !

a == &a[0] a+5 == &a[5]

a[0] == *a a[5] == *(a+5)

Einem Zeiger kann der Name eines Feldes zugewiesen werden!!


int a [10];
int* p = a; // entspricht int* p = &a[0];
7. Zeiger und Vektoren 93 Programmierung I

int a[10]; reserviert Speicherplatz a[0]…a[9] mit 10 integer Werten

int * p; Definition eines Pointers auf int

p = &a[0]; Pointer  Adresse des ersten Arrayelements

p = a; Identisch !

Zugriff auf Arrayelemente:

int b; Variablendefinition
int * p; Definition eines Pointers auf int

b = a[0]; identisch mit b = *a;


b = a[5]; identisch mit b = *(a+5);

p = a+5; identisch mit p = &a[5];


a[5] = 23; identisch mit *p = 23;

7. Zeiger und Vektoren 94 Programmierung I


7.5 Felder als Funktionsvariablen
hier: eindimensionale Felder
Beim Funktionsaufruf wird nur die Adresse des ersten Feldelementes übergeben!

- Arrays als Übergabeparameter können in Funktionen verändert werden.

- Es findet keine Bereichsüberprüfung statt. (Es wird ja nur die Adresse übergeben)

- Bei Aufruf erfolgt automatisch eine Umwandlung in einen Pointertyp (oder Typ
wird explizit angegeben)

Implizite Umwandlung in Zeiger


int function (int a[10], int); // Prototyp

int function (int a[10], int length) // Definition


{
for (int i = 0; i < length; i++)
a[i] = i;
return 0; Automatische Umwandlung
} in Zeiger auf int
int main () Übergabe einer Adresse
{ „Call by reference“
int b[10];
function (b, 10); // Funktionsaufruf
return 0;
}

7. Zeiger und Vektoren 95 Programmierung I

Expliziter Aufruf über Zeiger

int function (int *, int); // Prototyp

int function (int *a, int length) // Definition


{
for (int i = 0; i < length; i++)
{
*a = i;
a++; // Inkrementieren d.Pointers
}
return 0; Definition mit Pointer
}

int main ()
{
int b[10];
function (b, 10); // Funktionsaufruf
// oder
function (&b[0], 10);
return 0; Übergabe einer Adresse
} „Call by reference“

7. Zeiger und Vektoren 96 Programmierung I


Auch möglich – da keine Bereichsüberprüfung stattfindet

int function (int a[], int); // Prototyp

int function (int a[], int length) // Definition


{
for (int i = 0; i < length; i++)
a[i] = i;
return 0;
}

int main ()
{
int b[10];
function (b, 10); // Funktionsaufruf
return 0;
}

a [] bedeutet nicht unbestimmtes Array, sondern nur Übergabe der Adresse

Zur Array-Bearbeitung in einer Funktion: immer Länge mit übergeben!

7. Zeiger und Vektoren 97 Programmierung I

7.6 Operationen mit Zeigern

Inkrementieren / Dekrementieren eines Zeigers

„+n“ bedeutet bei Zeigern:


Inkrementierung um n Schritte der Schrittweite sizeof (Typ)

int i; // z.B. Adresse 0x0100


int j; // z.B. Adresse 0x0104
int k; // z.B. Adresse 0x0108
int feld[10]; // z.B. Adresse 0x010C, 0x0110, 0x0114, ...

int * ptr = &i; // ptr enthält Adresse von i, d.h. 0x0100

ptr = ptr + 2; // ptr enthält nun 0x0108, d.h. Adresse von k


ptr++; // ptr enthält nun 0x010C, d.h. Adresse von feld [0]
(zufällig)

Addition eines ganzzahligen Wertes zu einer Zeigervariable erhöht den Wert


der Adresse um die Größe der entsprechenden Anzahl von Objekten dieses Datentyps.
(Sinnvoll bei Feldern)

7. Zeiger und Vektoren 98 Programmierung I


Differenz zweier Zeiger

int feld[10];
int* ptr1 = &feld [1];
int* ptr8 = &feld [8];
int anzahl = ptr8 – ptr1; … Wert 7 (nicht 7*4...!)
// ergibt den

//Besser:
ptrdiff_t anzahl = ptr8 – ptr1; //vereinbart in stddef.h

7. Zeiger und Vektoren 99 Programmierung I

Einem Zeiger einen anderen Zeiger gleichen Typs zuweisen

int i;
int* ptr1 = &i;
int* ptr2 = ptr1;
int* ptr3 = ptr2 + 5;

Zuweisung eines anderen Typs über Typecast

Typecast zunächst ohne Zeiger:


int i;
float f = 3.5;

i = (int) f;

Jetzt:
char* pchar = (char*) ptr1; // mit int* ptr1 von oben

Anwendung: Um in einem int-Array doch mal byteweise „herumzupointern“.


Bsp: Zugriff auf einzelne RGB-Komponenten eines byteweise zusammengesetzten
Farb-Datentyps wie COLORREF

7. Zeiger und Vektoren 100 Programmierung I


NULL-Zuweisung

Kennzeichnung als nicht initialisierter Zeiger


int* ptr = 0;
int* ptr = NULL; oft: Rückgabewert von Funktionen bei Misserfolg

Vergleichsoperatoren

== und != sind zulässig,

testen auf Gleichheit der ADRESSEN, nicht der enthaltenen WERTE

7. Zeiger und Vektoren 101 Programmierung I

7.7 Beispiele zu Zeichenketten

1) strcpy nachprogrammieren

void strcpy (char *t, char *s)


{
int i = 0; Variante 1 mit Vektorindex
while ((t[i] = s[i]) != '\0')
i++;
}
Achtung! '\0' mitkopieren!

void strcpy (char *t, char *s)


{
while ((*t = *s) != '\0'){ Variante 2 mit Zeigern
t++;
s++;
}
}

void strcpy (char *t, char *s)


{ Variante 3
while ((*t++ = *s++) != '\0')
;
} Ver(un)gleich mit 0 ist redundant 

void strcpy (char *t, char *s)


{ while (*t++ = *s++) ; } Anm.: Die Bibliotheksfunktion gibt Zeiger
auf Kopierziel zurück.
7. Zeiger und Vektoren 102 Programmierung I
2) Vektoren von Zeigern

Anwendung: Sortieren von Zeichenketten

defghi\0 defghi\0
jklmnopqrst\0 jklmnopqrst\0
abc\0 abc\0

Vektor von Zeigern – auf Vektoren

#define MAXLINES 5000

char *lineptr [MAXLINES];

7. Zeiger und Vektoren 103 Programmierung I

3) Argumente aus der Kommandozeile

Kommen auch unter Windows noch vor…

7. Zeiger und Vektoren 104 Programmierung I


2. Beispiel: Aufruf aus Powerpoint

7. Zeiger und Vektoren 105 Programmierung I

Klassisch…:
main (int argc, char *argv[])
{...}

Zeiger auf einen Vektor von Zeigern auf Zeichenketten 


(= Vektoren)

Anzahl der Argumente der Kommandozeile incl. Programmname

Beispiel: Das Unix-Kommando echo  echo hello world

argc: 3

argv: echo\0
hello\0
world\0

7. Zeiger und Vektoren 106 Programmierung I


#include "stdio.h"

main (int argc, char *argv[])


{
int i;
"echo" soll selbst nicht mit ausgegeben werden
for (i = 1; i < argc; i++)
printf ("%s%s", argv [i], (i < argc-1) ? " ": "");
printf ("\n");
return 0; #include "stdio.h"
}
main (int argc, char *argv[])
{
while (--argc > 0)
printf ("%s%s", *++argv, (argc > 1) ? " ": "\n");
return 0;
}

7. Zeiger und Vektoren 107 Programmierung I

4) Probleme bei Zeichenketten-Feldern

So weit, so gut …

7. Zeiger und Vektoren 108 Programmierung I


Feld von Zeichenketten…

7. Zeiger und Vektoren 109 Programmierung I

7. Zeiger und Vektoren 110 Programmierung I

Das könnte Ihnen auch gefallen