30
Prof. Dr. Nikolaus Wulff Programmieren in C Programmieren in C Eigene Datentypen per typedef und Strukturen

Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

  • Upload
    ngothu

  • View
    229

  • Download
    4

Embed Size (px)

Citation preview

Page 1: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff

Programmieren in CProgrammieren in C

Eigene Datentypen per typedef und Strukturen

Page 2: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 2

C Datentypen

• Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char, etc.

• Zusätzlich definiert die Sprache Operationen die mit den Datentypen erlaubt sind, +,*, etc.

• Diese Typen sind eng angelegt an die Möglichkeiten einer CPU und den primitiven mathematischen Operationen, die damit möglich sind.

• Für fachliche Anwendungen ist es wünschenswert eigene Datentypen zu verwenden, wie z.B. einen Geldbetrag, ein Datum, eine Farbe, etc.

Page 3: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 3

Eigene Datentypen

• C kennt verschiedene Mechanismen, um eigene Datentypen zu definieren.

• Diese Typen können dann mit „sprechenden Typnamen“ versehen sein.

• Dies ermöglicht es sprachlich näher an der Semantik des Problembereichs zu bleiben.

• Dies erleichtert die Lesbarkeit und kann auch verwendet werden, um Programme leichter zwischen verschiedenen Maschinenarchitekturen zu portieren.

Page 4: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 4

Aufzählungstypen

• Das Konzept von Aufzählungen (eng. Enumeration) kommt derart häufig vor, das C hierfür eine eigene Anweisung besitzt, um einen Aufzählungstypen für Konstanten zu definieren.

• Statt vieler Konstanten per #define wird die enum Anweisung verwendet, um einen ganzen Satz von Konstanten zu definieren.

enum <identifier> { value1,...,value

N};

Page 5: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 5

Boolean per enum

• C kennt keinen Booleschen Datentyp, daher werden die Variablen TRUE und FALSE häufig per #define Anweisung definiert:

• Sauberer geht es per enum:

• Die Voreinstellung ist, dass der erste Bezeichner (hier false) mit 0 belegt wird und dann wird jeweils um eins inkrementiert.

#define FALSE 0#define TRUE 1

enum Boolean { false, true};

Page 6: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 6

Wochentage

• Wir wollen ein Programm Kalender zur Bearbeitung von Wochentagen entwickeln.

• Die Header Datei Kalender.h könnte so aus sehen:

#define MONDAY 1#define TUESDAY 2#define WEDNESDAY 3#define THURSDAY 4#define FRIDAY 5#define SATURDAY 6#define SUNDAY 7

void printDay(int day);

Page 7: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 7

Aufzählungstypen

• Statt vieler Konstanten per #define wird die enum Anweisung verwendet.

• Damit die Zählung nicht mit monday bei 0 beginnt, kann explizit der erste Wert belegt werden.

• Der enum Typ „Day“ kann sogar als Parametertyp in der Methode printDay deklariert werden.

enum Day { monday=1, tuesday, wednesday, thursday, friday, saturday,

sunday};

void printDay(enum Day day);

Page 8: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 8

Verwendung von enum

• Die Methode printDay kann nun mit den Konstanten des Aufzählungstypen Day gerufen werden:

• aber auch ein Aufruf mit int funktioniert:

• Intern wird enum immer als eine Konstante vom Typ int repräsentiert.

• Leider kann auch Unsinn übergeben werden:

• Merke: Wir kümmern uns um die Namen, der Compiler um die Werte...

printDay(tuesday);

printDay(2);

printDay(-20);

Page 9: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 9

Enum sind intern Integers

• Für solche Fälle muss eine Möglichkeit der Fehlerbehandlung vorgesehen werden...

void printDay(enum Day day) { switch(day) { case monday: case tuesday: case wednesday: case thursday: case friday: printf("Go to work\n"); break; case saturday: case sunday: printf("Sleep well it's weekend\n"); break; default: printf("Unknown day %d\n", day); handleError(); };}

Page 10: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 10

Enum Konstanten vorbelegen

• Die enum Konstanten können beliebig vergeben werden auch mit negativen Werten:

• Es lassen sich mehrere Bezeichner mit dem selben Wert belegen:

enum example { a, b, c, d, e=-2, f, g, h i=-3, j, k, l, m, ...};

Wert Name-3 i-2 e j-1 f k 0 a g l 1 b h m 2 c 3 d

Page 11: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 11

Alias per typdef

• Während enums immer Konstanten vom Typ int sind gibt es mit dem typedef Konstrukt eine Möglichkeit ein Alias für einen schon existierenden beliebigen Typ zu vergeben:

• So kann z.B. das Konstrukt char* mit einer Zeichenkette als String identifiziert werden:

• s ist immer noch eine Variable vom Typ char*!

typedef <type> <new_type_identifier>;

typedef char* String;

String s = "Hallo";

Page 12: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 12

Anwendungen von typedef

• Ein paar Beispiele zur Anwendung von typedef:

• Die Bedeutung des Codes erschließt sich mit den Typen Alter und Geld wesentlich leichter, als wenn dort mit unsigned short gearbeitet worden wäre.

• Sollte die Genauigkeit von float nicht ausreichen, genügt es den typedef auf double zu ändern und an allen Stellen, wo Geld vorkommt wird mit double gerechnet ...

typedef float Geld;typedef unsigned short Alter;

Alter volljaehrig = 18;Geld gehalt = 4711.00;

Page 13: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 13

typedef und enum

• Etwas unschön beim Day Beispiel war es überall in den Methodensignaturen enum mit einzufügen:

• Wesentlich eleganter geht es mit typedef :

• oder in einem Rutsch:

enum Day { monday=1, tuesday, ...};

void printDay(enum Day day);

enum day_enum { monday=1, tuesday,...};typedef enum day_enum Day;

void printDay(Day day);

typedef enum { monday=1, tuesday,...} Day;

Page 14: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 14

Ein altes Beispiel ...

/** two constants for f2c and c2f calculus */#define SHIFT 32.0#define SCALE (9.0/5.0)

/** calulate celsius as fct of fahrenheit */double f2c(double f) { double c = (f - SHIFT)/SCALE; return c;}/** calulate fahrenheit as fct of celsius */double c2f(double c) { double f = c*SCALE + SHIFT; return f;}

• Da müsste sich doch mit typedef etwas machen lassen ...

Page 15: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 15

Nochmal Celsius zu Fahrenheit

• So wird der Code sprechend ...

/** two constants for f2c and c2f calculus */#define SHIFT 32.0#define SCALE (9.0/5.0)

typedef double Celsius;typedef double Fahrenheit;

/** calulate celsius as fct of fahrenheit */Celsius f2c(Fahrenheit f) { Celsius c = (f - SHIFT)/SCALE; return c;}/** calulate fahrenheit as fct of celsius */Fahrenheit c2f(Celsius c) { Fahrenheit f = c*SCALE + SHIFT; return f;}

Page 16: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 16

C Datentypen• Die bis lang vorgestellten Konstrukte, enum und

typedef, erfüllen noch nicht die Anforderung an selbst definierten Datentypen.

• enum definiert Aufzählungen von int Konstanten.

• typedefs sind lediglich alias Bezeichner für bereits existierende Datentypen.

• Keines der beiden Konstrukte liefert wirklich einen neuen Datentyp.

Page 17: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 17

Do it yourself...• Wir möchten den Datentyp Farbe (Color)

implementieren.

• Color soll die drei Werte (r,g,b) als Triple, jeweils im Bereich 0<x<255 repräsentieren. = >(28,28,28)

• Welch Möglichkeiten kennen wir bis lang?

– Farbwerte in einer 4Byte Ganzzahl abspeichern

– Farbwerte in einem short/char Array abspeichern

Page 18: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 18

Farbe als Ganzzahl modelliert• Ein int mit 4 Byte (ansonsten typedef mit long)

bietet genug Platz, um 3 Byte rgb-Werte abzulegen, mit entsprechenden Bit und Shift Operationen...

• Die get-Methoden lesen mit entsprechenden Masken und shift Operationen die rgb-Werte.

typedef int Color;

#define R_MASK 0x00FF0000#define G_MASK 0x0000FF00#define B_MASK 0x000000FF

#define getR(C) ( ((C) & R_MASK)>>16 )#define getG(C) ( ((C) & G_MASK)>>8 )#define getB(C) ( ((C) & B_MASK) )

Bits: 0| 1| ... |7|8| ... |15|16| ... |23|24| ... |32

Page 19: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 19

Farbe als Ganzzahl setzen• Ein Farb-Byte gezielt innerhalb des 4 Byte Color int

zu setzten erfordert schon mehr Operationen:

• Zunächst werden die Bits der zu setzenden Farbe gelöscht, ohne die beiden anderen Farben zu löschen.

• Anschließend wird mit oder der neue Wert gesetzt.

• Diese Bytefolge ergibt sich aus einer Shift-Operation des Farbwertes und anschließender Maskierung.

#define setR(C,x) ( (C) = \ ((C) & ~R_MASK)|(((x)<<16)& R_MASK))#define setG(C,x) ( (C) = \ ((C) & ~G_MASK)|(((x)<< 8)& G_MASK))#define setB(C,x) ( (C) = \ ((C) & ~B_MASK)|((x) & B_MASK) )

Farbe löschen neuer Farbwert

Page 20: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 20

Ganzzahl Variante• Durch die Macros lassen sich per get/setX die Bit

und Shift-Operationen verstecken und in eine Color.h Datei auslagern.

• Ein Nachteil ist, dass für jeden getX/setX Befehl Berechnungen durchgeführt werden müssen.

• Eine Zuweisung per = Operanden funktioniert nicht, es ist immer ein setX Befehl notwendig.

Color color; setR(color,238); setG(color,124); setB(color, 32); printf("Color (%d,%d,%d)\n", getR(color),getG(color),getB(color));

Page 21: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 21

Farbe als Feld modellieren

• In diesem Fall werden die Farbeinträge als Feld abgelegt und auf jede Komponente kann direkt zugegriffen werden.

• Die Makros verstecken vor der Testroutine wieder die Implementierungsdetails ...

typedef unsigned char Color[3];

#define getR(C) ( (C)[0])#define getG(C) ( (C)[1])#define getB(C) ( (C)[2])

#define setR(C,x) ( (C)[0] = x)#define setG(C,x) ( (C)[1] = x)#define setB(C,x) ( (C)[2] = x)

Page 22: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 22

Feld Variante• Für die getX/setX Methoden sind keine

Berechnungen notwendig.

• Es ist möglich direkte Zuweisungen mit dem = Operanden vorzunehmen.

• Es muss immer berücksichtigt werden, dass es sich bei diesem Color Typ um ein Feld der Länge drei handelt, d.h. Zuweisungen geschehen per Index:

• Beide bisherigen Varianten sind unbefriedigend...

Color color ={0,255,127}; color[1] = 32; setR(color,125);

Page 23: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 23

C Strukturen • Im Allgemeinen kennen Programmiersprachen für

genau diese Problematik ein eigenständiges Model- lierungselement: z.B. in Pascal den record, in C das struct und OO-Sprachen besitzen hierzu das Konzept der Klasse.

• Ein struct ist ein neuer Datentyp. Zusammengesetzt als Aggregat aus bereits bekannten Datentypen:

struct <identifier> { type

1 <identifier

1>;

... ; typeN <identifierN>;};

Page 24: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 24

Color struct

• Die Zuweisungen sind viel deutlicher und klarer.

• Ein struct ist ein eigenständiger neuer Datentypen.

• Per typedef wird häufig ein struct-Zeiger definiert.

struct color_struct { unsigned char r; unsigned char g; unsigned char b;};typedef struct color_struct Color;

#define getR(C) ( (C).r )#define getG(C) ( (C).g )#define getB(C) ( (C).b )

#define setR(C,x) ( (C).r = (x) )#define setG(C,x) ( (C).g = (x) )#define setB(C,x) ( (C).b = (x) )

struct Definition

typedef mit struct

Page 25: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 25

struct Verwendung

• Ein struct kann bei der Erzeugung direkt mit entsprechenden Werten vorbelegt werden.

• Mit dem „ “ Operator wird auf die einzelnen Elemente des struct in beliebiger Reihenfolge sowohl lesend als auch schreibend zugegriffen.

• Die getX/setX Makros sind im Prinzip überflüssig.

Color white = {255,255,255}; Color color;

color.r = white.r; color.g = 64; color.b = 32;

printf("Color (%d,%d,%d)\n", color.r, color.g, color.b);

.

Page 26: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 26

Der komplexe Datentyp• Für die Ingenieurwissenschaften sind in vielen

Bereichen die komplexen Zahlen von Bedeutung.

• Mit Hilfe eines struct fällt es leicht diesen Datentypen zu implementieren und auch entsprechende Methoden wie +, - , * und / zu definieren.

• Ein gut modellierter abstrakter Datentyp (ADT) zeichnet sich nicht nur dadurch aus, dass er Felder besitzt, sondern auch noch einen Satz von Methoden, für die gültigen Operationen dieses ADT.

Page 27: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 27

Complex.h#ifndef __COMPLEX_H#define __COMPLEX_H/** * Structure for the complex ADT. */typedef struct { double real, imag;} Complex;

/** * The basic operations for the complex ADT. */Complex cadd(const Complex u, const Complex v);Complex csub(const Complex u, const Complex v);Complex cmul(const Complex u, const Complex v);Complex cdiv(const Complex u, const Complex v);

#endif /* __COMPLEX_H */

struct Definition undtypedef in einemSchritt ...

Page 28: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 28

Complex.c/** multiplication of two complex numbers */Complex cmul(const Complex u, const Complex v) { Complex z = { u.real * v.real - u.imag * v.imag, u.real * v.imag + u.imag * v.real }; return z;}

• Sobald die wesentlichen Operationen definiert und implementiert sind lässt sich leicht mit komplexen Zahlen rechnen.

• Leider erlaubt es C nicht die Operatoren für +,-,*,/ zu überladen, wie es mit C++ möglich ist. Deshalb werden die Methoden cadd, cmul, etc. definiert.

Page 29: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 29

structs verschachteln• Strukturen können ihrerseits wieder aus Strukturen

zusammengesetzt sein:typedef struct { String town; String street; long zipCode;} Adress;

typedef struct { short year, month, day;} Date;

typedef struct { String name; String surname; Adress adresse; Date birthday;} Person;

Page 30: Programmieren in C Eigene · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 2 C Datentypen • Variablen in C sind immer von einem bestimmten Datentyp, z. B. int, float, char,

Prof. Dr. Nikolaus Wulff Programmieren in C 30

Anwendung von Strukturen• Mit Hilfe von geschachtelten Strukturen lassen sich

Zugriffe recht übersichtlich programmieren:

Person nw;

nw.name = "Nikolaus"; nw.surname = "Wulff";

nw.adresse.town = "Steinfurt"; nw.adresse.street = "Stegerwaldstr. 39"; nw.adresse.zipCode = 48565;

nw.birthday.month = 11; nw.birthday.day = 20; ...