C-Arrays vs. C++-Container

Ähnliche Dokumente
C-Arrays vs. C++-Container

Assoziative Container in C++ Christian Poulter

Template-Klasse Eigenschaften Voraussetzungen Anwendungsgebiete std::vector<t> Reine Sequenz von Ts; Standard* Sortieren Dynamische Größenveränderung

Programmierkurs C++ Templates & STL (1/2)

Programmieren in C/C++ und MATLAB

C-Pointer (Zeiger, Adressen) vs. C++ Referenzen

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

9. Vektoren. (auch Felder/array)

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

19. Dynamische Datenstrukturen II

19. Dynamische Datenstrukturen II

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

Einführung in die STL

19. Dynamische Datenstrukturen II. Verkettete Listen, Vektoren als verkettete Listen

Repetitorium Programmieren I + II

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

C++ Teil 7. Sven Groß. 3. Juni Sven Groß (IGPM, RWTH Aachen) C++ Teil 7 3. Juni / 16

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

Datenkapselung: public / private

Arrays (Felder/Vektoren)

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

Algorithmen und Datenstrukturen

Mapra: C++ Teil 2. Felix Gruber, Sven Groß. 2. Mai 2017 IGPM. Felix Gruber, Sven Groß (IGPM) Mapra: C++ Teil 2 2. Mai / 11

Organisatorisches. Folien (u.a.) auf der Lva-Homepage Skriptum über MU Online

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

Einführung in die STL

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

Organisatorisches. Neue Übungsblätter: Nur mehr elektronisch? Abgabe Di, , 14 Uhr bis Do, , 8Uhr

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

STL-Container und Laufzeit

Polymorphismus 44. Function.hpp. #include <string>

Polymorphismus 179. Function.h. #include <string>

Mehrdimensionale Arrays

Organisatorisches. drei Gruppen Gruppe 1: 10:10-11:40, Gruppe 2: 11:45-13:15 Gruppe 3: 13:20-14:50

Programmierkurs. Steffen Müthing. November 16, Interdisciplinary Center for Scientific Computing, Heidelberg University

Organisatorisches. Folien (u.a.) gibt's auf der Lva-Homepage zum Download

Einstieg in die Informatik mit Java

C++ Kurs Teil 3. Standard Template Library (STL) Kommunikation mit der shell Hyper Text Markup Language (HTML)

Objektorientierte Programmierung mit C++ SS 2007

ÜBUNGS-BLOCK 7 LÖSUNGEN

5. Behälter und Iteratoren. Programmieren in C++ Überblick. 5.1 Einleitung. Programmieren in C++ Überblick: 5. Behälter und Iteratoren

Elementare Datentypen in C++

Wertebereich und Genauigkeit der Zahlendarstellung

Die Klasse string Verfasser: Christian Bartl

Einführung in die Programmiersprache C

Lambda-Funktionen. Lambda-Funktionen. Lambda-Funktionen sollen

Intensivkurs C++ Tag 2: Grundlagen++ Marc Tschentscher Institut für Neuroinformatik

Schleifen in C/C++/Java

Programmieren in C++ Überblick

Hier wird die Verwendung der Standard Template Library (kurz STL) kurz beschrieben. Inhalt 1.Verwendung der STL Grundlagen...

Visuelle Kryptographie. Anwendung von Zufallszahlen

Einführung in die Programmierung mit C++

Computeranwendung und Programmierung (CuP)

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

Programmier-Befehle - Woche 08

Wo und wie lange leben Objekte? globale Objekte lokale Objekte dynamische Objekte

Programmieren 2 C++ Überblick

Programmierung mit C Zeiger

Graphdurchmusterung, Breiten- und Tiefensuche

Felder (Arrays) und Zeiger (Pointers) - Teil I

Die C++ Standard Template Library Andreas Obrist

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

Objektorientierte Programmierung mit C++ Vector und List

6 ZEIGER UND REFERENZEN - ALLGEMEINES

Problem: Was ist, wenn der Stapel voll ist? Idee: Erzeuge dynamisch ein grösseres Array und kopiere um. Dynamische Anpassung der Größe

Kapitel 4: Bäume i. 1. Einleitung. 2. Ein Datenmodell für Listen. 3. Doppelt-verkettete Listen. 4. Bäume. 5. Das Collections-Framework in Java

12. Dynamische Datenstrukturen

C-Pointer (Zeiger, Adressen) vs. C++ Referenzen

Mapra: C++ Teil 4. Felix Gruber, Michael Rom. 24. Mai 2016 IGPM. Felix Gruber, Michael Rom (IGPM) Mapra: C++ Teil 4 24.

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

12. Felder (Arrays) II

Computergrundkenntnisse und Programmieren, WS 07/08, Übung 11: Klassen der Standardbibliothek 2

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

12.3 Ein Datenmodell für Listen

Informatik für Mathematiker und Physiker Woche 7. David Sommer

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

C++ - Einführung in die Programmiersprache Standard Templates. Leibniz Universität IT Services Anja Aue

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

1. Übung zu "Numerik partieller Differentialgleichungen"

Probeklausur Name: (c)

Programmier-Befehle - Woche 09

Einstieg in die Informatik mit Java

Zeiger, Arrays und Strings in C und C++

Teil 5: Felder, Zeiger, Zeigerarithmetik Gliederung

Arrays. Einleitung. Deklarieren einer Array Variablen

Felder (Arrays) und Zeiger (Pointers) - Teil I

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

Praxis der Programmierung

Felder. Gerd Bohlender. Einstieg in die Informatik mit Java, Vorlesung vom

Felder (Arrays) und Zeiger (Pointers) - Teil I

C++ - Objektorientierte Programmierung Konstante und statische Elemente

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

Einführung in die STL 226

Teil 5: Zeiger, Felder, Zeichenketten Gliederung

5.4 Arrays. Oft müssen viele Werte gleichen Typs gespeichert werden. Idee: Lege sie konsekutiv ab! Greife auf einzelne Werte über ihren Index zu!

C# - Einführung in die Programmiersprache Arrays, Enumeration und Collections. Leibniz Universität IT Services Anja Aue

1. Referenzdatentypen: Felder und Strings. Referenz- vs. einfache Datentypen. Rückblick: Einfache Datentypen (1) 4711 r

1. Referenzdatentypen: Felder und Strings

Transkript:

C-Arrays vs. C++-Container In C verwendet man (mangels Alternativen) sehr häufig das C-Array (= Feld): im Speicher hintereinander abgelegte Elemente vom gleichen Typ. Arrays haben einen Basistyp (Typ des einzelnen Elementes), die Anzahl der Elemente (Dimension) muss bei der Definition als Konstante vorgegeben werden: int i, x[20], y[1]; // x enthält 20 Elemente, y nur 1 // ABER: y ist KEIN int, sondern ein int-array char zeile[81]; // Platz für 80 Zeichen + das Nullbyte!!!! const int dim = 13; double x[dim]; // Fehler: keine Konstante als Dimension constexpr int dim = 13; double x[dim]; // ok WICHTIG: Die Array-Elemente beginnen immer mit dem Index 0; der Index wird in eckigen Klammern geschrieben, es ist nur ein Index möglich (also nicht z.b. Zeile/Spalte) : x[0] = 17; x[20] = 0; // setzt allererstes Array-Element // Fehler: dieses Element gibt es nicht mehr for (i = 0; i < 20; ++i) x[i] = i; // x = {0, 1, 2,..., 19} for (i = 0; i <= 20; ++i) x[i] = i; // Fehler: x[20] existiert nicht for (auto i : x) // nur in C++ ab C++11 cout << i << '\n'; // gib alle Werte aus for (auto& i : x) // nur in C++ ab C++11 i = 1; // setze alle Werte auf 1 Arrays können als Ganzes oder teilweise initialisiert werden. int x[20] = {1, 2, 3, 4, 5, 6}; // nur die ersten 6 Werte werden gesetzt, der Rest wird mit 0 aufgefüllt int x[20]{1, 2, 3, 4, 5, 6}; // (ohne =) bedeutet dasselbe (ab C++11)

int y[] = {1, 2, 3, 4}; // y wird dadurch zu einem int[4] int z[10] = {}; // alle 10 Elemente werden mit 0 belegt x = {1, 2, 3}; // FEHLER: Das geht nur bei der Initialisierung Die auch in C++ verwendeten C-String-Literale (Zeichenketten-Konstante) wie "blabla" sind genau solche (konstante) C-Arrays aus char (hier char[7]). Arrays haben natürlich auch Nachteile: Man kann unbemerkt die Arraygrenzen überschreiten, die Dimension ist schon zur Übersetzungszeit festzulegen und kann nachträglich nicht geändert werden usw. Aus diesem Grund besitzen die moderneren Varianten C++ (und auch Java) Ersatzlösungen, die diesen Komfort zusätzlich bieten: Container bzw. genauer Container-Template-Klassen. Es gibt einige vordefinierte Containertypen (Array, Vector, Menge, Liste,...). Die STL = Standard Template Library Diese Bibliothek hat sich seit C++11 als zentraler Bestandteil von C++ etabliert. Mit jeder C++ Evolution wird der Inhalt ausgebaut und optimiert. Sie definiert die sogenannten Container- Templates, die beliebige Datentypen in nahezu beliebigen Speicherformen aufnehmen können, sowie einige wichtige Algorithmen für diese Container. Der Typ der gespeicherten Objekte steht dabei in Spitzklammern, es handelt sich demnach um Templates (genaueres dazu kommt später). Das std::array-template Nach dem Inkludieren der Headerdatei array steht dem C++-Programmierer das Klassentemplate std::array<t, Dim> zur Verfügung, welches ähnlich wie ein C-Array von T mit der Dimension Dim verwendet werden kann. Der Grundtyp T und die konstante Dimension Dim muss in den Spitzklammern angegeben werden std::array<double, 100> x; // erzeugt array mit 100 double-werten std::array <double, 3> x = { 1., 2., 3.}; // erzeugt array mit den 3 Werten 1.0, 2.0, 3.0 std::array <double, 3> x{ 1., 2., 3.}; // dasselbe x[1] = 2.0; // setzt 2. Element auf 2.0 (gleich wie bei C-Array) std::cout << "x hat " << x.size() << " Elemente\n";

Das std::vector-template Nach dem Inkludieren der Headerdatei vector steht dem C++-Programmierer das Klassentemplate std::vector<t> zur Verfügung, welches ähnlich wie ein T-Array verwendet werden kann. Der Grundtyp T muss in Spitzklammern angegeben werden: std::vector<double> x; // erzeugt leeren vector, der wachsen kann std::vector<double> x(100); // erzeugt vector mit 100 Werten 0.0 std::vector<double> x(100, 1.); // erzeugt vector mit 100 Werten 1.0 std::vector<double> x = {1., 2., 3.}; // erzeugt vector mit den 3 Werten 1.0, 2.0, 3.0 std::vector<double> x{1., 2., 3.}; // dasselbe x[1] = 2.0; // setzt 2. Element auf 2.0 (gleich wie bei Array) std::cout << "x hat derzeit " << x.size() << " Elemente\n"; x.push_back(20.); // hänge hinten 20.0 an den vector an, dieser wächst Das std::list-template Nach dem Inkludieren der Headerdatei list steht dem C++-Programmierer das Klassentemplate std::list<t> zur Verfügung, welches die Daten als (doppelt verkettete Liste verwaltet). Der Grundtyp T muss in Spitzklammern angegeben werden. Die Liste gestattet keinen wahlfreien Zugriff mit Indexklammer, kann dafür an jeder Position schnell neue Elemente einfügen und ist daher gut für Datenbank-Anwendungen geeignet. std::list<double> x; // erzeugt leere list, die wachsen kann std::list<double> x{ 1., 2., 3.}; // erzeugt Liste mit diesen 3 Elementen x[1] = 2.0; // Fehler: eine Liste hat keinen Index-Zugriff std::cout << "x hat derzeit " << x.size() << " Elemente\n"; x.push_back(20.); // hänge hinten 20.0 an die Liste an Unterschiede zwischen C-Array und einigen C++-Containern: C-Array: + geht in C/C++/Java gleich

+ ist ein bisschen schneller im Zugriff - Größe muss zur Compilezeit festgelegt werden - kann weder wachsen noch schrumpfen - bei zu großen Arrays besteht die Gefahr eines Programmabsturzes (am Stack) - weiß nicht, wie viele Elemente tatsächlich enthalten sind - Zugriff mit Index [] auch außerhalb der Arraygrenzen möglich - bei Übergabe an Funktionen zerfällt das Array (zu einem Pointer auf den Beginn) std::array: + kann wie ein C-Array verwendet werden (Indexzugriff) + weiß seine fixe Größe (size() Methode) + kann ohne Zeitverlust bei Bedarf in ein C-Array umgewandelt werden + Zugriff innerhalb der Grenzen kann überwacht werden (at() Methode) + bei Übergabe an Funktionen bleibt der Typ erhalten + besitzt noch weitere nützliche Methoden (z.b. size()) - Größe muss zur Compilezeit festgelegt werden - kann weder wachsen noch schrumpfen - bei zu großen arrays besteht die Gefahr eines Programmabsturzes (am Stack) std::vector: + kann beliebig groß werden + kann wie ein C-Array verwendet werden + weiß seine Größe (size() Methode) + kann ohne Zeitverlust bei Bedarf in ein C-Array umgewandelt werden + Zugriff innerhalb der Grenzen kann überwacht werden (at() Methode) + bei Übergabe an Funktionen bleibt der Typ erhalten + keine Gefahr eines Programm-Absturzes (da am Heap) + besitzt noch weitere nützliche Methoden (z.b. size()) + ist sehr schnell (ist daher der meistverwendete Containertyp, der wachsen kann) - beim Wachsen kann sich der Speicherort der Daten ändern std::list: + kann beliebig groß werden + weiß seine Größe (size() Methode) + keine Gefahr eines Programm-Absturzes (am Heap) + kann an jeder Stelle schnell Elemente einfügen oder löschen + bei Übergabe an Funktionen bleibt der Typ erhalten + besitzt noch weitere nützliche Methoden (z.b. size()) - kein Zugriff mit dem Index-Operator möglich

- nur sequenzieller Zugriff möglich, daher langsam std::string: (entspricht einem std::vector<char> mit weiteren nützlichen Methoden) Stack: Ein Speicherbereich mit fester Größe. Ist dieser voll, stürzt das Programm ab. Hier werden z.b. die Funktionsargumente und die lokalen Variablen angelegt. Heap: Ein Speicherbereich, der wachsen kann. Ist dieser voll, besorgt sich C++ vom Betriebssystem Nachschub. Hier werden dynamische Daten (deren Umfang sich ändern kann) angelegt. Die Container-Typen verwenden eine feste Größe an Stack-Speicher (für die Verwaltung der Daten) und speichern die eigentlichen Daten am Heap. Sie bestehen also aus 2 getrennten Datenblöcken. Im Allgemeinen fällt die Entscheidung in C++ fast immer zugunsten eines Containers. Wir verwenden in den Übungen fast ausschließlich std::string, std::array, std::vector, da in der Mathematik sehr häufig (Matrizen, Vektoren) solche Container mit wahlfreiem Indexzugriff benötigt werden. Abseits der Mathematik (z.b. bei Datenbanken) benötigt man statt des Indexzugriffs eher die Möglichkeit, neue Elemente überall einzufügen oder alte Elemente zu löschen, wofür etwa (doppelt) verkettete Listen manchmal besser geeignet sind (std::list). Weitere Speicherstrukturen der STL sind z.b. für Bäume: #include <set> (oder #include <unordered_set>) für Hash-Tabellen: #include <map> Wichtige Methoden der gebräuchlichen Container-Templates Eine vollständige Liste aller Containermethoden findet man im WWW! http://www.cplusplus.com/reference http://en.cppreference.com/ Die folgenden Methoden werden von fast allen Containertypen unterstützt: size() front() back() begin(), end() Anzahl der Elemente des Containers; Ergebnis std::size_t (meist unsigned long) Das erste Elemente des Containers; Ergebnis ist Referenz auf das Element Das letzte Elemente des Containers; Ergebnis ist Referenz auf das Element Iteratoren auf das 1., hinter das letzte Element Ergebnis: iterator

cbegin(), cend() konstante Iteratoren auf das 1., hinter das letzte Element Ergebnis: const_iterator rbegin(), rend() reverse Iteratoren auf das letze, vor das 1. Element Ergebnis: reverse_iterator crbegin(), crend() konstante reverse Iter. auf das letze, vor das 1. Element Ergebnis: const_reverse_iterator empty() ob der Container Elemente enthält Ergebnis: bool push_back(val) fügt val hinten an den Container an (nicht bei array) Ergebnis: void insert(it, val) fügt val an der Iterator-Position it ein (nicht bei array) Ergebnis: void Konstruktoren mit Werten in geschwungen Klammern (nicht bei array, diese können aber ebenfalls mit solchen Listen initialisiert werden. Dabei handelt es sich aber genau genommen um keine Konstruktoren.) std::list<int> v{1, 2, 3, 5}; // kreiert int-list mit Werten 1, 2, 3, 5 for (auto it = v.cbegin(); it!= v.cend(); ++it) cout *it << '\n ' ; // klassische Iteratoren-Schleife // statt range-based for Ich verwende in dieser Lehrveranstaltung die Methodenaufrufe wie v.cbegin(), v.cend(), nicht sondern rufe statt dessen die analogen Funktionen der STL auf: std::cbegin(v), std::cend(v)... Der Grund dafür ist, dass diese Funktionen sowohl für die Containertypen als auch für C-Arrays funktionieren, letztere aber keine Methoden besitzen. for (auto i : {-1, -5, 10}) v.push_back(i); // an v hinten anhängen cout << "erstes Element: " << v.front() << '\n ' ; cout << "letztes Element: " << v.back() << '\n ' ; std::array<t>, std::vector<t> (und std::deque<t>, std::string) haben auch: Indexzugriff mit eckigen Klammern [3] Index-Zugriff mit Überprüfung, ob vorhanden: at(3)