• Keine Ergebnisse gefunden

Ziele dieser Einheit:

N/A
N/A
Protected

Academic year: 2022

Aktie "Ziele dieser Einheit:"

Copied!
15
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

10. Zeiger-Datentyp

Ziele dieser Einheit:

- Einführung dynamischer Datentypen und deren

Anwendung (in erster Näherung, als Vorbereitung auf verkettete Listen und Dateiverarbeitung).

- Einblick in C-spezifischen Umgang mit Zeiger-Datentypen

(„Zeiger-Arithmetik“).

(2)

10.1 Sinn des Zeiger-Datentyps, speziell in C

- Realisierung dynamischer Datenstrukturen, bei denen die Größe (Speicherbedarf) erst zur Laufzeit bekannt wird (Listen-,

Dateiverarbeitung).

- Effizienzsteigerung durch hardwarenahe Programmierung, z.B.

Rechnen mit Absolut-/Relativ-Adressen, wahlfreien Direktzugriff auf Daten etc. durch

ƒ Zeiger-Arithmetik in C: Operatoren + (Addition) und – (Subtraktion) speziell für Zeiger definiert.

ƒ Parameterübergabe zwischen aufrufendem Programm (Hauptprogramm) und aufgerufenem Unterprogramm (Funktion).

Beispiel: scanf(“ %c“, &zeichen)

- ABER: Nicht bzw. falsch initialisierte Zeiger können zu schwer erkenn- baren Fehlern und Systemabstürzen führen!

(3)

10.2 Definition von Zeigern

ƒ Zeiger: pInt ist ein Integer-Zeiger (Inhalt: die Hexadezimal-

Adresse af00 – die Speicheradresse (&zhl) der Variablen zhl).

ƒ Gezeigte: Inhalt des Speichers, auf den pInt zeigt, ist eine ganze Zahl (Integer-Variable, hier 20).

Definition eines Zeiger-Datentyps

Bezeichner

Datentyp *

- Beispiel: int *pInt; /* Zeiger */

int zhl = 20;

pInt = &zhl;

- Zeiger-Variablen werden mit dem * Operator deklariert.

0xaf00 pInt

20 zhl

af00

(4)

- int* i,j; entspricht int *i; int j;

- Adressoperator & liefert die Speicheradresse einer Variablen.

Beispiel: int idx;

int *pIdx; /* Definition eines Zeigers */

pIdx = &idx; /* pIdx zeigt jetzt auf die Variable idx */

- Dereferenzierungsoperator : * (Inhaltsoperator)

Achtung: der *-Operator wird auch zur Definition eines Zeigers benutzt.

Beispiel: int idx, zahl;

int *pIdx = &idx;

zahl = *pIdx; /* *pIdx liefert den Inhalt von idx */

Bemerkungen

(5)

Beispiel (1):

Gezeigte (Bezugs-)Variable:

• Wert: 10

• Adresse: 0xa004

• Typ: int

• Name: idx (symb. Adr.)

• Definition: int idx;

• Wert: 0xa004

• Adresse: 0xa00b

• Typ: Zeiger auf int

• Name: pIdx (symb. Adr.)

• Definition: int *pIdx;

Zeiger-Variable 10

0xa004 0xa004

(idx)

0xa00b

(*pIdx)

Arbeitsspeicher:

...

(6)

Beispiel (2):

- Inhalt von idx: Wert 10

- Inhalt von &idx: Adresse 0xa004

- &idx liefert 0xa004

- &pIdx liefert 0xa00b

- *pIdx liefert 10 int idx;

0xa004

0xa00b

Arbeitsspeicher:

10 idx = 10;

0xa004

pIdx = &idx;

int *pIdx;

(7)

Beispiele:

*pInt2 = *pInt1;

10

... ... 10

pInt1 *pInt1 pInt2 *pInt2

10

*pInt1 ...

pInt1

30 ...

pInt2 *pInt2

*pInt1 = 10; *pInt2 = 30;

pInt2 = pInt1;

10

*pInt1(*pInt2)

... ... 10

pInt1 pInt2

int *pInt1 = &...

int *pInt2 = &...

*pInt1 = 5;

5

... ... 10

pInt1 *pInt1(*pInt2) pInt2

(8)

#include <stdio.h>

void main() {

short zahl = 10;

short *pShort; /* Pointer/Zeiger auf short-Variable */

pShort = &zahl; /* pShort zeigt auf zahl */

printf("Wert %d \n", *pShort);

/* Ausgabe : Wert 10 */

}

Beispiel (3):

(9)

- Feldbezeichner werden bei Bedarf automatisch in Zeiger auf die erste Komponente umgewandelt.

Beispiel: *(vektor+idx) /* Feldbezeicher: vektor */

10.3 Felder und Zeiger

for (idx=0; idx<5; idx++) {

vektor [idx] = 0;

}

for (idx=0; idx<5; idx++) {

*(vektor+idx) = 0;

}

int vektor[5]; /* Feldbezeichner: vektor */

int idx;

- Enger Zusammenhang zwischen Feldern (Arrays) und Zeigern.

- Feldverarbeitung mittels Zeiger und spezieller Arithmetik darauf.

- Beispiel: Es gelten folgende Vereinbarungen:

- Folgende Code-Fragmente bewirken dann das gleiche (Initialisierung):

(10)

int vektor [10];

int *pInt = vektor;

int idx = ..;

Dann gilt:

ƒ *(pInt+idx) entspricht vektor[idx] (Inhalt einer Komponente)

ƒ pInt+idx entspricht &vektor[idx] (Adresse einer Komponente) -Beispiel: Folgende Vereinbarungen mögen gelten:

vektor:

pInt:

*(pInt+1)

*(pInt+2)

pInt+9

Inhalt Inhalt

Adresse Adresse

Beispiel:

..

(11)

10.4 Felder von Zeigern

- Folgendes Programmfragment veranschaulicht das:

int zhl = 7;

int *pVektor[5]; /* Feld mit 5 Zeigern auf int */

...

pVektor[3] = &zhl;

...

printf("%d \n", *pVektor[3]);

7

pVektor:

- Feldelemente können aus Zeigern bestehen.

Beispiel:

(12)

- Bei der Addition/Subtraktion von ganzen Zahlen auf einen Zeiger wird automatisch die Größe des Datentyps berücksichtigt.

Beispiel:

Inhalt von pInt 0xa004

pInt + 1 0xa004+4 = 0xa008

10.5 Zeiger-Arithmetik

int vektor[5];

int *pInt = vektor, idx;

for (idx=0; idx<5; idx++) {

pInt = pInt + 1; /* entspricht pInt++ */

*pInt = 0;

printf("Komponente %d hat die Adresse %d \n", idx, pInt);

}

- Für Zeiger-Variablen sind spezielle Additions-/Subtraktions-Operatoren definiert (dargestellt durch die üblichen Zeichen: + und –).

Beispiel:

(13)

- Folgende Definitionen sind möglich:

a) char nachricht1[11] = “Hallo Welt“; /* Feld */

b) char nachricht2[] = “Hallo Welt“; /* Feld */

c) char *pNachricht = “Hallo Welt“; /* Zeiger */

- Fall a) und b) sind identisch:

ƒ Jeweils Platz für 11 Zeichen reserviert.

ƒ Ihre Inhalte sind beliebig veränderbar.

ƒ nachricht1 und nachricht2 sind (als Adressen) nicht veränderbar.

- Fall c) ist anders:

ƒ Platz für einen char-Zeiger reserviert.

ƒ Änderungen des Inhalts sind systemabhängig.

ƒ pNachricht ist veränderbar.

10.6 Zeichenketten (Strings)

(14)

H a l l o W e l t \0

Beispiel:

H a l l o W e l t \0

nachricht1 pNachricht

Bemerkungen:

- Strings sind in C kein echter Datentyp.

- Direkte Vergleiche (==) sind nicht möglich.

- Zuweisungen haben oft unerwünschte Ergebnisse („Seiteneffekte“).

- C bietet Funktionen zur Stringbehandlung (#include <string.h>)

(15)

- Beispiel:

struct complex {float re, im;};

struct complex cmpl_zhl;

struct complex *pCmpl_zhl = &cmpl_zhl;

- Zugriff auf die einzelnen Komponenten mit ->

Es gilt: cmpl_zhl.re bzw. cmpl_zhl.im Aber: pCmpl_zhl->re bzw. pCmpl_zhl->im

- pCmpl_zhl->re ist gleichwertig zu (*pCmpl_zhl).re

10.7 Zeiger auf Strukturen

Referenzen

ÄHNLICHE DOKUMENTE

Dies geschieht durch Dezentralisierung und Schaffung interner Märkte, in denen autonom agie- rende Marktparteien (Profit Centers, Fertigungsseg- mente etc.) auftreten. Auf der

Logically separating version visibility checks from the index structure and operations, as in the traditional version-oblivious index, leads to ver- sion management overhead:

Ich bin damit einverstanden, dass die vorgenannten Kontaktdaten zu Vereinszwecken durch den Verein genutzt und hierfür auch an andere Mitglieder des Vereins weitergegeben

Das Mengengerüst des Ist-Zustandes wurde aus betrieblichen Unterlagen, einer Befragung der Belegschaft sowie anhand repräsentativer Baugruppen verfolgter Arbeitsabläufe ermittelt

(4) Als Abfälle gelten Sachen, deren geordnete Erfassung und Behandlung im öffentlichen Interesse (§ lAbs. 3) geboten ist, auch dann, wenn sie eine die Umwelt beeinträchtigende

⋅ wenn zufolge der Anzahl der anwesenden Personen (z.B. Mehrheit von Parteien) die soziale Distanz nicht eingehalten werden kann und ein Ausweichen in einen grösse- ren Saal

Immerhin lässt es sich mit dem temporalen Faktor begründen, dass die Veränderungen in dem Zeitraum von nur fünf Jahren (2011 und 2016) nicht so sichtbar wie in dem Zeitraum

Wenn man für einen anderen Menschen sorgt, ohne ver- wandtschaftliche Beziehung und oft auch ohne offizielle An- erkennung, so hat man meiner Ansicht nach etwas zutiefst