Download - Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Transcript
Page 1: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Gliederung

Strukturen

Typdefinitionen

Unionen

Dynamische Speicherverwaltung

Teil 6: Strukturen und Unionen

Page 2: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.2

Strukturen

Page 3: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.3

Strukturen

� Ursprung in Pascal als Datentyp record, Verbunddatentyp

� Strukturtyp in C

� kann Komponenten (Variablen) verschiedener Typen enthalten:

� Anwendung: Gruppierung logisch zusammenhängender Daten z. B. Datum, Adresse, Personendaten, geometrische Objekte, .

� Behandlung beim Lesen und Schreiben immer als als Einheit

Personal- Nachname Vorname Straße Haus- Postleit- Wohnort Gehalt nummer nummer zahl

int char[20] char[20] char[20] int int char[20] float

Page 4: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.4

Strukturtyp-Definition

� frei definierter, zusammengesetzter Datentyp

� feste Anzahl von Komponenten

struct Name

{

typ1 komponentenVariable_1;

typ2 komponentenVariable_2;

. . .

typN komponentenVariable_n;

};

� der Typname ist struct Name

Page 5: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.5

Strukturvariablen-Definition

� Variable eines Strukturtyps = aus Komponentenvariablen zusammengesetzte Variable

� Erstellung einer Variablen des Typs struct Name

struct Name variable;

Komponenten- variable 1

Komponenten- variable 2

Komponenten- variable n ...

Strukturvariable

Page 6: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.6

Beispiel-Definition

struct Adresse

{

char strasse[20];

int hausnummer;

int postleitzahl;

char stadt[20];

};

struct Student

{

int matrikelnummer;

char name[20];

char vorname[20];

struct Adresse wohnort;

};

struct Student meyer, mueller; // 2 Studenten

struct Student semester[50]; // Feld aus 50 Studenten

Page 7: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.7

Übergabe an Funktionen

� call-by-value (wie bei elementaren Datentypen int, float, etc.)

Initialisierungslisten

struct Student student1 =

{

66202,

"Meyer",

"Herbert",

{

"Schillerplatz",

20,

73730,

"Esslingen"

}

};

Page 8: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.8

Zugriff auf Komponentenvariablen

student1.matrikelnummer = 716347;

struct Wort

{

char s[20];

}

struct Wort w1, w2;

char c1[20], c2[20];

strcpy(c1, "Hallo");

strcpy(w1.s, "Hallo");

c2 = c1;

w2 = w1;

strcpy(c2, c1); /* RICHTIG */

/* RICHTIG, eine Struktur ist ein L-Value */

/* FALSCH, ein Feld ist kein L-Value */

Page 9: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.9

Zugriff auf Komponentenvariablen

student1.matrikelnummer = 716347;

strcpy (student1.name, "Meyer");

student1.wohnort.postleitzahl = 73733;

strcpy (student1.wohnort.stadt, "Esslingen");

printf ("%6d %5d %s\n", student1.matrikelnummer,

student1.wohnort.postleitzahl,

student1.name);

Page 10: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.10

Kombination von Typ- und Variablendefinition

� ohne Strukturname/Etikett (unüblich)

struct

{

float x;

float y;

} punkt1, punkt2, punkt3;

� mit Strukturname/Etikett (üblich)

struct Koordinaten

{

float x;

float y;

} punkt1, punkt2, punkt3;

struct Koordinaten punkt4, punkt5, punkt6;

Page 11: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.11

Struktur-Zuweisungen, Vergleich

� direkte Zuweisung möglich, alle Komponentenwerte der Variablen punktAwerden den jeweiligen Komponenten der Variablen punkt3 zugewiesen

struct Koordinaten punktA = {1.5, 3.0}, punktB;

punktB = punktA;

� ABER: Prüfung auf Gleichheit if (punktA == punktB) ist nicht möglich!

� Bestimmung der Größe in Bytes einer Strukturvariablen:

sizeof (struct Koordinaten)

Page 12: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.12

Selektion über Zeiger

� Punktoperator . und Pfeiloperator ->

struct Koordinaten

{

float x;

float y;};

struct Koordinaten punktA = {1.5, 3.0}, *ppunkt;

ppunkt = &punktA;

� Wie greife ich auf Komponenten von punktA über den Zeiger ppunkt zu?

� Komponenten-Selektion über Zeiger auf 2 Arten möglich:

(*ppunkt).x bzw. ppunkt->x

(*ppunkt).x = 3; ppunkt->x = 3;

Page 13: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.13

Zeiger und geschachtelte Strukturen

� Strukturvariablen als Komponenten

struct Vektor

{

struct Koordinaten *anfang;

struct Koordinaten *ende;};

� Zeiger vom Typ Vektor

struct Vektor vec, *pvec;

vec.anfang = &punkt2;

vec.ende = &punkt3;

pvec = &vec;

...

pvec->anfang->x bzw.

Page 14: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.14

Strings in Strukturen

� String als Komponentenvariable

struct Name

{

char nachname[20];

char *vorname;

};

struct Name person1 = {"Maier", "Herbert"};

� char nachname[20]; strukturintern, String gehört zur Strukturvariablen

� char *vorname; strukturextern, (in diesem Falle konstanter String)

Page 15: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.15

Typdefinition mit typedef

Page 16: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.16

Was ist typedef?

� Vergabe eines neuen Namens (Alias) neuername für einen

• schon bekannten oder

• soeben definierten Datentyp

typedef bekanntertyp neuername;

� Beispiele: typedef unsigned long int UINT;

UINT a;

typedef float REAL;

REAL b;

Page 17: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.17

Anwendung

� spart Schreibarbeit

� Portierbarkeit von Programmen mit maschinenabhängigen Datentypen(maschinenabhängige Datentypen treten NUR in der typedef Zeile auf)

� Beispiel: Windows-API

https://msdn.microsoft.com/en-

us/library/windows/desktop/aa383751%28v=vs.85%29.aspx

Page 18: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.18

Anwendung

� Beispiel: einheitlicher Long-Integer LINT

typedef long long int LINT; // Anpassung auf LLP64-System

typedef long int LINT; // Anpassung auf LP64-System

Page 19: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.19

typedef und Strukturen

struct Datum

{

short int tag;

char monat[10];

short int jahr;

};

struct Datum heute;

Empfohlene Variante

typedef struct

{

short int tag;

char monat[10];

short int jahr;

} DATUM;

DATUM heute;

Page 20: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.20

Unionen

Page 21: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.21

Union-Definition

� Benutzung wie Struktur

� ABER: alle Komponenten (Alternativen) beginnen bei der selben Adresse

� speichert jeweils nur eine einzige Komponente (aus Reihe von Alternativen)

� Programmierer ggf. muss verfolgen, welcher Typ momentan in der Union gespeichert ist

union Variant

{

int intAlternative;

float floatAlternative;

};

Page 22: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.22

Zugriff auf Alternativen

union Variant

{

int intAlternative;

float floatAlternative;

};

int x;

union Variant vario;

� Alternative schreiben / auslesen

vario.floatAlternative = 123.0;

x = vario.intAlternative;

� Zeiger auf Union

union Variant *pVario = &vario;

x = pVario->intAlternative;

Page 23: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.23

Beispiel: Prozessorregister

struct WORDREGS

{

unsigned int ax;

unsigned int bx;

unsigned int cx;

unsigned int dx;

};

struct BYTEREGS

{

unsigned char al,ah;

unsigned char bl,bh;

unsigned char cl,ch;

unsigned char dl,dh;

};

union REGS

{

struct WORDREGS w;

struct BYTEREGS b;

};

inregs.w.ax = 0x0815; /* BX Register auf Hex 0815 setzen */

inregs.b.ch = 0x1A; /* AH Register auf Hex 1A setzen */

union REGS inregs;

Page 24: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Dynamische Speicherverwaltung

Page 25: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.26

Dynamische Speicherverwaltung

Problem: Speicherbedarf ist während verschiedenerProgrammausführungen unterschiedlich

Lösung: Variablen (insb. Arrays) maximal dimensionieren:

char eingabetext[1000];

Variable Feldgröße in lokalen Arrays nutzen (ab C99)

� Nachteile?

Page 26: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.27

Statische vs. dynamische Variablen

� statische Variable (inkl. lokal, global)

int x;

Verfügbarkeit und Ablage/Speichersegment je nach Speicherklasse (auto, register, static, extern)

� Speichersegmente

Code

Daten

Heap

Stack

lokale

Variable

globale

Variable

Page 27: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.28

Statische vs. dynamische Variablen

� dynamische Variable hat keinen Bezeichner, keine Vereinbarung

� Anlegen erfolgt bei Bedarf auf dem Heap

� Zugriff durch Zeiger auf Bereich im Heap

Daten

Stack

Heap

stat. Pointer-Variable

stat. Pointer-Variable

dyn. Variable

dyn. Variable

Code

Daten

Heap

Stack

lokale

Variable

globale

Variable

Page 28: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.29

Dynamische Speicherverwaltung

Problem: Speicherbedarf ist während verschiedenerProgrammausführungen unterschiedlich

Lösung bisher: Variablen (insb. Arrays) maximal dimensionieren � Nachteil: "verschenkter" Speicher

Page 29: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.30

Dynamische Speicherverwaltung

Problem: Speicherbedarf ist während verschiedenerProgrammausführungen unterschiedlich

Lösung bisher: Variablen (insb. Arrays) maximal dimensionieren � Nachteil: "verschenkter" Speicher

stdlib.h bietet Funktionen zum Speicheranforderung und -freigabe:

void* malloc(int Groesse);

void* calloc(int AnzahlElemente, int ElementGroesse);

void* realloc(void *memBlock, int Groesse);

void free(void *memBlock);

Lösung neu: Speicherbedarf dynamisch, d.h. zur Programmlaufzeitfestlegen

Page 30: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.31

Speicherreservierung mit malloc()

#include <stdio.h>

#include <stdlib.h>

int main()

{

int *pMem;

pMem = malloc(sizeof (int));

if (p != NULL)

{

*pMem = 3;

printf("pointer auf int-Zahl mit Wert: %d\n", *pMem);

free(pMem);

}

else

printf("Speicheranforderung fehlgeschlagen.\n");

return 0;

}

Page 31: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.32

Speicherreservierung mit realloc() I

#include <stdio.h>

#include <stdlib.h>

int main()

{

int *pMem;

pMem = malloc(sizeof (int));

if (pMem == NULL)

{

printf("Speicheranforderung fehlgeschlagen.\n");

return -1;

}

*pMem = 3;

printf("Nach malloc():\n");

printf("pointer auf int-Zahl mit Wert: %d\n", *pMem);

...

Page 32: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.33

Speicherreservierung mit realloc() II

...

pMem = realloc ((void *)pMem, 2 * (sizeof(int)));

if (pMem == NULL)

{

printf ("Speicheranforderung fehlgeschlagen.\n");

return -1;

}

pMem[0] = 4;

pMem[1] = 6;

printf("Nach realloc():\n");

printf("1. Element von pMem hat den Wert: %d\n", pMem[0]);

printf("2. Element von pMem hat den Wert: %d\n", pMem[1]);

free(pMem);

return 0;

}

Page 33: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.34

Speicherreservierung für ein Feld

#include <stdio.h>

#include <stdlib.h>

int main()

{

int *pArray = NULL;

int i, anzahl = 0;

printf "Geben Sie die Anzahl der Feld-Elemente ein: ");

scanf("%d", &anzahl);

pArray = malloc(anzahl * sizeof(int));

if (pArray == NULL)

return -1;

// Nutzung des reservierten Speicherbereichs

for (i = 0; i < anzahl; i++)

pArray[i] = i * i;

...

free(pArray);

return 0;

}

Page 34: Teil 6: Strukturen und Unionen - fritzsch/Programmieren/Folien/Prog06.pdf · Kapitel 6: Strukturen und Unionen Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung 6.21

Kapitel 6: Strukturen und Unionen

Strukturen Typdefinitionen Unionen Dynamische Speicherverwaltung

6.35

malloc & free: Typische Fehler

Fehler Folge

1) kein Speicher mehr frei2) Freigabe einer falschen Adresse u.U. Absturz3) Freigabe bereits freigegeben Speichers u.U. Absturz4) Freigabe eines regulären Feldes /

einer regulären Variablen mit free() u.U. Absturz5) Freigabe eines nicht-initialisierten Speichers u.U. Absturz6) Zugriff auf ungültigen Speicher vor der

Speicheranforderung u.U. Absturz7) Zugriff auf bereits freigegebenen Speicher u.U. Absturz8) Zugriff auf Speicher mit ungültigen Indizes u.U. Absturz9) Verlust des Speichers durch Überschreiben

des Zeigers "memory leak"10) Verlust des Zeigers durch Rücksprung aus

einer Funktion "memory leak"11) Verlust des Zeigers bei Rückgabe

(return-value verworfen) "memory leak"