Inhalt. 4.5 Arbeit mit Zeigern (engl. Pointer)

Ähnliche Dokumente
Programmierung mit C Zeiger

Inhalt. Peter Sobe 63. Felder in C

Zusammenfassung des Handzettels für Programmieren in C

2. Programmierung in C

Einheit Variablen in der Programmiersprache C Variablen-Modell, Variablen-Vereinbarungen

Inhalt. 4.7 Funktionen

2. Programmierung in C

Einführung in die Programmierung Arrays, Zeiger, Strings. Arvid Terzibaschian

Programmieren in C. Zeiger und Zeichenketten. Prof. Dr. Nikolaus Wulff

JAVA-Datentypen und deren Wertebereich

Java Einführung VARIABLEN und DATENTYPEN Kapitel 2

Deklarationen in C. Prof. Dr. Margarita Esponda

Dr. Monika Meiler. Inhalt

Welche Informatik-Kenntnisse bringen Sie mit?

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny

Elementare Datentypen in C++

Zeiger: Der Adressoperator &

Programmieren in C++ Arrays, Strings und Zeigerarithmetik

Einstieg in die Informatik mit Java

+ C - Array (Vektoren, Felder)

Programmiersprachen Einführung in C

Javaprogrammierung mit NetBeans. Variablen, Datentypen, Methoden

Modellierung und Programmierung 1

Primitive Datentypen und Felder (Arrays)

Java - Zahlen, Wahrheitswerte und Zeichen. Leibniz Universität IT Services Anja Aue

Kapitel 3: Variablen

RO-Tutorien 3 / 6 / 12

Modul 122 VBA Scribt.docx

Übung zur Vorlesung Programmieren in C

Algorithmen und Programmierung II

Einführung in die C++ Programmierung für Ingenieure

Die Programmiersprache C

Einstieg in die Informatik mit Java

Java - Zahlen, Wahrheitswerte und Zeichen. Leibniz Universität IT Services Anja Aue

3. Datentypen, Ausdrücke und Operatoren

Grundlagen der Programmiersprache C++

Javakurs für Anfänger

Erste Schritte der Programmierung in C

C allgemein. C wurde unter und für Unix entwickelt. Vorläufer sind BCPL und B.

Mikrocomputertechnik. Adressierungsarten

Unterprogramme, Pointer und die Übergabe von Arrays

C/C++ Programmierung

Objektorientiertes Programmieren für Ingenieure

Übungen zur Vorlesung Computergrundlagen WS 2008/09 Fakultät Physik, Universität Stuttgart Jens Harting, Martin Hecht, Bibhu Biswal Blatt 14

Einführung in die Programmiersprache C

Zusammengesetzte Datentypen -- Arrays und Strukturen

Pass by Value Pass by Reference Defaults, Overloading, variable Parameteranzahl

C kompakt für Java-Programmierer

Kurzeinführung in C++

Die Programmiersprache C99: Zusammenfassung

Modellierung und Programmierung

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Kurzeinführung in C. Johannes J. Schneider

Hello World. Javakurs 2014, 1. Vorlesung. Sebastian Schuck. basierend auf der Vorlage von Arne Kappen. wiki.freitagsrunde.org. 3.

Objektorientierte Programmierung OOP Programmieren mit Java

Programmieren in C / C++ Grundlagen C 2

Kapitel 5. Datentypen und Operatoren

String s1, s2; Eine Zuweisung geschieht am einfachsten direkt durch Angabe des Strings eingeschlossen in doppelte Hochkommata:

2 Einfache Rechnungen

5. Unterprogrammtechnik/Module

Elementare Konzepte von

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 18

C-Propädeutikum Höhere Datentypen

Grundlagen der Informatik I (Studiengang Medieninformatik)

Technische Infor matik 2 C/C++-Kurs. Pointer und Arrays AG Rechner netze 2.1

Modul Entscheidungsunterstützung in der Logistik. Einführung in die Programmierung mit C++ Übung 1

C++ - Einführung in die Programmiersprache Funktionen. Leibniz Universität IT Services Anja Aue

Einstieg in die Informatik mit Java

9 Zeiger (Pointer). Dynamischer Speicher

Das Typsystem von Scala. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala

Einführung in die Programmiersprache C und in den C166-Compiler

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein

Der Datentyp String. Stringvariable und -vergleiche

Felder, Rückblick Mehrdimensionale Felder. Programmieren in C

4.2 Basisdatentypen und einfache Anweisungen

Einführung in die Programmierung

Proseminar C-Programmierung. Strukturen. Von Marcel Lebek

Kapitel 7. Zusammengesetzte Datentypen, Vektoren, Zeichenketten

Kurze Einführung in die Programmiersprache C++ und in Root

PROGRAMMIEREN MIT C. }, wird kompiliert mit dem Befehl. (-o steht für output) und ausgeführt mit dem Befehl

Kodierung. Kodierung von Zeichen mit dem ASCII-Code

2. Programmierung in C

Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden.

Prof. W. Henrich Seite 1

Hochschule Niederrhein Einführung in die Programmierung Prof. Dr. Nitsche. Bachelor Informatik WS 2015/16 Blatt 3 Beispiellösung.

Moderne C-Programmierung

Programmieren in C. C Syntax Datentypen, Operatoren und Kontrollstrukturen. Prof. Dr. Nikolaus Wulff

Einführung in den Einsatz von Objekt-Orientierung mit C++ I

3. Arrays und Pointer

Objective-C CheatSheet

Transkript:

Inhalt Inhalt: 4. Programmiersprache C 4.1 Programmaufbau in C 4.2 Basisdatentypen und einfache Anweisungen 4.3 Steuerfluss-Konstrukte 4.4 Arbeit mit indizierten Größen (Felder) 4.5 Arbeit mit Zeigern (Pointer) 4.6 Zeichen und Zeichenketten 4.7 Funktionen 4.8 Strukturen 4.9 Typen, Variable und Konstante Peter Sobe 72 4.5 Arbeit mit Zeigern (engl. Pointer) Zeiger Ein Zeiger (engl. Pointer) speichert eine Adresse, unter der ein Wert im Speicher des Computers gespeichert werden kann. Eine Variable im Gegensatz speichert einen Wert. Der Name eines Zeigers ist mit einer Adresse verbunden, ein Variablenname dagegen mit einem bestimmten Wert. Zeiger werden z.b. für folgende Zwecke benutzt: Dynamische Speicherverwaltung Parameterübergabe in Funktionen Zeichenkettenverarbeitung Peter Sobe 73

Definition von Zeigervariablen Bei der Definition eines Zeigers wird ein Stern ("*") vor den Bezeichner geschrieben. Werden die Bezeichner mit Kommas getrennt in einer Definitionsliste angegeben, so muss der Stern vor jeden einzelnen Bezeichner geschrieben werden, der als Zeiger definiert werden soll. long *LZ, LZ2; // LZ ist ein Zeiger, LZ2 eine Variable float summe, * psumme; // summe ist eine Variable, // psumme ein Zeiger Für eine gute Übersichtlichkeit, besser Variablen und Zeiger in jeweils einer eigenen Zeile definieren! float summe; float* psumme; Peter Sobe 74 Veranschaulichung einer Zeigervariablen Der Speicher eines Rechners wird über Adressen verwaltet, die die Speicherstellen (Bytes) linear durchnummerieren. Die Nummer des angesprochenen Bytes ist die Adresse. Hier ein Beispiel (stark vereinfacht) : float summe; float* psumme = &summe; // Zeiger mit Adresse von summe 4 Inhalt 0 1 4 summe 12 psumme Adresse Zugriff auf summe wird durch Compiler mit Zugriff auf Adresse 4 ersetzt Peter Sobe 75

Der &-Operator Zeiger - Adressoperator Um die Adresse einer Variablen (einen sogenannten L-Wert) zu erhalten, muss ein spezieller Operator verwendet werden. Lvalue = location for a value Dieser Operator wird als Adressoperator bezeichnet. Er wird mit dem Zeichen "&" (Ampersand) symbolisiert. Zum Beispiel: int Io = 1024; int* IZ = &Io; // IZ erhält die Adresse von Io // und nicht den Wert 1024 Peter Sobe 76 Zeiger Ein Zeiger kann auch mit einem anderen Zeiger desselben Typs initialisiert werden. // jetzt enthält auch IZ2 die Adresse von Io int* IZ2 = IZ; int ** IZ4 = &IZ; // Zeiger auf Zeiger Peter Sobe 77

Ein Beispiel zur Benutzung von Zeigern void swap(float* x1, float* x2) { // zwei Werte vertauschen float temp = *x1; *x1 = *x2; *x2 = temp; void swap2(float** x1, float** x2) { // zwei Zeiger vertauschen float* temp = *x1; *x1 = *x2; *x2 = temp; int main(void) { float a, b, *pa, *pb; a = 1.0, b = 2.0, pa = &a, pb = &b; swap(&a, &b); /* Tauscht die Werte a und b wirklich* / swap2(&pa, &pb); /* tauscht nur die Pointer */ Peter Sobe 78 Der * - Operator * ist der Inhaltsoperator. Damit kann ein Zeiger dereferenziert werden, d.h. auf den Wert der Variable (auf die gezeigt wird) zugegriffen werden. Die Vereinbarung int* pi; oder auch int *pi; kann gelesen werden als der Inhalt von pi ist vom Typ int, also ist pi vom Typ Zeiger auf int : int i = 1234; int* pi; // pi ist also vom Typ Zeiger auf int pi = &i; // pi zeigt jetzt auf i *pi = 5678; // i hat jetzt den Wert 5678, // der Zugriff auf i erfolgt hier durch Dereferenzieren // des Zeigers pi. Dereferenzierung: Typ* ptr; // hier wird eine Zeigervariable definiert *ptr =...;... = *ptr; // hier wird ptr dereferenziert // und damit auf den Inhalt zugegriffen Peter Sobe 79

Zeiger und Typen Jeder Zeiger ist mit einer Variablen eines bestimmten Typs verbunden Der Datentyp gibt den Typ des Datenobjekts an, das mit Hilfe dieses Zeigers adressiert wird. Ein Zeiger des Typs int zeigt zum Beispiel auf ein Objekt des Typs int. int intvar; int* intzeiger = &intvar; Um auf ein Objekt des Typs double zu zeigen, muss der Zeiger mit dem Datentyp double definiert werden. double dvar; double* dzeiger = &dvar; Peter Sobe 80 Zeiger - Speicherbedarf von Zeigern Der Speicherplatz, der für einen Zeiger reserviert wird, muss eine Speicheradresse aufnehmen können. Das bedeutet, dass ein Zeiger des Typs int und ein Zeiger auf einen Datentyp double normalerweise gleich groß sind. Der Typ, der einem Zeiger zugeordnet ist, gibt den Inhalt und damit auch die Größe des adressierten Speicherbereichs an. int* pint ; // pint belegt 4 Byte double* pdouble; // pdouble belegt auch 4 Byte Der Speicherplatz der für Zeiger verwendte wird ist implementierungsabhängig und typischerweise 32 oder 64 Bit (d.h. 4 oder 8 Byte lang). Peter Sobe 81

Zugriff auf Felder durch Zeiger (1) In C sind Variablen für Felder und Zeiger zuweisungskompatibel. Beispiel: int zahlenfeld[20]; int einzelzahl; int *iptr; iptr = zahlenfeld; // dem Zeiger kann der Name eines Feldes // zugewiesen werden einzelzahl = iptr[5]; // Ein Zeiger kann wie ein Feld benutzt werden Ein Feld mit Elementen eines bestimmten Typs wird als Variable wie ein Zeiger auf ein Element des Typs behandelt. Gleichzeitig kann ein Zeiger auch wie ein Feldbezeichner mit Indexklammern versehen werden. Peter Sobe 82 Zugriff auf Felder durch Zeiger (2) Hintergrund: int feld[10]; int* ptr = feld; // entspricht: int* ptr = &feld[0] Der Feldname entspricht damit der Adresse des ersten Feldelementes, d.h. dem mit dem Index 0. Der Zusammenhang zwischen Feldern und Zeigern wird oft bei der Übergabe von Feldern in Funktionsparametern ausgenutzt: void auswahlfunktion( int *feld, int index, int *wert ) { *wert = feld [index]; Details zu Funktionen und deren Parametern folgen später! Peter Sobe 83

Addition und Subtraktion bei Zeigern Bei der Addition (oder Subtraktion) eines ganzzahligen Wertes (z.b. 2), wird der Wert der entsprechenden Adresse um die Größe von z.b. zwei Objekten dieses Datentyps (hier int) erhöht (oder erniedrigt). Wenn z.b. ein char 1 Byte, ein int 4 Byte und ein double 8 Byte belegt, dann erhöht sich bei einer Addition um 2 zu einem Zeiger, der Wert der im Zeiger gespeicherten Adresse um 2, 8 bzw. 16 Byte. Beispiele: 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 feld[0] Peter Sobe 84 Operationen mit Zeigern (1) Einem Zeiger kann man einen Zeiger des gleichen Typs zuweisen. int* ptr1 = &i; int* ptr2 = ptr1; Ein Zeiger kann auch inkrementiert oder dekrementiert werden. So bedeutet z.b. +5 hier eine Inkrementierung um 5 Schritte mit der Schrittweite sizeof(int) : int* ptr3 = ptr2 + 5; Eine Zuweisung eines anderen Typs ist nur über Typecast möglich: char* pchar = (char*) ptr2; // typecast Peter Sobe 85

Operationen mit Zeigern (2) Es kann die Differenz zweier Zeiger gebildet werden: int feld[10]; int* ptr1 = &feld[1]; int* ptr8 = &feld[8]; int anzahl = ptr8 ptr1; // ergibt den Wert 7 // Besser: ptrdiff_t anzahl = ptr8 ptr1; ( ptrdiff_t ist in cstddef bzw. stddef.h vereinbart ) Einem Zeiger darf der Wert 0 (NULL) zugewiesen werden. Dadurch wird der Zeiger als nicht initialisierter Zeiger gekennzeichnet: int* ptr = 0; // oder: int* ptr = NULL; Die Vergleichsoperationen == und!= sind zulässig, um zwei Zeiger auf Gleichheit zu testen, d.h. ob sie auf die gleiche Adresse verweisen. Dieses hat nichts mit den Werten zu tun, die die Adressen enthalten. Peter Sobe 86 NULL - Zeiger Es gibt einen besonderen Zeigerwert, der als Konstante NULL definiert ist. Die interne Darstellung der NULL ist implementierungsabhängig, aber kompatibel zur ganzzahligen Null (0). NULL kann jeder Zeigervariablen zugewiesen werden, und jede Zeigervariable kann auf NULL getestet werden; p = NULL; /* Beide Anweisungen sind */ p = 0; /* korrekt und bedeutungsgleich! */... if (p==null)... /* Alle drei */ if (!p)... /* Abfragen sind korrekt */ if (p==0)... /* und bedeutungsgleich! */ Diese Operationen können auch dazu verwendet werden, um zu ermitteln, ob ein Zeiger bereits initialisiert wurde: int *ptr = 0, *ptr2;... if (ptr == 0) { // initialisiere jetzt ptr Peter Sobe 87

Weitere Bedeutung von Zeigern Zeiger zur Übergabe von Parametern an Funktionen Call by Reference Parameter sind Zeiger void function(int x, int *y) { *y = 2*x*x 3*x +5; // der Wert auf den y zeigt wird verändert Zeiger für dynamische Speicherstrukturen int *p; int anzahl_werte; // konkreter Wert ergibt sich zur Laufzeit p = malloc(anzahl_werte*sizeof(int)); Peter Sobe 88