Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Claudio Moraga; Gisbert Dittrich

Ähnliche Präsentationen


Präsentation zum Thema: "Claudio Moraga; Gisbert Dittrich"—  Präsentation transkript:

1 Claudio Moraga; Gisbert Dittrich
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 6 Claudio Moraga; Gisbert Dittrich FBI Unido

2 Gliederung Kapitel 6: Strukturen
Vereinbarung für Zeichen auf char Zusammengesetzte Strukturen: struct Beispiel Buchdaten (einfach) Vereinbarung Zugriff u.a. unter Verwendung von Zeigern Verwendung Beispiel Buchdaten (komplexer) Karteikarte KarteLesen Aufruf Namensraum

3 Vereinbarung für Zeichen auf char
char Kette[]; // Deklaration einer Zeichenkette // unbestimmter Länge. Kette // ist gleichzeitig ein Zeiger zur // ersten Komponente des Feldes. char Kette[]= “Text“; // Definition einer // Zeichenkette mit dem Initialinhalt “Text“ Kurze Schreibweise (Vereinbarung): char * Kette = “Text“;

4 Vereinbarung für Zeichen auf char
Einige Autoren interpretieren die kurze Schreibweise wie folgt: „Der Datentyp für eine Zeichenkette ist char *, der einen Zeiger auf den Beginn der Zeichenfolge beschreibt, über den auf die Zeichenkette zugegriffen wird. Bei der Ausgabe einer Zeichenkette weißt der zu cout gehörende Ausgabeoperator <<, dass char * nicht als Zeiger, sondern als mit \0 terminierter Zeichenfolge aufzufassen ist.“

5 #include<iostream.h> void main ( ) {
char feldname[ ]= "Frohe Weihnachten!"; char * zeigername; zeigername = &feldname[0]; cout << "\n *zeigername = " << *zeigername << endl; cout << "\n uebernaechstes Symbol = " << *(zeigername + 2) << endl; cout << "\n zeigername = " << zeigername << endl; 1

6 // Nun nur die Abgekürtzte Definition:
char * zeiger_alleine = "Guten Rutsch!"; cout << "\n *zeiger_alleine = " << *zeiger_alleine << endl; cout << "\n uebernaechstes Symbol = " << *(zeiger_alleine + 2) << endl; cout << "\n zeiger_alleine = " << zeiger_alleine << endl; cout << endl; } 2 Ausführen

7 Zusammengesetzte Strukturen
Buch- Daten jahr (int) Möchte die Daten von Büchern verwalten (Daten eines Buchs sollen logisch zusammengefügt werden). seiten (int) Als Beispiel für zusammengesetzte Strukturen wollen wir Bücher diskutieren. Ein Buch wird im Buchhandel ja nicht durch seinen Inhalt katalogisiert, sondern z. B. unter anderem durch sein Erscheinungsjahr, Anzahl der Seiten und den Preis. (Hierbei handelt es sich um eine sehr kleine Buchhandlung, die zunächst lediglich einen Autor vertreibt.) Es ist nun praktisch, die Daten für ein Buch zusammenzuhalten, so daß, wenn man auf ein Buch zugreifen möchte, man diese Informationen nicht aus verschiedenen Daten zusammensuchen muß. Die Folie verdeutlicht das Aussehen einer solchen zusammengesetzten Struktur. Das Beispiel zeigt, wie diese Daten in einer einzigen Struktur abgespeichert werden. preis (float)

8 struct Vereinbarung durch Name der struct struct BuchDaten {
Angabe der einzelnen Komponenten mit Namen und Typ: struct BuchDaten { int jahr, seiten; float preis; }; Name der struct Die entsprechende Möglichkeit zur Strukturierung von Daten heißt Struktur, in C mit dem Schlüsselwort struct charakterisiert, jede dieser structs hat Komponenten, die typisiert sind, und einen Namen, über den die Struktur angesprochen werden kann. In unserem Beispiel handelt es sich um die Struktur Buchdaten, die drei Komponenten hat. Zwei Komponenten sind ganzzahlig (nämlich die Komponente jahr und die Komponente seiten) und eine ist eine Gleitkommazahl, nämlich der Preis. Sie sehen, daß die Typen und die Namen der Komponenten sehr ähnlich aufgeschrieben werden, wie dies etwa in Vereinbarungen für lokale Variable von Funktionen der Fall ist. Typ der Komponenten Name der Komponenten

9 Anmerkungen zu struct Name der Struktur ist zugleich Typname.
damit können Variable und Konstanten deklariert werden: BuchDaten meineDaten; Danach hat die Variable meineDaten den Typ BuchDaten Zugriff auf die Komponenten (jahr, seiten, preis) durch Qualifikation: meineDaten.jahr Der hinter dem Schlüsselwort struct angegebene Name der Struktur ist zugleich der Name des entsprechenden Typs. Erinnern Sie sich: Ein Typ beschreibt unter anderem die mögliche Wertemenge, die eine Variable dieses Typs annehmen kann. In unserem Fall haben wir also Werte, die jeweils aus drei Komponenten bestehen, wobei die ersten beiden Komponenten ganzzahlig und die letzte Komponente reellwertig ist. Weil wir einen Typnamen haben, können wir auch Variable und Konstanten auf diese Art deklarieren, wie dies bei den bisher behandelten Typen, die üblicherweise primitiv heißen, ja bereits geschehen kann. Betrachten Sie das angegebene Beispiel, das eine Variable vom Typ BuchDaten deklariert. Der Zugriff auf die Komponenten geschieht durch die Angabe der Variablen, dann einen Punkt und den Namen der Komponenten. Dies bezeichnet man als Qualifikation.

10 Anmerkungen zu struct Beispiel (Zuweisung über Komponenten) meineDaten.jahr = GanzeZahlLesen("Jahr: "); meineDaten.seiten = GanzeZahlLesen("Seiten: "); meineDaten.preis = ReelleZahlLesen("Preis: "); Andere Möglichkeit durch Zuweisung einer vollständigen struct (vom Typ BuchDaten) meineDaten = dieseDaten Über Verwendung von Zeigern (analog) Auf diese Komponenten kann lesend zugegriffen werden, so daß diese Komponenten ihren Wert abgeben, sie können aber auch geschrieben werden, ihnen kann also ein Wert zugewiesen werden. Beides geschieht durch Qualifikation und ist durch die Beispiele auf der Folie erläutert. Man kann natürlich auch eine Struktur vollständig einer anderen zuweisen. Dies geschieht durch Verwendung des Gleichheitszeichens. In analoger Weise können auch Adressen einander zugewiesen werden.

11 Anmerkungen zu struct Zuweisung unter Verwendung von Zeigern:
Z.B.: Gib die Adresse eines Elements von BuchDaten an, schreibe die eingelesenen Daten "an die entsprechende Adresse“ : BuchDaten meineDaten LiesBuchDaten (&meineDaten); Die Funktion LiesBuchDaten ist so definiert: Die Zuweisung an Komponenten eines zusammengesetzten Objekts wird zudem durch ein Beispiel erläutert, indem man einen Zeiger als Parameter verwendet: Beim Aufruf kann man als aktuellen Parameter speziell auch als konkreten Wert eines solchen Zeigers die Adresse eine entsprechend getypten Objektes verwenden. Die Funktion, mit deren Hilfe dies bewerkstelligt wird, findet sich auf der nächsten Folie.

12 Signatur benutzter Funktionen
Anmerkungen struct Funktion LiesBuchDaten Signatur benutzter Funktionen Zeiger auf Typ BuchDaten int GanzeZahlLesen (char *); float ReelleZahlLesen (char *); void LiesBuchDaten (BuchDaten *bd) { bd->jahr = GanzeZahlLesen ("Jahr: "); bd->seiten = GanzeZahlLesen ("Seiten: "); bd->preis = ReelleZahlLesen ("Preis: "); } Betrachten wir zunächst die Signatur der Funktion LiesBuchDaten. Sie gibt keinen Wert zurück und hat als einzigen Parameter einen Zeiger. Zunächst wird die Signatur der beiden benutzten Funktionen vereinbart. Und dann weist man den einzelnen Komponenten durch Aufruf der Funktionen Werte zu. Beachten Sie hierbei die Konstruktion von bd->jahr. Dies ist eine Abkürzung dafür, daß wir zunächst die entsprechende Variable dereferenzieren und dann die Komponente jahr extrahieren; dieser Ausdruck steht also für (*bd).jahr. Bei den anderen Funktionen verhält es sich völlig analog. Insgesamt arbeitet die Funktion LiesBuchDaten also so, daß ein Zeiger auf ein Element vom Typ BuchDaten übergeben wird. Die Komponenten, die unter dieser Adresse zu finden sind, werden dann entsprechend gefüllt. bd->jahr steht für (*bd).jahr Zuweisung an Komponenten

13 Anmerkungen struct Also:
in der Funktionsdefinition wird als formaler Parameter verwendet Zeiger auf Element vom Typ BuchDaten. im Rumpf der Definition Zugriff durch Dereferen-zieren Beispiel: Die Komponente jahr wird angesprochen als (*bd).jahr, abgekürzt als bd->jahr Aufruf : Im Beispiel: mit konkreter Adresse &meineDaten Aus dieser Konstruktion folgt unmittelbar, daß, wenn wir eine Variable vom Typ Buchdaten einlesen wollen, wir ihre Adresse als Parameter an diese Funktion übergeben müssen. LiesBuchDaten(&meineDaten)

14 Anmerkungen struct Vereinbarung konstanter structs durch Angabe der Werte: const BuchDaten dieseDaten = {1997,234,14.70}; Es ist übrigens möglich, konstante Strukturen durch Angabe der Werte zu vereinbaren. Diese Werte werden in geschweifte Klammern eingeschlossen. Es müssen so viele Werte angegeben werden, wie Komponenten vorhanden sind. Die Folie macht dies an einem Beispiel klar.

15 Anmerkungen zu {..} Allgemein:
Wertangaben bei der Definition zur gleichzeitigen Initialisierung mehrerer Werte können in geschweiften Klammern {..} angegeben werden. Weiteres Beispiel: char s[4] = {'a', 'b', 'c', ‘\0'}; (wirkt wie die Zeichenkette s="abc") Allgemein sieht man, daß Wertangaben bei der Deklaration in geschweiften Klammern zur Initialisierung herangezogen werden. Wir zeigen dies an dem Beispiel einer Zeichenkette, die mit einzelnen Zeichen gefüllt wird. Beachten Sie, daß wir das Symbol für das Ende der Zeichenkette ebenfalls hier angeben müssen, wenn wir eine Zeichenkette (und nicht ein Feld von Zeichen) haben wollen.

16 Beispiel Karteikarte für ein Buch soll enthalten:
Wir gestalten die Buchdaten jetzt ein wenig komplexer: Eine Karteikarte mit den Daten eines Buchs soll nun Angaben über Verfasser, Titel und Verlag enthalten und dann die Buchdaten, die wir gerade behandelt haben. Die Zeichenketten sollen alle von verschiedener Länge sein, die Sie in der angegebenen Tabelle finden. Das Beispiel soll zeigen, daß Strukturen selbst wieder Strukturen als Komponente haben können, so daß die Bildung von Strukturen eigentlich nichts exorbitant Außergewöhnliches darstellt. Wir fangen jetzt an, einen Baukasten aufzubauen, mit dessen Hilfe wir recht komplizierte Gebilde aufbauen können. Der Baukasten ist insofern flexibel, als die aufgebauten Strukturen wie hier selbst wieder Teil größerer Strukturen sein können.

17 Beispiel Direkte Umsetzung der angegebenen Spezifi-
const int autorMax = 75, titelMax = 100, verlagMax = 128; struct karteikarte { char autor [autorMax]; char titel [titelMax]; char verlag [verlagMax]; BuchDaten dieDaten; }; Direkte Umsetzung der angegebenen Spezifi- kation für die Daten. Strukturen können selbst Strukturen enthalten

18 Buchdatei void AngabeLesen (char *, char *, int);
void LiesBuchDaten(Buchdaten *); void KarteLesen(int i, karteikarte * k){ cout << "Buch Nr. :" << (i + 1) << endl; AngabeLesen("Autor: ", k->autor, autorMax); AngabeLesen("Titel: ", k->titel, titelMax); AngabeLesen("Verlag : ", k->verlag, verlagMax); LiesBuchDaten (&(k->dieDaten)); } Wir demonstrieren die Verwendung der Karteikarten in der Funktion KarteLesen, die eine ganze Zahl als Ordnungszahl und einen Zeiger auf eine Karteikarte als Parameter enthält. Dies beinhaltet insbesondere das Verhalten, wie es in der Funktion LiesBuchDaten besprochen wurde. Wir haben hier einige Angaben ausgelassen, weil es uns darauf ankommt, die Verwendung komplexer Strukturen innerhalb anderer Strukturen zu demonstrieren.

19 KarteLesen/Buchdatei
Der Aufruf KarteLesen (17, &ka) liest die Karte Nr. 17 ein und speichert sie unter der Adresse &ka (wobei vereinbart ist Karteikarte ka) Programm: KKarte als struct

20 1 // K6-P1 KKarte als Struct // // demonstriert structs
// Bei Behandlung von "Randfällen" nicht robust. // Fehlerhaft !? #include <iostream.h> #include <stdio.h> const char ZeilenEnde = '\n', Null = '\0'; const int autorMax = 75, titelMax = 100, verlagMax = 128; struct BuchDaten { int jahr, seiten; float preis; } 1

21 2 struct karteikarte { char autor[autorMax]; char titel[titelMax];
char verlag[verlagMax]; BuchDaten dieDaten; }; //Funktionsprototypen int GanzeZahlLesen(char *); float ReelleZahlLesen(char *); void LiesBuchDaten (BuchDaten *); void AngabeLesen(char *, char *, int); void KarteLesen(int, karteikarte *); void AutorAusgeben(karteikarte *); void TitelAusgeben(karteikarte *); const int n=2; 2

22 3 main() { // const int n=2; karteikarte kartei[n],*zk; int i;
cout << "Eingabe der Kartei-Karten:\n"; for (int i=0;i<n;i++) KarteLesen(i, &kartei[i]); zk = kartei; cout << "\nAusgabe der Autoren:\n"; for (i=0;i<n;i++) { AutorAusgeben(zk); TitelAusgeben(zk++); } cout << '\n' << "Fertig!" << endl; 3

23 4 void AngabeLesen(char * prompt, char * angabe, int maxWert){
int i = 0; cout << prompt << "(Zeichenkette)\t"; for (i = 0; (angabe[i] = getchar()) != ZeilenEnde && i < maxWert; i++); if (i <= maxWert) angabe[i] = Null; } void LiesBuchDaten (BuchDaten *bd) { bd->jahr = GanzeZahlLesen ("Jahr: "); bd->seiten = GanzeZahlLesen ("Seiten: "); bd->preis = ReelleZahlLesen ("Preis: "); void KarteLesen(int i, karteikarte * k){ cout << “\nBuch Nr. :" << (i + 1) << endl; AngabeLesen("Autor: ", k->autor, autorMax); AngabeLesen("Titel: ", k->titel, titelMax); AngabeLesen("Verlag : ", k->verlag, verlagMax); LiesBuchDaten (&(k->dieDaten)); 4

24 5 int GanzeZahlLesen(char * prompt) { int i;
cout << prompt << "(ganze Zahl)\t"; cin >> i; return i; } float ReelleZahlLesen(char * s) { float fl; cout << s << "(reelle Zahl)\t"; cin >> fl; return fl; 5

25 6 Ausführen void AutorAusgeben(karteikarte * k){
cout << "Autor : " << k->autor << '\n'; } void TitelAusgeben(karteikarte * k){ cout << "Titel : " << k->titel 6 Ausführen

26 KarteLesen/Buchdatei
Jedes struct hat seinen eigenen Namensraum struct eins { int x; char *t; } struct zwei { float x; int t; unabhängig voneinander Wir hatten gesehen, daß Strukturen über Komponenten verfügen, die selbst wieder mit Namen und Typ versehen sind. Wir merken an dieser Stelle an, daß die Namensgebung sozusagen lokal für die Struktur-Vereinbarung ist: Taucht etwa der Name x in zwei verschiedenen Strukturen auf, so sind diese Namen vollständig unabhängig voneinander. Uns begegnet hier ein Lokalitätsprinzip, das ganz ähnlich zur Vereinbarung lokaler Namen in Funktionen ist. Es ist also hier festzuhalten, daß die Namensräume für Strukturen unabhängig voneinander sind, wie Sie dem angegebenen Beispiel entnehmen können.


Herunterladen ppt "Claudio Moraga; Gisbert Dittrich"

Ähnliche Präsentationen


Google-Anzeigen