Praxis der Programmierung



Ähnliche Dokumente
Einführung in die Programmierung zusammengesetzte Datentypen, dynamischer Speicher

Praxis der Programmierung

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

Algorithmen und Datenstrukturen

Dynamischer Speicher

Programmieren in C. Speicher anfordern, Unions und Bitfelder. Prof. Dr. Nikolaus Wulff

Dynamische Speicherverwaltung

Probeklausur Name: (c)

Grundlagen der Informatik 11. Zeiger

Grundlagen und Konzepte von C Datenstrukturen

2. Programmierung in C

4.2 Programmiersprache C

Vorlesung Programmieren

Dynamische Speicherverwaltung

7. Übung Informatik II - Objektorientierte Programmierung

Software Entwicklung 1

F Zeiger, Felder und Strukturen in C

Teil 5: Zeiger, Felder, Zeichenketten Gliederung

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

C-Propädeutikum Höhere Datentypen

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

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

2. Programmierung in C

INE1 Arrays, Zeiger, Datenstrukturen

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

6 Speicherorganisation

Physische Datenstrukturen

Crashkurs C++ - Teil 1

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

Teil 5: Felder, Zeiger, Zeigerarithmetik Gliederung

C++ Teil 7. Sven Groß. 30. Nov Sven Groß (IGPM, RWTH Aachen) C++ Teil Nov / 13

Zeiger und dynamischer Speicher

C++ - Objektorientierte Programmierung Konstruktoren und Destruktoren

C++ - Objektorientierte Programmierung Konstante und statische Elemente

Übersicht. Speichertypen. Speicherverwaltung und -nutzung. Programmieren in C

Anregungen zu Übung 2

Zeiger (engl. Pointer)

Programmierung mit C Zeiger

Inhalt. 4.5 Arbeit mit Zeigern (engl. Pointer)

Einführung in C. Alexander Batoulis. 5. Mai Fakutltät IV Technische Universität Berlin

Praxis der Programmierung

II. Grundlagen der Programmierung. Beispiel: Merge Sort. Beispiel: Merge Sort (Forts. ) Beispiel: Merge Sort (Forts. )

Typische Speicherfehler in C

C++ Teil 6. Sven Groß. 27. Mai Sven Groß (IGPM, RWTH Aachen) C++ Teil Mai / 14

Array-Verwaltung. Array-Verwaltung im Speicher Illustration. Zuweisung von Arrays. Speicherbereinigung. Aliasierung Eine Besonderheit

Advanced Programming in C

Dynamische Datentypen. Destruktor, Copy-Konstruktor, Zuweisungsoperator, Dynamischer Datentyp, Vektoren

Einstieg in die Informatik mit Java

einlesen n > 0? Ausgabe Negative Zahl

INE1 Speicherverwaltung und zweidimensionale Arrays. Speicherorganisation Dynamischer Speicher in C Zweidimensionale Arrays

Einleitung Typsystem Typisierung Zusammenfassung Literatur. Typisierung. Effiziente Programmierung. Thomas Schnieders

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

Speicherklassen (1) Lokale Variablen

Arrays (Felder/Vektoren)

Heap vs. Stack vs. statisch. 6 Speicherorganisation. Beispiel Statische Variablen. Statische Variablen

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

Javaprogrammierung mit NetBeans. Variablen, Datentypen, Methoden

U4-1 Aufgabe 3: einfache malloc-implementierung

Heap vs. Stack vs. statisch. 6 Speicherorganisation. Beispiel Statische Variablen. Statische Variablen

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

Arrays. Einleitung. Deklarieren einer Array Variablen

Praxisorientierte Einführung in C++ Lektion: "Dynamische Speicherverwaltung"

Java Referenzdatentypen genauer betrachtet

Kapitel 6: Dynamische Speicherverwaltung

Hydroinformatik I: Referenzen und Zeiger

EEPROM Strukturen speichern über SPI-Bus

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

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

C++ Notnagel. Ziel, Inhalt. Programmieren in C++

Transkript:

Zusammengesetzte Datentypen, dynamische Speicherverwaltung Institut für Informatik und Computational Science Universität Potsdam Henning Bordihn Einige Folien gehen auf A. Terzibaschian zurück. 1

Zusammengesetzte Datentypen 2

Zusammengestzte Datentypen Motivation Aufgabe: Kundenverzeichnis anlegen Für jeden Kunden erfassen: Name, Adresse, Kundennummer, Telefonnummer, Umsatz,... Wie kann man das in C umsetzen? 3

Zusammengesetzte Datentypen Motivation (2) Array für jeden Kunden? Array für jedes Merkmal? char* name[1024]; char* address[1024]; short phone[1024]; short id[1024]; float b_volume[1024];... unmöglich wegen der versch. Datentypen Zusammengehörgkeit der Variablen nicht sichergestellt Übergabe an Funktionen nur einzeln Strukturen (structs) zur Definition komplexer Datentypen, die sich aus mehreren Datentypen zusammensetzen 4

Zusammengesetzte Datentypen Motivation (2) Array für jeden Kunden? Array für jedes Merkmal? char* name[1024]; char* address[1024]; short phone[1024]; short id[1024]; float b_volume[1024];... unmöglich wegen der versch. Datentypen Zusammengehörgkeit der Variablen nicht sichergestellt Übergabe an Funktionen nur einzeln Strukturen (structs) zur Definition komplexer Datentypen, die sich aus mehreren Datentypen zusammensetzen 5

Stukturen Strukturtyp: - selbst definierter Datentyp - zusammengesetzt aus Komponenten verschiedener Typen Variable von Typ Struktur (Verbund/Record) kann Datensatz speichern Kundennr. Nachname Vorname Straße Hausnr. PLZ Wohnort Umsatz short char[64] char[64] char[64] short short char[64] float Komponenten haben einen eigenen Namen und Typ (statt Index) 6

Deklaration eines Strukturtyps struct name { komponententyp 1 komponentenname 1; komponententyp 2 komponentenname 2;. komponententyp n komponentenname n; }; struct ist Schlüsselwort Datentyp: struct name Anzahl der Komponenten bei Deklaration festgelegt Semikolon nach } (kein Anweisungsblock!) 7

Deklaration eines Strukturtyps Beispiel char* name[1024]; char* address[1024]; short phone[1024]; short id[1024]; float b_volume[1024]; = struct customer { short id; char name[64]; char adress[64]; short phone; float b_volume; }; struct customer ctms[1024]; 8

Strukturtypen Strukturtypen Warum? definieren immer einen Datentyp bilden die Zusammengehörigkeit von Daten ab bilden die Realität direkter ab bessere Modellierung von Anwendungsdomänen erleichtertes Code-Verständnis erleichterte Wartung des Codes 9

Strukturvariablen Deklaration: struct name variablenname; Variable vom zusammengesetzten Typ struct name besteht aus mehreren Komponentenvariablen bei Stukturtypdeklaration vereinbart gleichzeitige Vereinbarung von Strukturtyp und -variablen möglich: struct point { float x; float y; } pt1; struct point pt2, pt3; // Def. neuer Datentyp (Strukturtyp) // zwei Komponenten (Member) x und y pt1, pt2, pt3 als (Struktur-) Variablen dieses neuen Datentyps deklariert 10

Zugriff auf Komponentenvariablen 1. Punktoperator: Strukturvariable.Komponentenvariable Beispiele: pt1.x meyer.name meyer.address lesender und schreibender Zugriff: strcpy(meyer.name, "Meyer, Jens"); strcpy(meyer.address, "14482 Potsdam, A-Bebel-Str. 89"); printf("%s\n\%s\verb\n", meyer.name, meyer.address); 11

2. Pfeiloperator: Pointer auf Strukturvariable->Komponentenvariable Beispiel: (&pt1)->x (&meyer)->name Pfeil: Minuszeichen und Größerzeichen lesender und schreibender Zugriff: printf("adresse: %s\n", (&meyer)->address); Wie kann die Adresse in ihre Komponenten zerlegt werden? Strukturen als Komponenten von Strukturen 12

Strukturen als Komponenten von Strukturen struct address { char street[64]; short number; short zip_code; char city[64]; }; struct customer { char name[64]; struct address adr;... }; struct customer meyer; strcpy(meyer.name, "Meyer, Jens"); strcpy(meyer.adr.street, "A.-Bebel-Str."); meyer.adr.number = 89; 13

Initialisierung von Strukturvariablen 1. mit Punkt- oder Pfeiloperator 2. mit Initialisierungslisten nur direkt bei der Definition der Strukturvariablen wie bei Arrays (mit Ausdrücken passenden Typs), z.b.: struct customer meyer = { "Meyer, Jens", { "A.-Bebel-Str.", 89, 14482, "Potsdam" }... }; 3. Zuweisung von struct-variablen: customer krause = meyer; // Kopie der WERTE aller Elemente!!! 14

Strukturen als Parameter und Rückgabewerte von Funktionen Voraussetzung: Deklaration des Strukturtyps außerhalb und vor den Funktionen Übergabe wie einfache Datentypen (call-by-value beachten!): void print_customer (struct customer c) { printf("%s\n", c.name); printf("%s %d\n", c.adr.street, c.adr.number); printf("%d %s\n", c.adr.zip_code, c.adr.city); } struct point new_point () { return struct point new = {0, 0}; } oft unnötiges Kopieren großer Datenmengen im Speicher 15

Pointer auf Struktuen als Parameter Simulation von call-by-reference durch Übergabe von Pointern: void print_customer (struct customer * c) { printf("%s\n", c->name); printf("%s %d\n", c->adr.street, c->adr.number); printf("%d %s\n", c->adr.zip_code, c->adr.city); } int main() { struct customer meyer = {... }; print_customer(&meyer); } Veränderung der Werte des Originals (c) möglich Gefahr: Parameter kann nicht oder mit NULL initialisiert sein (Laufzeitfehler) 16

Vereinbarung eigener Typnamen Vereinbarung eines Aliasnamens für bereits deklarierte Datentypen typedef Datentyp Aliasname; typedef int integer; Anwendung: Vereinfachung von Typnamen typedef struct customer Customer; Customer meyer; typedef unsigned long long ULL Vorbereitung Portierung maschinenabhängiger Datentypen typedef int INT; typedef short INT; 17

Strukturen im Speicher Elemente von Strukturvariablen liegen hintereinander im Speicher, z.b.: struct kt { int kundennummer; char name[64]; char adresse[64]; }; struct kt kunde[3]; 18

Dynamische Speicherverwaltung 19

Datentypen im Speicher bisher: Größe und Anzahl der Variablen bei Deklaration festlegen Variablen elementarer Datentypen (auch Pointer-Variablen) Strings, Arrays Strukturen (structs) Problem: Größe von Arrays/Strings kann oft erst zur Laufzeit bestimmt werden immer maximale Größe annehmen ist oft kritische Speicherverschwendung Lösung: dynamische Speicherreservierung on demand Nachteile: komplexere Programmlogik, hohe Fehleranfälligkeit, möglicher Datenverlust 20

Speicherbereiche eines Programms 1. Bereich für ausführbaren Maschinencode Bereich für Maschinencode (kompilierte Anweisungen) Bereich für statische Daten (Konstanten und statische Strings) 2. Programm-Stack (zur Compile-Zeit angelegt) Variablen, Arrays, Funktionsparameter temporäre Werte (bei Berechnungen) Aufrufstack für Funktionen 3. Programm-Heap (vom Programm zur Laufzeit verwaltet) dynamisch als Pointer auf den Heap angefordert (in C: malloc()) dynamisch wieder freigegeben (in C: free()) 21

Speicherbereiche eines Programms 1. Bereich für ausführbaren Maschinencode Bereich für Maschinencode (kompilierte Anweisungen) Bereich für statische Daten (Konstanten und statische Strings) 2. Programm-Stack (zur Compile-Zeit angelegt) Variablen, Arrays, Funktionsparameter temporäre Werte (bei Berechnungen) Aufrufstack für Funktionen 3. Programm-Heap (zur Laufzeit verwaltet) dynamisch als Pointer auf den Heap angefordert (in C: malloc()) dynamisch wieder freigegeben (in C: free()) 22

Speicherbereiche eines Programms 1. Bereich für ausführbaren Maschinencode Bereich für Maschinencode (kompilierte Anweisungen) Bereich für statische Daten (Konstanten und statische Strings) 2. Programm-Stack (zur Compile-Zeit angelegt) Variablen, Arrays, Funktionsparameter temporäre Werte (bei Berechnungen) Aufrufstack für Funktionen 3. Programm-Heap (zur Laufzeit verwaltet) dynamisch als Pointer auf den Heap angefordert (in C: malloc()) dynamisch wieder freigegeben (in C: free()) 23

Bibliotheksfunktionen zur dynamischen Speicherverwaltung in <stdlib.h> zum Anfordern von Speicher (liefert Pointer zurück), z.b.: void * malloc(size t size) Beispiel: ganze Zahlen von 1 bis N in einem Array speichern int N, i; int * nums; scanf("%d", &N); nums = malloc(n * sizeof(int)); for(i = 0; i < N; ++i) { nums[i] = i+1; } 24

Bibliotheksfunktionen zur dynamischen Speicherverwaltung (2) Freigeben von reserviertem Speicher (Pointer auf Speicherbereich übergeben): void free(void * pointer) am Beispiel: free(nums); // Speicherbereich zurueckgegeben nums = NULL; // nums zeigt nicht mehr auf den Speicherbereich keine automatische Speicherfreigabe Zu jedem malloc() gehört (irgendwann) genau ein free(). 25

Probleme mit dynamischer Speicherverwaltung Programmierer ist voll verantwortlich keine Freigabe Speicher läuft voll mit Daten, auf die nicht mehr zugegriffen werden kann / die nicht mehr gebraucht werden Freigabe eines nicht (mehr) alloziierten Bereichs Programmabsturz korrekte/geeignete Stelle zur Speicherfreigabe oft nicht klar: } char * create_string(int n) { // n ist Laenge des Strings char * str; str = malloc((n+1)*sizeof(char)); return str; free(str); // Problem??? 26

Dynamisch gespeicherte Daten als Rückgabewerte char * create_string(int n) { // n ist Laenge des Strings char * str; str = malloc((n+1)*sizeof(char)); return str; } void delete_string(char * s) { if (s!= NULL) { free(s); // s = NULL; hier nutzlos - warum?! } } Zu jedem Aufruf von create string gehört genau ein Aufruf von delete string, gefolgt von Zuweisung des NULL-Pointers! 27