Programmierung mit C Zeiger

Ähnliche Dokumente
C++ - Einführung in die Programmiersprache Zeiger, Referenzen und Strukturen. Leibniz Universität IT Services Anja Aue

2. Programmierung in C

Zeiger (engl. Pointer)

Inhalt. 4.5 Arbeit mit Zeigern (engl. Pointer)

INE1 Arrays, Zeiger, Datenstrukturen

Zeiger in C und C++ Zeiger in Java und C/C++

Zeiger und dynamischer Speicher

Algorithmen und Datenstrukturen

Zeiger, Arrays und Strings in C und C++

F Zeiger, Felder und Strukturen in C

C++ Teil 5. Sven Groß. 16. Nov Sven Groß (IGPM, RWTH Aachen) C++ Teil Nov / 16

Zeiger in C und C++ Zeiger in Java und C/C++

Zeiger. C-Kurs 2012, 2. Vorlesung. Tino Kutschbach 10.

C++ Teil 5. Sven Groß. 8. Mai IGPM, RWTH Aachen. Sven Groß (IGPM, RWTH Aachen) C++ Teil 5 8. Mai / 16

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny

Einführung in die Programmierung II. 5. Zeiger

C++ Teil 5. Sven Groß. 13. Mai Sven Groß (IGPM, RWTH Aachen) C++ Teil Mai / 18

C- Kurs 09 Dynamische Datenstrukturen

C++ - Objektorientierte Programmierung Konstante und statische Elemente

Projekt 3 Variablen und Operatoren

C- Kurs 08 Zeiger. Dipl.- Inf. Jörn Hoffmann leipzig.de. Universität Leipzig Ins?tut für Informa?k Technische Informa?

Teil 5: Zeiger, Felder, Zeichenketten Gliederung

C++ - Objektorientierte Programmierung Konstruktoren und Destruktoren

1. Referenzdatentypen: Felder und Strings. Referenz- vs. einfache Datentypen. Rückblick: Einfache Datentypen (1) 4711 r

1. Referenzdatentypen: Felder und Strings

2. Programmierung in C

8. Referenzen und Zeiger

RO-Tutorien 15 und 16

Arrays. Theorieteil. Inhaltsverzeichnis. Begriffe. Programmieren mit Java Modul 3. 1 Modulübersicht 3

PROCESSING EINE ZUSAMMENFASSUNG. Created by Michael Kirsch & Beat Rossmy

RO-Tutorien 3 / 6 / 12

Variablen, Konstanten und Datentypen

Crashkurs C++ - Teil 1

Programmierkurs C++ Datenstrukturen Seite 1

Teil 5: Felder, Zeiger, Zeigerarithmetik Gliederung

int i=1; //Integerzahl i anlegen und mit 1 initialisieren float wert; //Floatzahl deklarieren scanf( %f,&wert); //Wert über Tastatur eingeben

ÜBUNGS-BLOCK 7 LÖSUNGEN

9. Vektoren. (auch Felder/array)

Felder (Arrays) und Zeiger (Pointers) - Teil I

Programmieren in C. Eine Einführung in die Programmiersprache C. Prof. Dr. Nikolaus Wulff

Einstieg in die Informatik mit Java

Vorlesung Programmieren

Zeiger: Der Adressoperator &

Betriebssysteme, Rechnernetze und verteilte Systeme 1. Crashkurs C (2)

Felder, Zeiger und Adreßrechnung

6 ZEIGER UND REFERENZEN - ALLGEMEINES

einlesen n > 0? Ausgabe Negative Zahl

Welche Informatik-Kenntnisse bringen Sie mit?

Vorkurs Informatik: Erste Schritte der Programmierung mit C++

Objekte. Theorieteil. Inhaltsverzeichnis. Begriffe. Programmieren mit Java Modul 5. 1 Modulübersicht 3

Grundlagen der Informatik 11. Zeiger

Kapitel 8. Adressen und Zeiger

Herzlich willkommen!

5.4 Arrays. Oft müssen viele Werte gleichen Typs gespeichert werden. Idee: Lege sie konsekutiv ab! Greife auf einzelne Werte über ihren Index zu!

Arrays. Einleitung. Deklarieren einer Array Variablen

Teil 8: Dynamische Speicherverwaltung. Prof. Dr. Herbert Fischer Fachhochschule Deggendorf Prof. Dr. Manfred Beham Fachhochschule Amberg-Weiden

Variablen. Deklaration: «Datentyp» «Variablenname» Datentyp bestimmt Größe in Bytes: sizeof Beispiel: long int v; Größe: 4 Bytes

Klassen als Datenstrukturen

Viel Erfolg bei der Bearbeitung der Aufgaben!

Kapitel 3: Variablen

Beispiel. Problem: mehrteilige Nachnamen (von Goethe, Mac Donald, Di Caprio)

7.2 Dynamischer Speicher in Objekten/Kopierkonstruktor

Einführung in C. EDV1-04C-Einführung 1

Typ : void* aktuelle Parameter Pointer von beliebigem Typ

Institut für Programmierung und Reaktive Systeme. Java 2. Markus Reschke

Funktionen. mehrfach benötigte Programmteile nur einmal zu schreiben und mehrfach aufzurufen

3.2 Datentypen und Methoden

Organisatorisches. Folien (u.a.) gibt's auf der Lva-Homepage zum Download

Java Einführung Klassendefinitionen

Elementare Datentypen in C++

C-Programmierung: Ausdrücke und Operatoren#Division.2F

6. Zeiger Allgemeines Definition eines Zeigers

7 Funktionen. 7.1 Definition. Prototyp-Syntax: {Speicherklasse} {Typ} Name ({formale Parameter});

Programmierung in C. Grundlagen. Stefan Kallerhoff

Transkript:

Programmierung mit C Zeiger

Zeiger (Pointer)... ist eine Variable, die die Adresse eines Speicherbereichs enthält. Der Speicherbereich kann... kann den Wert einer Variablen enthalten oder... dynamisch allokiert sein.... verweist auf einen bestimmten Bereich im Speicher.... enthält eine Referenz auf eine andere Variable. Zeiger werden genutzt, um... Speicherbereiche dynamisch zu verwalten.... Adressen von Datenobjekten direkt an Funktionen zu übergeben.... Funktionen als Argumente an andere Funktionen zu übergeben.... Datenstrukturen wie Listen, Bäume, Stacks und Queues zu implementieren. Zeiger... führen dazu, dass die Programmstruktur häufig unübersichtlich wird.... sind die häufigste Fehlerquelle in C.... erfordern Disziplin vom Programmierer. Programmieren mit C 19.03.07 Folie 2

Zeiger deklarieren Datentyp *Name_der_Zeigervariablen Jeder Datentyp benötigt eine bestimmte Menge an Speicher. Der Zeiger zeigt auf den Anfang des definierten Speicherbereichs. Der Zeiger wird mit demselben Datentyp vereinbart wie die Variable, auf die er zeigt. Wichtig für Zeigerarithmetik! Das Sternchen gekennzeichnet die Variable als Zeiger. Der Variablenname ist eindeutig und spiegelt die Nutzung der Variablen wieder. Programmieren mit C 19.03.07 Folie 3

Beispiel int main(void) { int *zeigerint; char *zeigerchar; float *zeigerfloat; /* ptrint ist als Zeiger deklariert. */ /* ptrganz ist eine Variable */ int *ptrint, ptrganz; Programmieren mit C 19.03.07 Folie 4

Grafische Darstellung $00401000 $00401004 $00401008 1 2.5 float *zeiger int *zeiger $0040100C $00401010 'A' 31...0 char *zeiger Programmieren mit C 19.03.07 Folie 5

Hinweise int *ptrxpoint, *ptrypoint, *ptrzpoint, ptrpoint; Hier wird jede Variable als Zeiger gekennzeichnet. Der Programmier kann auf einen Blick sehen, welche Variablen als Zeiger genutzt werden oder nicht. int* ptrxpoint, ptrypoint, ptrzpoint, ptrpoint; ptrxpoint wird als Zeiger deklariert. Alle anderen Namen sind Synonyme für Variablen. int * ptrxpoint; int*ptrypoint; Leerzeichen werden vom Compiler ignoriert. Ein Zeiger wird gelesen als "Der Inhalt, auf den der Zeiger verweist, ist ein int.". Der Name des Zeigers symbolisiert den Verweis. Aus diesem Grund sollte das Sternchen (Asterisk) direkt vor dem Namen stehen. Programmieren mit C 19.03.07 Folie 6

Zeiger initialisieren Name_der_Zeigervariablen = &Variable; Der Zeiger wird mit der Adresse einer vorher bekannten Variablen initialisiert. Der Zeiger besitzt als Wert die Adresse der Variablen, auf die er zeigt. Das kaufmännische UND-Zeichen wird als Adressoperator bezeichnet. Es wird die Adresse der Variablen an den Zeiger übergeben und nicht der Wert der Variablen. Zwischen dem kaufmännischen Zeichen und dem Variablennamen darf kein Leerzeichen stehen. Wenn einem Zeiger keine Adresse, sondern ein Wert zugewiesen wird, wird eine Warnung ausgegeben. Programmieren mit C 19.03.07 Folie 7

Beispiel int main(void) { int *zeigerint; int summe; summe = 12345; zeigerint = &summe; Speicherort der Variablen summe zeigerint 0000 xxxx 0108 Adresse 0000 0100 xxxx 0000 0104 xxxx 0000 0108 12345 xxxx 0000 010C xxxx Programmieren mit C 19.03.07 Folie 8

Dereferenzierung *Zeigervariable = Ausdruck; Das Sternchen wird als Dereferenzierungsoperator bezeichnet. Mit Hilfe des Dereferenzierungsoperator wird der Wert verändert, auf den der Zeiger zeigt. Der Zeiger besitzt als Wert eine Adresse. An dieser Adresse ist ein Datenwort hinterlegt. Das Datenwort an dieser Adresse wird mit Hilfe des Dereferenzierungsoperators und des Zeigers verändert. Der Wert des Zeigers selber wird nicht verändert. Wenn Sie einen Zeiger innerhalb eines Ausdrucks nutzen, klammern Sie die Dereferenzierung! Programmieren mit C 19.03.07 Folie 9

Beispiel int main(void) { int *zeigerint; int summe; summe = 12345; zeigerint = &summe; *zeigerint = 67890; Speicherort der Variablen summe 0000 0100 xxxx 0000 xxxx 0108 0000 0104 0000 0108 0000 010C xxxx 12345 67890 xxxx xxxx zeigerint Adresse Programmieren mit C 19.03.07 Folie 10

Die Adresse einer Variablen ausgeben int main(void) { int wert; wert = 5; printf("der Wert: %d\n", wert); In diesem Fall wird der Wert der Variablen wert als Integer auf dem Bildschirm ausgegeben. printf("die Adresse: %p\n", &wert); return 0; Mit Hilfe des Formatzeichens %p wird eine Adresse auf dem Bildschirm ausgegeben. Wenn der Adressoperator dem Variablennamen voran gestellt ist, wird die Adresse der Variablen ausgegeben. Programmieren mit C 19.03.07 Folie 11

NULL-Zeiger Ein Null-Zeiger zeigt auf keine gültige Adresse und ist mit 0 initialisiert. Die Verwendung der Null für unbenutzte Zeiger ist eine Konvention der Programmierer! Es gibt verschiedene Möglichkeiten einen NULL-Zeiger zu erzeugen. char *ptr = 0; Dem Zeiger wird eine 0 zugewiesen. #define NULL (void *) 0 int *ptr = NULL; Es wird eine Konstante definiert, die einen Zeiger mit 0 initialisiert. #include <stdef.h> int *ptr =NULL; Es wird die vorgefertigte Konstante aus der Bibliothek <stdef.h> genutzt. Programmieren mit C 19.03.07 Folie 12

NULL-Zeiger #include <stdio.h> #define NULL (void *) 0 #include <stdlib.h> int main(void) { int *pointer; pointer = NULL; Hier wird die vordefinierte Konstante NULL als Makro definiert. if (NULL == pointer) { printf("keine gueltige Adresse\n"); else { *pointer = 3; system("pause"); return 0; Warum wird die Reihenfolge Konstante == Variable gewählt? Programmieren mit C 19.03.07 Folie 13

void-zeiger... werden als untypisierte oder generische Zeiger bezeichnet. Ein Zeiger vom Datentyp void ist ein typenloser Zeiger.... ist zu jedem Datentyp kompatibel.... werden genutzt, wenn die Größe des Speicherbereichs nicht bekannt ist.... kann eine beliebige Adresse zugewiesen werden. Programmieren mit C 19.03.07 Folie 14

Beispiel #include <stdio.h> int main(void) { void *pointer; int wert; wert = 10; pointer = (int *)&wert; Hier findet eine Typumwandlung eines Zeigers in der Form pointer = (Datentyp *)&Variable statt. Der Zeiger wird mit einem Verweis auf eine Variable vom Datentyp Integer initialisiert. Einen void-zeiger kann jeder andere Zeigertyp zugewiesen werden. *(int *)pointer = 100; printf("pointer = %p, %d", pointer, wert); return 0; Programmieren mit C 19.03.07 Folie 15

Beispiel #include <stdio.h> int main(void) { void *pointer; int wert; wert = 10; pointer = (int *)&wert; Hier findet eine Dereferenzierung eines void-zeigers in der Form *(Datentyp *)pointer = Ausdruck; statt. Der void-zeiger kann nicht direkt dereferenziert werden. Zuerst wird ein temporärer Zeiger vom Datentyp int erzeugt. Dieser temporärer Zeiger wird dereferenziert. *(int *)pointer = 100; printf("pointer = %p, %d", pointer, wert); return 0; Programmieren mit C 19.03.07 Folie 16

Zeiger-Arithmetik Folgende Operationen können mit Zeigern ausgeführt werden: Addition von Ganzzahlwerten. Subtraktion von Ganzzahlwerten. Inkrementieren. Dekrementieren. Ein Zeiger wird immer um ein Vielfaches der Speichergröße seines Datentyps erhöht oder erniedrigt. Das Arbeiten mit Vergleichsoperatoren ist erlaubt. Wird häufig bei Arrays eingesetzt. int main(void) { int *pointer; int wert; pointer = &wert; pointer += 10; pointer--; return 0; Programmieren mit C 19.03.07 Folie 17

Beispiel int main() { int *pointer; int feld[] = {'a', 'b', 'c', 'd', 'e', 'f'; pointer = &feld[0]; pointer += 2; return 0; a b c d e f pointer pointer Programmieren mit C 19.03.07 Folie 18

Zeiger einem anderen Zeiger zuweisen Mit Hilfe des Zuweisungsoperator wird einem Zeiger der Wert eines anderen Zeigers zugewiesen. Beide Zeiger zeigen auf die gleiche Adresse und können den Wert an dieser Adresse verändern. Wenn der Wert eines Zeigers an einen anderen Zeiger zugewiesen wird, wird kein Adressoperator benötigt. int main(void) { int *pointer; int *zeiger; int wert; pointer = &wert; zeiger = pointer; *zeiger = 5; *pointer = *zeiger * 2; return 0; Programmieren mit C 19.03.07 Folie 19

Zeiger auf Zeiger Ein Zeiger zeigt auf einen Zeiger, der wiederum auf den Wert einer Variablen zeigt. Mehrfach-Indirektion.... werden für die Matrizenberechnung eingesetzt. Ein Zeiger auf Zeiger wird folgendermaßen deklariert: datentyp **Name; Mit Hilfe von Zeiger_Zeiger = &Zeiger; wird dem Zeiger die Adresse eines anderen Zeigers zugewiesen. Die Anweisung **Zeiger_Zeiger = ausdruck; verändert den Wert an der Adresse, die in dem Zeiger abgelegt ist, auf den der Zeiger zeigt. Die Anweisung *Zeiger_Zeiger = wert; würde dem Zeiger auf Zeiger eine neue Adresse zuweisen, die einen beliebigen Wert besitzt. Programmieren mit C 19.03.07 Folie 20

Beispiel int main(void) { int *pointer; int wert; wert = 10; pointer = &wert; Speicherort der Variablen wert return 0; pointer 0000 xxxx 0108 Adresse 0000 0100 xxxx 0000 0104 xxxx 0000 0108 xxxx 10 0000 010C xxxx Programmieren mit C 19.03.07 Folie 21

Beispiel int main(void) { int *pointer; int **ptr_pointer; int wert; wert = 10; pointer = &wert; ptr_pointer = &pointer; Speicherort der Variablen wert return 0; ptr_pointer Adresse xxxx pointer pointer 0000 xxxx 0108 Adresse 0000 0100 xxxx 0000 0104 xxxx 0000 0108 xxxx 10 0000 010C xxxx Programmieren mit C 19.03.07 Folie 22

Übergabe von Werten als Argument einer Funktion void malzwei(float zahl ) { zahl = (zahl) * 2; int main(void) { float wert; wert = 2.5 malzwei(wert); return 0; Stack 2.5 xxxx xxxx xxxx Speicheradresse 0000 0100 xxxx 0000 0104 xxxx 0000 0108 2.5 0000 010C xxxx Programmieren mit C 19.03.07 Folie 23

Übergabe von Adressen als Argument einer Funktion void malzwei(float *zahl ) { *zahl = (*zahl) * 2; int main(void) { float wert; wert = 2.5 malzwei(&wert); return 0; Programmieren mit C 19.03.07 Folie 24

Übergabe von Adressen als Argument einer Funktion void malzwei(float *zahl ) { *zahl = (*zahl) * 2; int main(void) { float wert; wert = 2.5 malzwei(&wert); return 0; Der Funktion wird ein Zeiger als Argument übergeben. Der Zeiger sollte auf Werte vom Datentyp float zeigen. Mit Hilfe des Zeigers kann die Funktion Werte an der angegebenen Adresse verändern. Bedenken Sie, das der Zugriff auf die Adresse auch ungewollte Änderungen erlaubt. Programmieren mit C 19.03.07 Folie 25

Übergabe von Adressen als Argument einer Funktion void malzwei(float *zahl ) { *zahl = (*zahl) * 2; int main(void) { float wert; wert = 2.5 malzwei(&wert); return 0; Mit Hilfe der Dereferenzierung wird der Wert an der Adresse, auf die der Zeiger verweist, verändert. Hier wird der Wert an der angegebenen Adresse mal zwei genommen und anschließend das Ergebnis an der angegebenen Adresse gespeichert. Programmieren mit C 19.03.07 Folie 26

Übergabe von Adressen als Argument einer Funktion void malzwei(float *zahl ) { *zahl = (*zahl) * 2; int main(void) { float wert; wert = 2.5 malzwei(&wert); return 0; Der Funktion wird die Adresse der Variablen wert übergeben. Der Variablennamen beginnt mit dem Adressoperator. Hier wird nicht der Wert der Variablen übergeben, sondern die Adresse der Variablen. Programmieren mit C 19.03.07 Folie 27

Übergabe von Adressen als Argument einer Funktion void malzwei(float *zahl ) { *zahl = (*zahl) * 2; int main(void) { float wert; wert = 2.5 malzwei(&wert); return 0; Stack 0000 0108 xxxx xxxx xxxx Speicheradresse 0000 0100 xxxx 0000 0104 xxxx 0000 0108 2.5 0000 010C xxxx Programmieren mit C 19.03.07 Folie 28

Funktionsadresse Eine Funktion hat eine physikalische Adresse im Speicher, die einem Zeiger zugewiesen werden kann. Diese Adresse ist der Eingangspunkt der Funktion und wird beim Aufruf der Funktion genutzt. Wenn ein Zeiger auf diese Adresse zeigt, kann die Funktion darüber aufgerufen werden. Der Funktionsname ohne Klammern oder Argumenten enthält als Wert die Adresse im Speicher. Programmieren mit C 19.03.07 Folie 29

Funktionszeiger Funktiontyp (*Zeiger)(Argument1,..., ArgumentN);... können Funktionen als Argumente an andere Funktionen übergeben werden. Der Zeiger verweist auf eine Funktion von einem bestimmten Datentyp Funktionstyp ist abhängig vom Datentyp (Rückgabewert) der Funktion. Die Deklaration des Zeigers muss aufgrund der Prioritäten von Operatoren immer geklammert werden. In Klammern steht die Anzahl der Argumente und deren Datentyp entsprechend der Funktion, auf die der Zeiger zeigt. Programmieren mit C 19.03.07 Folie 30

Beispiel #include <stdio.h> int Antwort(int zahl) { return zahl; int main(){ int (*ptr)(int) = Antwort; printf("%d\n", ptr(3)); return 0; Programmieren mit C 19.03.07 Folie 31

Konstante Zeiger const Datentyp *Pointer Zeiger auf einen konstanten Wert. Der Zeiger selber ist nicht konstant und kann verändert werden. Datentyp *const Pointer Zeiger auf einen variablen Wert. Der Zeiger selber ist konstant und kann nicht verändert werden. const Datentyp *const Pointer Zeiger zeigt auf einen konstanten Wert. Der Zeiger ist konstant. Diese Art wird sehr selten genutzt. Programmieren mit C 19.03.07 Folie 32

Beispiel const char constchar = 'A'; char nonconstchar = 'a'; const char *ptrconstwert; char *const ptrconstzeiger = &nonconstchar; ptrconstwert = &constchar; /* Fehler: Veränderung einer Konstante */ *ptrconstwert = 'B'; ptrconstwert = &nonconstchar; /* Fehler: Veränderung einer Konstante */ *ptrconstwert = 'B'; Programmieren mit C 19.03.07 Folie 33

Beispiel const char constchar = 'A'; char nonconstchar = 'a'; const char *ptrconstwert; char *const ptrconstzeiger = &nonconstchar; *ptrconstwert++; /* Zeiger nicht konstant */ /* Fehler: Konstanter Zeiger */ ptrconstzeiger = &ConstChar; /* Verweis auf einen variablen Wert */ *ptrconstzeiger = 'B'; Programmieren mit C 19.03.07 Folie 34

Ein Zitat von Howard und LeBlanc (2003) Zeiger (engl. Pointer) gehören zu den fehleranfälligsten Bereichen moderner Programmiertechniken. Etliche moderne Sprachen wie Java, C# und Visual Basic stellen daher gar keinen Datentyp für Zeiger zur Verfügung. Der Einsatz von Zeigern ist von Haus aus kompliziert und erfordert von Ihnen ein exzellentes Verständnis der Speicherverwaltung Ihres Compilers. Viele verbreitete Sicherheitsprobleme, insbesondere Pufferüberläufe, lassen sich auf Fehler bei der Benutzung von Zeigern zurückführen. Zitat aus Das C-Lösungsbuch ; Clovis L. Tondo, Scot E. Gimpel Quelle: /5/ Programmieren mit C 19.03.07 Folie 35

Mögliche Fehler Bei der Deklaration eines Zeigers, wird nur der Zeiger angelegt, aber nicht das Objekt worauf er zeigt. Zeiger müssen initialisiert werden, andernfalls können Datenbereiche... des eigenen Programms oder... anderer Programm oder... des Betriebssystems überschrieben werden. Folgende Zuweisung erzeugt keinen Compiler-Fehler: int *pointer; *pointer = 100; Programmieren mit C 19.03.07 Folie 36