Einführung in die Programmierung für Physiker. Die Programmiersprache C Strukturen ("struct...")

Ähnliche Dokumente
Einführung in die Programmierung für Physiker. Die Programmiersprache C Strukturen ("struct...")

Informatik. Pointer (Dynamisch) Vorlesung. 17. Dezember 2018 SoSe 2018 FB Ing - SB Umwelttechnik und Dienstleistung - Informatik Thomas Hoch 1

Praxis der Programmierung

Betriebssysteme, Rechnernetze und verteilte Systeme 1. Crashkurs C (2)

Algorithmen und Datenstrukturen

Einführung in die Programmierung zusammengesetzte Datentypen, dynamischer Speicher

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

Zeiger und dynamischer Speicher

Einführung in die Programmierung für Physiker. Die Programmiersprache C Kontrollstrukturen

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

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

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

Einführung in die Programmierung für Physiker. Die Programmiersprache C Ein- und Ausgabe

Einführung in die Programmierung Konstanten, dynamische Datenstrukturen. Arvid Terzibaschian

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

C++ Teil 6. Sven Groß. 23. Nov Sven Groß (IGPM, RWTH Aachen) C++ Teil Nov / 15

Dynamische Speicherverwaltung

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

Übersicht. Einführung in die Programmierung. Zeichenketten. Zeichenketten. Zeichenketten. Arrays und Zeichenketten. Arrays und Zeichenketten

Advanced Programming in C

Einführung in die Programmiersprache C

Einführung in die Programmiersprache C

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

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

Algorithmen und Datenstrukturen (für ET/IT)

Kontrollfragen Mikrocontroller Programmiersprache C H1203 Felix Rohrer

7. Organisation von Informationen

Einführung in die Programmierung für Physiker. Die Programmiersprache C++ Basics an Hand von Beispielen

Einführung in die Programmierung für Physiker. Die Programmiersprache C++ Basics an Hand von Beispielen

Programmierkurs C/C++

Algorithmen und Datenstrukturen (für ET/IT) Wiederholung: Ziele der Vorlesung. Wintersemester 2012/13. Dr. Tobias Lasser

Hinweise zur Prüfung Programmieren WS0304 Seite 1. Schreiben Sie folgende For-Schleife in eine äquivalente While-Schleife um.

Programmierkurs C++ Datenstrukturen Seite 1

Grundlagen der Programmiersprache C für Studierende der Naturwissenschaften

Vorlesung Datenstrukturen

F Zeiger, Felder und Strukturen in C

Praxis der Programmierung

Modellierung und Programmierung

Nachname:... Vorname:... MatrNr.:... Klausur PR2. int main() { char Text[] = "Sehr geehrte Damen und Herren!"; char *tmp=text;

C- Kurs 09 Dynamische Datenstrukturen

INE1 Arrays, Zeiger, Datenstrukturen

Fakultät Angewandte Informatik Lehrprofessur für Informatik

Typ : void* aktuelle Parameter Pointer von beliebigem Typ

Programmierung mit C Zeiger

Lösungen der P1-Musterprüfungsaufgaben

Datenkapselung: public / private

Programmiersprachen Einführung in C

Inhalt. 1 Einstieg in die Welt von C Erste Schritte in C 31. Vorwort... 15

Teil 5: Zeiger, Felder, Zeichenketten Gliederung

Crashkurs C++ - Teil 1

Zusammengehörige Daten struct. Strukturierte Datentypen und Funktionszeiger. Zugriff auf struct-elemente. Variablendeklarationen mit struct

Mazura. h 2. Vertiefung

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

Pointer und Arrays. INE1, Montag M. Thaler, Office TG208. ZHAW, M. Thaler, K. Rege, G.

Datenkapselung: public / private

6 ZEIGER UND REFERENZEN - ALLGEMEINES

Grundlagen der Informatik

Probeklausur Name: (c)

Programmieren in C. Rekursive Strukturen. Prof. Dr. Nikolaus Wulff

Teil 6: Strukturen und Unionen Gliederung

Algorithmen und Datenstrukturen (für ET/IT)

Grundlagen der Informatik 12. Strukturen

Datenstrukturen. InE1 M. Thaler, Office TG ZHAW, M. Thaler, K. Rege, G. Burkert

Einführung Sprachfeatures Hinweise, Tipps und Styleguide Informationen. Einführung in C. Patrick Schulz

C++ - Objektorientierte Programmierung Konstante und statische Elemente

U8 7. Übung U8 7. Übung

Klausur Kompaktkurs Einführung in die Programmierung Dr. T. Weinzierl & M. Sedlacek 25. März 2011

Objekte werden eindeutig beschrieben durch ihren Typ und einen beliebig wählbaren Bezeichner.

Strukturierte Datentypen (struct) 2006 Pearson Education, Inc. All rights reserved.

Einführung in die Programmierung Konstanten, dynamische Datenstrukturen. Arvid Terzibaschian

Einstieg in die Informatik mit Java

Operatoren in C. Gastvorlesung Andreas Textor

Zeiger vom Typ void* benötigen weniger Speicher als andere Zeiger, da bei anderen Zeigertypen zusätzlich die Größe gespeichert werden muss.

Hydroinformatik I: Referenzen und Zeiger

C:\!hinher\AdressVw.cpp Top. <überschrift>

structure-type-specifier struct [ identifier ] { struct-declaration-list } struct identifier struct-declaration-list struct-declaration

Mapra: C++ Teil 4. Felix Gruber. 6. Mai IGPM, RWTH Aachen. Felix Gruber (IGPM, RWTH Aachen) Mapra: C++ Teil 4 6.

Datenkapselung: public / private class rational { r.d = 0 int n; int d; // INV: d!= Klassen rational r; r.n = 1; // error: n is private

Programmiertechnik. Teil 4. C++ Funktionen: Prototypen Overloading Parameter. C++ Funktionen: Eigenschaften

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

C- Kurs 03 Ausdrücke und Operatoren

Teil 5: Felder, Zeiger, Zeigerarithmetik Gliederung

2. Programmierung in C

Vorlesung 6: Operatoren, Logische Ausdrücke

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

Arrays (Felder/Vektoren)

2. Programmierung in C

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

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

FH Ravensburg-Weingarten Schriftlich Prüfung Programmieren

8. Referenzen und Zeiger

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

Globale Variablen Diverses. Globale Variablen. Globale Variablen

Arrays. Theorieteil. Inhaltsverzeichnis. Begriffe. Programmieren mit Java Modul 3. 1 Modulübersicht 3

9. Vektoren. (auch Felder/array)

Programmierkurs C++ Variablen und Datentypen

Grundgebiete der Informatik 2 Lösungsvorschlag zur Probeklausur

Beispiel. Problem: mehrteilige Nachnamen (von Goethe, Mac Donald, Di Caprio)

DAP2-Programmierpraktikum Einführung in C++ (Teil 2)

Transkript:

Einführung in die Programmierung für Physiker Die Programmiersprache C Strukturen ("struct...") Marc Wagner Institut für theoretische Physik Johann Wolfgang Goethe-Universität Frankfurt am Main WS 2017/18

Strukturen Eine Struktur (structure) ist eine Gruppierung mehrerer Variablen zu einem neuen Datentyp; die Variablen können unterschiedlichen Datentyps sein. Strukturen dienen der Organisation konzeptionell zusammengehöriger Variablen; sie vereinfachen die Programmierung und erhöhen die Lesbarkeit von Programmcode. Syntax (Definition einer Struktur): struct tag { type1 name1; type2 name2;... }; tag bezeichnet den Namen der Struktur (Etikett, structure tag). type1 name1 bezeichnet Datentyp und Namen der ersten Variable der Struktur (Komponente, member). type2 name2 bezeichnet Datentyp und Namen der zweiten Variable der Struktur (Komponente, member).... Nach einer solchen Strukturdefinition bildet struct tag einen eigenen Datentyp, kann syntaktisch also analog zu int, double, etc. verwendet werden; z.b. kann mit struct tag name; eine Variable vom Datentyp struct tag und mit Namen name definiert werden. Auf die Komponenten einer Struktur kann mit. zugegriffen werden, z.b. name.name1, name.name2,... Beispiel: Struktur für 2-komponentige Vektoren und einige zugehörige Funktionen... 1. #include<stdio.h> 2. 3. // ******************** 4. 5. // Definition einer Struktur fuer 2-komponentige Vektoren. 6. struct vec2d 7. { 8. 9. 10. }; 11. double x; double y; 12. // ******************** 13. 14. // Initialisieren eines 2-komponentigen Vektors. 15. struct vec2d vec2d_init(double x, double y) 16. { 17. 18. 19. 20. 21. } 22. struct vec2d v; v.x = x; v.y = y; return v; 23. // ******************** 24. 25. // Ausgabe eines 2-komponentigen Vektors. 26. void vec2d_print(struct vec2d v) 27. { 28. 29. } 30. printf("( %+.2lf, %+.2lf )\n", v.x, v.y); 31. // ******************** 32. 33. // Addition zweier 2-komponentiger Vektoren. 34. struct vec2d vec2d_add(struct vec2d v1, struct vec2d v2)

35. { 36. struct vec2d v; 37. v.x = v1.x + v2.x; 38. v.y = v1.y + v2.y; 39. return v; 40. } 41. 42. // ******************** 43. 44. //... (Weitere Funktionen fuer 2-komponentige Vektoren.) 45. 46. // ******************** 47. 48. int main(void) 49. { 50. struct vec2d v1, v2; 51. 52. v1 = vec2d_init(1.0, 2.0); 53. v2 = vec2d_init(3.0, 4.0); 54. 55. printf("v1 = "); 56. vec2d_print(v1); 57. printf("v2 = "); 58. vec2d_print(v2); 59. 60. struct vec2d v3 = vec2d_add(v1, v2); 61. printf("v3 = v1 + v2 = "); 62. vec2d_print(v3); 63. } v1 = ( +1.00, +2.00 ) v2 = ( +3.00, +4.00 ) v3 = v1 + v2 = ( +4.00, +6.00 ) Strukturen können nicht mit Vergleichsoperatoren verglichen werden. 43.... 44. int main(void) 45. { 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. } struct vec2d v1, v2; v1 = vec2d_init(1.0, 2.0); v2 = vec2d_init(3.0, 4.0); if(v1 == v2) else // Liefert einen Fehler beim Kompilieren. printf("v1 ist gleich v2.\n"); printf("v1 ist ungleich v2.\n"); mwagner@laptop-tigger:~/lecture_progphys/slides/tmp$ g++ -o prog prog.c prog.c: In Funktion "int main()": prog.c:60:12: Fehler: keine Übereinstimmung für "operator==" in "v1 == v2" mwagner@laptop-tigger:~/lecture_progphys/slides/tmp$ gcc -o prog prog.c prog.c: In Funktion "main": prog.c:60:9: Fehler: Ungültige Operanden für binäres == (haben "struct vec2d" und "struct vec2d") Ausweg: Benutze eine selbstgeschriebene "Vergleichsfunktion" an Stelle des Vergleichsoperators ==. 43.... 44. // Vergleich (==) zweier 2-komponentiger Vektoren. 45. int vec2d_is_eq(struct vec2d v1, struct vec2d v2) 46. { 47. 48. } 49. return (v1.x == v2.x) && (v1.y == v2.y); 50. // ******************** 51. 52. int main(void) 53. {

54. struct vec2d v1, v2; 55. 56. v1 = vec2d_init(1.0, 2.0); 57. v2 = vec2d_init(3.0, 4.0); 58. 59. if(vec2d_is_eq(v1, v2)) 60. printf("v1 ist gleich v2.\n"); 61. else 62. printf("v1 ist ungleich v2.\n"); 63. } v1 ist ungleich v2. Werden Zeiger auf Strukturen verwendet, kann auch mit -> auf die Komponenten zugegriffen werden. 51.... 52. // Vertauschen zweier 2-komponentiger Vektoren. 53. void vec2d_swap(struct vec2d *pv1, struct vec2d *pv2) 54. { 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. } 65. double tmp; tmp = pv1->x; pv1->x = pv2->x; pv2->x = tmp; tmp = pv1->y; pv1->y = pv2->y; pv2->y = tmp; 66. // ******************** 67. 68. int main(void) 69. { 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. } struct vec2d v1, v2; v1 = vec2d_init(1.0, 2.0); v2 = vec2d_init(3.0, 4.0); vec2d_swap(&v1, &v2); printf("v1 = "); vec2d_print(v1); printf("v2 = "); vec2d_print(v2); // Aequivalent zu "tmp = (*pv1).x;", nicht aber zu "tmp = *pv1.x;". v1 = ( +3.00, +4.00 ) v2 = ( +1.00, +2.00 ) Mit typedef type name; kann dem Datentyp type der neue Datentypname name zugewiesen werden; besonders bei Strukturen bietet sich die Definition eines kürzeren äquivalenten Dateitypnamens an. 1. #include<stdio.h> 2. 3. // ******************** 4. 5. // Definition einer Struktur fuer einen 2-komponentigen Vektor. 6. struct vec2d 7. { 8. 9. 10. }; 11. double x; double y; 12. typedef struct vec2d VEC2D; // VEC2D ist nun aequivalent zu struct vec2d. 13.

14. // ******************** 15. 16. // Initialisieren eines 2-komponentigen Vektors. 17. VEC2D vec2d_init(double x, double y) 18. { 19. VEC2D v; 20. v.x = x; 21. v.y = y; 22. return v; 23. } 24. 25. // ******************** 26. 27. // Ausgabe eines 2-komponentigen Vektors. 28. void vec2d_print(vec2d v) 29. { 30. printf("( %+.2lf, %+.2lf )\n", v.x, v.y); 31. } 32. 33. // ******************** 34. 35. // Addition zweier 2-komponentiger Vektoren. 36. VEC2D vec2d_add(vec2d v1, VEC2D v2) 37. { 38. VEC2D v; 39. v.x = v1.x + v2.x; 40. v.y = v1.y + v2.y; 41. return v; 42. } 43. 44. // ******************** 45. 46. // Vergleich (==) zweier 2-komponentiger Vektoren. 47. int vec2d_is_eq(vec2d v1, VEC2D v2) 48. { 49. return (v1.x == v2.x) && (v1.y == v2.y); 50. } 51. 52. // ******************** 53. 54. // Vertauschen zweier 2-komponentiger Vektoren. 55. void vec2d_swap(vec2d *pv1, VEC2D *pv2) 56. { 57. double tmp; 58. 59. tmp = pv1->x; // Aequivalent zu "tmp = (*pv1).x;", nicht aber zu "tmp = *pv1.x;". 60. pv1->x = pv2->x; 61. pv2->x = tmp; 62. 63. tmp = pv1->y; 64. pv1->y = pv2->y; 65. pv2->y = tmp; 66. } 67. 68. // ******************** 69. 70. int main(void) 71. { 72. VEC2D v1, v2; 73. 74. v1 = vec2d_init(1.0, 2.0); 75. v2 = vec2d_init(3.0, 4.0); 76. 77. vec2d_swap(&v1, &v2); 78. 79. printf("v1 = ");

80. vec2d_print(v1); 81. printf("v2 = "); 82. vec2d_print(v2); 83. }

Anwendung: Einfach verkettete Listen Zur Verwaltung einer zunächst unbekannten Menge von Daten (z.b. Namen, Messergebnisse, etc.) ist ein statisches Array ungeeignet. Auch ein dynamisch angelegtes Array ist nicht ideal, wenn z.b. häufig Daten hinzugefügt werden; dann müsste jedes Mal ein entsprechend vergrößerter Speicherbereich angelegt werden und die existierenden Daten müssten in diesen neuen Speicherbereich kopiert werden (sehr ineffizient). Häufig werden für solche Probleme Listen eingesetzt. Einfach verkettet Liste: Jedes Listenelement entspricht einer Struktur, die die Daten eines Elements (z.b. bei einem Messergebnis den Messwert, das Datum, eine Bemerkung, etc.) enthält, sowie einen Zeiger auf das nächste Listenelement. Der Zeiger des letzten Listenelements besitzt den Wert NULL. Die Liste entspricht einem Zeiger auf deren erstes Element; über den Zeiger des ersten Elements kann dann auf das Zweite zugegriffen werden, über den Zeiger des zweiten Elements kann dann auf das Dritte zugegriffen werden, etc. Eine leere Liste ist ein Zeiger auf ein Listenelement, der den Wert NULL besitzt. Das Einfügen eines neuen bzw. Löschen eines existierenden Listenelements ist sehr effizient; lediglich Speicherplatz für ein Element muss dynamisch angefordert bzw. freigegeben werden. 1. #include<stdio.h> 2. #include<stdlib.h> 3. #include<string.h> 4. 5. // ******************** 6. 7. // Definition einer Struktur fuer ein Listenelement (enthaelt einen Namen). 8. struct l_elem 9. { 10. char name[100]; 11. 12. }; 13. struct l_elem *next; // Zeiger auf das naechste Listenelement. 14. typedef struct l_elem L_ELEM; 15. 16. // ******************** 17. 18. // Haengt ein neues Listenelement am Ende der Liste *p_list an; initialisiert 19. // das neue Listenelement mit name. 20. void l_append(l_elem **p_list, const char name[]) 21. { 22. // Dynamisches Anlegen des neuen Listenelements. 23. 24. L_ELEM *p_new_elem; 25. 26. if((p_new_elem = (L_ELEM *)malloc(sizeof(l_elem))) == NULL) 27. { 28. printf("fehler in void l_append(...\n"); 29. exit(0);

30. } 31. 32. strcpy(p_new_elem->name, name); 33. p_new_elem->next = NULL; 34. 35. // ***** 36. 37. // Anhaengen des neuen Listenelements an die bestehende Liste. 38. 39. if(*p_list == NULL) 40. // Die bestehende Liste ist leer 41. // --> setze die Liste gleich dem neuen Element. 42. { 43. *p_list = p_new_elem; 44. return; 45. } 46. 47. // Die bestehende Liste ist nicht leer 48. // --> suche das Ende der Liste und haenge das neue Element an. 49. 50. L_ELEM *p_tmp = *p_list; 51. 52. while(p_tmp->next!= NULL) 53. p_tmp = p_tmp->next; 54. 55. p_tmp->next = p_new_elem; 56. } 57. 58. // ******************** 59. 60. // Ausgabe der Liste p_list. 61. void l_print(l_elem *p_list) 62. { 63. if(p_list == NULL) 64. return; 65. 66. printf("%s\n", p_list->name); 67. l_print(p_list->next); 68. } 69. 70. // ******************** 71. 72. // Loescht das index-te Element aus der Liste. 73. void l_delete(l_elem **p_list, int index) 74. { 75. int i1; 76. 77. if(index == 0) 78. // Loeschen des 0-ten Listenelements (index == 0). 79. { 80. if(*p_list == NULL) 81. { 82. printf("fehler in void l_delete(...\n"); 83. exit(0); 84. } 85. 86. L_ELEM *p_del = *p_list; // Das zu loeschende Element. 87. *p_list = (*p_list)->next; // Die Liste wird zu einem Zeiger auf das 1-te Listenelement. 88. free(p_del); // Freigeben des Speichers. 89. } 90. else 91. // Loeschen eines Listenelements, das nicht am Anfang der Liste steht (index >= 1). 92. { 93. L_ELEM *p_tmp = *p_list; 94. 95. for(i1 = 0; i1 < index-1; i1++)

96. { 97. if(p_tmp == NULL) 98. { 99. printf("fehler in void l_delete(...\n"); 100. exit(0); 101. } 102. 103. p_tmp = p_tmp->next; 104. } 105. 106. // p_tmp zeigt jetzt auf das Listenelement vor dem zu loeschenden Element. 107. 108. if(p_tmp->next == NULL) 109. { 110. printf("fehler in void l_delete(...\n"); 111. exit(0); 112. } 113. 114. L_ELEM *p_del = p_tmp->next; // Das zu loeschende Element. 115. p_tmp->next = p_tmp->next->next; // Das zu loeschende Element wird "uebersprungen". 116. free(p_del); // Freigeben des Speichers. 117. } 118. } 119. 120. // ******************** 121. 122. int main(void) 123. { 124. 125. L_ELEM *list = NULL; // Legt eine leere Liste an. 126. l_append(&list, "Donald"); 127. l_append(&list, "Dagobert"); 128. l_append(&list, "Tick"); 129. l_append(&list, "Trick"); 130. l_append(&list, "Track"); 131. l_print(list); 132. printf("**********\n"); 133. 134. l_delete(&list, 3); 135. l_print(list); 136. printf("**********\n"); 137. 138. l_delete(&list, 0); 139. l_print(list); 140. printf("**********\n"); 141. 142. l_delete(&list, 2); 143. l_print(list); 144. printf("**********\n"); 145. 146. l_append(&list, "Pluto"); 147. l_append(&list, "Goofy"); 148. l_print(list); 149. printf("**********\n"); 150. 151. l_delete(&list, 4); 152. } Donald Dagobert Tick Trick Track ********** Donald Dagobert Tick Track ********** Dagobert Tick

Track ********** Dagobert Tick ********** Dagobert Tick Pluto Goofy ********** Fehler in void l_delete(... Hausaufgabe: Schreibe weitere Funktionen für einfach verkettete Listen, z.b. Einfügen eines neuen Elements an einer bestimmten Position, Kopieren einer Liste, Umdrehen einer Liste,...