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

Ähnliche Dokumente
Dynamischer Speicher

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

Programmierung mit C Zeiger

Felder (1) Allgemeines

2. Programmierung in C

8. Referenzen und Zeiger

Inhalt. 4.5 Arbeit mit Zeigern (engl. Pointer)

Zeiger: Der Adressoperator &

Zeiger, Arrays und Strings in C und C++

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

6. Zeiger Allgemeines Definition eines Zeigers

9 Zeiger (Pointer). Dynamischer Speicher

+ C - Array (Vektoren, Felder)

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

Vorkurs C++ Programmierung

Arrays (Felder/Vektoren)

Modellierung und Programmierung 1

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

RO-Tutorien 3 / 6 / 12

Vektoren 105. array-qualifier static restrict const volatile array-size-expression assignment-expression * simple-declarator identifier

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

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

Grundlagen der Informatik 11. Zeiger

Objektorientierte Programmierung OOP Programmieren mit Java

Einstieg in die Informatik mit Java

Wertebereich und Genauigkeit der Zahlendarstellung

2. Programmierung in C

Die Programmiersprache C99: Zusammenfassung

Übungspaket 14 Eindimensionale Arrays

Speicherklassen (1) Lokale Variablen

Zeiger und dynamischer Speicher

Grundlagen der Programmiersprache C für Studierende der Naturwissenschaften

Primitive Datentypen und Felder (Arrays)

Übersicht. Informatik 1 Teil 9: komplexe Datentypen (Strukturen, Enumerationen, Unions)

Kapitel 6. Programmierkurs. 6.0 Felder (Arrays) Deklaration von Feldern. Felder (Arrays) Mehrdimensionale Arrays. Birgit Engels, Anna Schulze WS 07/08

C-Kurs 2010 Pointer. 16. September v2.7.3

Programmieren in C. Funktionen mit Zeigern und Adressen. Prof. Dr. Nikolaus Wulff

10 Die Programmiersprache C99: Zusammenfassung

Welche Informatik-Kenntnisse bringen Sie mit?

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

Unterprogramme, Pointer und die Übergabe von Arrays

Einführung in die Java- Programmierung

Das folgende Programm demonstriert, wie man Speicheradressen von Variablen ermittelt.

Vorkurs Informatik: Erste Schritte der Programmierung mit C++

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

Deklarationen in C. Prof. Dr. Margarita Esponda

Dr. Monika Meiler. Inhalt

R-Wörterbuch Ein Anfang... ein Klick auf einen Begriff führt, sofern vorhanden, zu dessen Erklärung.

Datentypen: Enum, Array, Struct, Union

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

Übungspaket 23 Mehrdimensionale Arrays

Prozeduren und Funktionen

Java programmieren mit JavaKara. Eine Zusammenfassung in Beispielen

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

Kapitel 4: Zeiger. Inhalt. Zeiger Zeigerarithmetik

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

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

C-Pointer (Zeiger, Adressen) vs. C++ Referenzen

Elementare Datentypen in C++

Übungspaket 23 Mehrdimensionale Arrays

C- Kurs 09 Dynamische Datenstrukturen

Zeiger in C. Thomas Mechelke August 2011

C# - Einführung in die Programmiersprache Arrays, Enumeration und Collections. Leibniz Universität IT Services Anja Aue

Übungspaket 29 Dynamische Speicherverwaltung: malloc() und free()

Javakurs für Anfänger

Übersicht PERL. !!!! Wichtig: Nach dem Befehl einem Strichpunkt setzen!!!!

Arrays und Schleifen

GI Vektoren

C für Java-Programmierer

Access [basics] Programmieren mit Arrays. Beispieldatenbank. Arrays. Eindimensionale Arrays. VBA-Grundlagen Programmieren mit Arrays

Ein- und Ausgabe. C - Kurs Mario Bodemann. 15. September 2010

Die Programmiersprache C

4 Kontrollfluss-Diagramme

Tag 4 Repetitorium Informatik (Java)

Vorkurs C++ Programmierung

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

Organisatorisches. drei Gruppen Gruppe 1: 10:10-11:40, Gruppe 2: 11:45-13:15 Gruppe 3: 13:20-14:50

Zeichendarstellung. Zeichen sind Zahlen (in C) Zeichen und switch

Zusammenfassung des Handzettels für Programmieren in C

Javakurs für Anfänger

Inhalt. Peter Sobe 63. Felder in C

Einführung in die Programmiersprache C

Propädeutikum zur Programmierung

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

Felder, Rückblick Mehrdimensionale Felder. Programmieren in C

Die Programmiersprache C Eine Einführung

Programmieren in C/C++ und MATLAB

Datenstrukturen, Alignment Stack Prozeduraufruf, Parameterübergabe und -rückgabe (Calling Conventions) Leaf procedures

Java Einführung Methoden. Kapitel 6

Der Datentyp String. Stringvariable und -vergleiche

Advanced Programming in C

Algorithmen und Datenstrukturen

Verschlüsseln eines Bildes. Visuelle Kryptographie. Verschlüsseln eines Bildes. Verschlüsseln eines Bildes

Pointer überall Pointer von Jörg Jacob, Mai 2004 (Version 0.2)

Java Einführung Klassendefinitionen

Funktionen in PHP 1/7

Felder (1) Felder (Arrays) speichern viele Datenelemente des gleichen Typs. Auf einzelne Elemente kann über einen Index zugegriffen werden

Pointer. Variablen. Pointer. Ein elementares Beispiel. Pointer in C

Themen. Statische Methoden inline Methoden const Methoden this Zeiger Destruktor Kopierkonstruktor Überladen von Operatoren

Benutzerfunktionen Was ist eine Funktion, was ist eine Prozedur?

Transkript:

Zeiger C-Kurs 2012, 2. Vorlesung Tino Kutschbach tino.kutschbach@campus.tu-berlin.de http://wiki.freitagsrunde.org 10. September 2012 This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 License. 1 / 23

Inhaltsverzeichnis 1 Grundlegendes zum Speicher 2 Zeiger und einfache Variablen 3 Lokale Variablen, Funktionsaufrufe und Parameterübergabe 4 Zeiger und Arrays 5 Mehrdimensionale Arrays 6 Zusammenfassung Zeigeroperationen 2 / 23

Inhaltsverzeichnis 1 Grundlegendes zum Speicher 2 Zeiger und einfache Variablen 3 Lokale Variablen, Funktionsaufrufe und Parameterübergabe 4 Zeiger und Arrays 5 Mehrdimensionale Arrays 6 Zusammenfassung Zeigeroperationen 3 / 23

Speicherzellen, Adressen, Inhalte Der Arbeitsspeicher besteht aus vielen einzelnen Speicherzellen Jede Speicherzelle besitzt eine eindeutige Adresse und speichert einen Inhalt Bei Deklaration einer Variable wird eine Speicherzelle reserviert und mit einem Namen versehen 4 / 23

Direkter und indirekter Zugriff Direkter Zugriff per Name erfolgt durch Verwendung des deklarierten Namens, wobei direkt auf den Inhalt der verknüpften Zelle zugegriffen wird also direkter Bezug: Name liefert Inhalt Indirekter Zugriff per Adresse ermöglicht es auch auf Speicherzellen zuzugreifen, welche keinen Namen haben, bzw. deren Name nicht sichtbar ist erfolgt mit Hilfe von Zeigern. 5 / 23

Inhaltsverzeichnis 1 Grundlegendes zum Speicher 2 Zeiger und einfache Variablen 3 Lokale Variablen, Funktionsaufrufe und Parameterübergabe 4 Zeiger und Arrays 5 Mehrdimensionale Arrays 6 Zusammenfassung Zeigeroperationen 6 / 23

Der Adressoperator & Der Adressoperator & liefert die Adresse einer Variable &x liefert die Adresse der Speicherzelle mit dem Namen x Eine Adresse ist eine Zahl und lässt sich wie jede andere Zahl behandeln, z.b in Variablen speichern Eine Variable, die eine Adresse enthält, nennt man Zeiger 7 / 23

Der Indirektionsoperator * Der Indirektionsoperator * nimmt eine Adresse und liefert den Inhalt der entsprechenden Speicherzelle Ist y ein Zeiger auf x, also: Enthält y die Adresse von x (y=&x) y liefert den Wert der in der Speicherzelle mit der Adresse y gespeichert ist, also: y==x * ist eine der wenigen Ausnahmen von Operatoren, die auch auf der linken Seite einer Zuweisung stehen können 8 / 23

Zeiger deklarieren und initialisieren Eine Zeigerdeklaration weist die folgende Form auf: typname zeigername; das bedeutet: der Inhalt der Speicherzelle mit Adresse zeigername ist vom Typ typname oder anders formuliert: zeigername ist ein Zeiger auf den Typ typname Nach einer Deklaration muss ein Zeiger initialisiert werden, damit er auf eine gültige Speicherstelle zeigt: zeigername = &variable; Verwende niemals uninitialisierte Zeiger! 9 / 23

Einfaches Zeiger-Beispiel 1 #i n c l u d e <s t d i o. h> 2 3 i n t main ( v o i d ) { 4 i n t v a r = 1 ; Listing 1: src/zeiger.c 5 i n t z g r ; // D e k l a r a t i o n e i n e s Z e i g e r s auf i n t 6 7 z g r = &v a r ; // I n i t i a l i s i e r u n g : z g r z e i g t auf v a r 8 9 / I n h a l t von v a r ausgeben / 0 p r i n t f ( D i r e k t e r Z u g r i f f, v a r = %d \n, v a r ) ; 1 p r i n t f ( I n d i r e k t e r Z u g r i f f, v a r = %d \n, z g r ) ; 2 / A d r e s s e von v a r ausgeben / 3 p r i n t f ( A d r e s s e von v a r = %p \n, &v a r ) ; 4 p r i n t f ( A d r e s s e von v a r = %p \n, z g r ) ; 5 6 r e t u r n 0 ; 7 } 10 / 23

Inhaltsverzeichnis 1 Grundlegendes zum Speicher 2 Zeiger und einfache Variablen 3 Lokale Variablen, Funktionsaufrufe und Parameterübergabe 4 Zeiger und Arrays 5 Mehrdimensionale Arrays 6 Zusammenfassung Zeigeroperationen 11 / 23

Datenhaltung lokaler Variablen Funktionen hinterlegen ihre lokal deklarierten Variablen auf dem Stack in ihrem zugehörigen Stackframe Die Namen der lokalen Variablen einer Funktion sind nur in der Funktion selbst bekannt Ein direkter Zugriff auf Variablen höherer Funktionen, Funktionen mit aufliegendem Stackframe, ist daher nicht möglich Existiert jedoch ein Zeiger auf solche Variablen, so ist ein indirekter Zugriff möglich Ruft eine Funktion selbst eine weitere Funktion auf, so werden die Parameter auf dem Stack kopiert und so der Unterfunktion übergeben. 12 / 23

Call-by-value Listing 2: src/cbv.c 1 i n t a d d i e r e ( i n t p1, i n t p2 ) { 2 r e t u r n p1+p2 ; 3 } Beim Aufruf der Funktion werden die Parameter in die Funktion hinein kopiert. Ein Zugriff auf die Originaldaten ist nicht möglich Ein Ergebnis kann nur über return zurückgegeben werden 13 / 23

Call-by-reference Listing 3: src/cbr.c 1 v o i d i n k r e m e n t i e r e ( i n t p1, i n t p2 ) { 2 ( p1 )++; 3 ( p2 )++; 4 r e t u r n ; 5 } Beim Aufruf der Funktion werden Parameter in die Funktion hinein kopiert, hier sind diese Parameter jedoch Zeiger. Ein Zugriff auf Originaldaten ist durch die Zeiger möglich. Es wird direkt mit auf den Originaldaten gearbeitet Zusätzlich könnte auch noch über return ein Wert zurückgegeben werden 14 / 23

Inhaltsverzeichnis 1 Grundlegendes zum Speicher 2 Zeiger und einfache Variablen 3 Lokale Variablen, Funktionsaufrufe und Parameterübergabe 4 Zeiger und Arrays 5 Mehrdimensionale Arrays 6 Zusammenfassung Zeigeroperationen 15 / 23

Array-Anordnung im Speicher Die Elemente eines Arrays werden hintereinander in sequentieller Reihenfolge im Speicher abgelegt Das erste Element steht an der niedrigsten Adresse. Die folgenden Elemente folgen bei höheren Adressen Die Anzahl von Speicherzellen, die ein Element belegt, hängt dabei vom Datentyp des Arrays ab Ein Array-Name ohne eckige Klammern ist ein Zeiger auf das erste Element es gilt also: array == &array[0] Bei einem Funktionsaufruf werden Arrays über ihren Namen, ohne Klammern, übergeben. Da der Name nur ein Zeiger ist, ist eine Array-Parameterübergabe immer Call-by-reference 16 / 23

Zeigerarithmetik Gibt es einen Zeiger auf das erste Array-Element, kann man durch inkrementieren des Zeigers auf nachfolgende Array-Elemente zugreifen Die Größe des Inkrements entspricht der Größe des Datentyps der im Array gespeicherten Elemente Zeiger inkrementieren: Wird der Wert eines Zeigers um 1 erhöht, so sorgt die Zeigerarithmetik dafür, dass der Zeiger automatisch um die Größe des Datentyps, auf den der Zeiger zeigt, erhöht wird Bei der inkrementierung eines Zeigers auf int um 1: zgr auf int ++ wird der Wert automatisch um die Größe des Typs int (4 Bytes) erhöht Bei der inkrementierung eines Zeigers auf double um 10: zgr auf double += 10 wird der Wert automatisch um 80 (wenn double 8 Bytes groß) erhöht und rückt somit den Zeiger um 10 Elemente weiter Zeiger dekrementieren erfolgt analog, wobei hiermit der Zeiger verringert wird und somit auf vorherige Arrayelemente zugegriffen werden kann 17 / 23

Index-Zeigernotation bei Arrays Es besteht folgender Zusammenhang zwischen Index- und Zeigernotation bei Arrays (array ) == array[0] ( array + 1) == array[1] ( array + 2) == array[2]... ( array + i) == array[i] 18 / 23

Inhaltsverzeichnis 1 Grundlegendes zum Speicher 2 Zeiger und einfache Variablen 3 Lokale Variablen, Funktionsaufrufe und Parameterübergabe 4 Zeiger und Arrays 5 Mehrdimensionale Arrays 6 Zusammenfassung Zeigeroperationen 19 / 23

Zeiger auf Zeiger Zeiger sind selbst numerische Variablen und in eigenen Speicherzellen gespeichert Die Anwendung des Adressoperators & auf einen Zeiger ist also ebenfalls gültig Was man dann erhält ist ein Zeiger auf einen Zeiger Listing 4: src/zgr auf zgr.c 1 i n t x = 1 2 ; // x i s t e i n e i n t V a r i a b l e. 2 i n t z g r = &x ; // z g r i s t e i n Z e i g e r auf x. 3 i n t z g r a u f z g r = &z g r ; // z g r a u f z g r i s t e i n Z e i g e r 4 // auf e i n e n Z e i g e r auf i n t Um einen Zeiger auf einen Zeiger für den Zugriff auf eine Variable zu verwenden muss nun doppelt de-referenziert werden Der Indirektionsoperator * muss also doppelt verwendet werden Die folgende Anweisung gibt also den Wert von x auf dem Bildschirm aus printf ( %d, zgr auf zgr); 20 / 23

Mehrdimensionale Arrays Der Einsatz von Zeigern auf Zeiger wird vor allem bei der Verwendung mehrdimensionaler Arrays deutlich Ein Beispiel für ein zweidimensionales Array: int multi [2][4]; Dieses Array kann man sich als Tabelle mit zwei Zeilen und vier Spalten vorstellen C orientiert es jedoch auf eine andere Art und Weise: multi ist ein Zeiger auf ein Array mit 2 Elementen Jedes dieser Elemente (multi[0], multi[1]) ist wiederum ein Zeiger auf ein Array mit 4 Elementen Jedes dieser insgesamt acht Elemente ist vom Typ int multi ist demnach ein Zeiger auf einen Zeiger Es gilt daher die folgende Analogie: multi [ i ][ j ] == ( (multi+i)+j) 21 / 23

Inhaltsverzeichnis 1 Grundlegendes zum Speicher 2 Zeiger und einfache Variablen 3 Lokale Variablen, Funktionsaufrufe und Parameterübergabe 4 Zeiger und Arrays 5 Mehrdimensionale Arrays 6 Zusammenfassung Zeigeroperationen 22 / 23

Zusammenfassung Zeigeroperationen Operation Operator Beschreibung Zuweisung = Einen Zeiger kann ein Wert zugewiesen werden. Das sollte eine Adresse sein, die von einem Zeiger (Array-Name) kommt oder die durch den &-Operator ermittelt wurde Indirektion * Der Indirektionsoperator * liefert den Wert an der Speicherstelle, auf die der Zeiger verweist Adresse ermitteln & Wird der Adressoperator & auf einen Zeiger angewendet, so liefert dieser die Speicheradresse zurück, an welcher der Zeiger gespeichert ist. So können Zeiger auf Zeiger erzeugt werden Inkrement ++, +=, + Ein Zeiger kann um eine ganze Zahl erhöht werden, sodass er auf eine andere Speicherposition verweist. Die Größe des Datentyps wird dabei automatisch mit eingerechnet. Dekrement, -=, - Ein Zeiger kann um eine ganze Zahl verringert werden, sodass er auf eine andere Speicherposition verweist. Die Größe des Datentyps wird dabei automatisch mit eingerechnet. Differenzbildung - Zwei Zeiger können voneinander subtrahiert werden. So kann festgestellt werden wie viele Elemente die Zeiger voneinander entfernt sind. Die Größe des Datentyps wird dabei automatisch mit eingerechnet. Vergleich ==, >,!=, <=, >=, < Zwei Zeiger können miteinander verglichen werden. Dies liefert allerdings nur gültige Ergebnisse, wenn beide Zeiger auf das selbe Array zeigen 23 / 23