c++ - arrays – abstrakter datentyp · pdf filefb informatik prof. dr. r.nitsch...
Post on 06-Feb-2018
216 Views
Preview:
TRANSCRIPT
FB InformatikProf. Dr. R.Nitsch
C++ -
Arrays –
Abstrakter Datentyp
Reiner Nitsch 8417
r.nitsch@fbi.h-da.de
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 2
Abstrakter Datentyp - Begriff
•
Daten stehen im Mittelpunkt; •
Sie haben eigene Funktionen zur Verfügung, die Methoden
bzw. Operationen
genannt
werden. Zu jeder Operation gehören 2 Bedingungen–
Vorbedingung (precondition): gibt an, welche Eigenschaften das ADT-Objekt vor der Operation haben muss, damit diese ihre Leistung korrekt erbringen kann.
–
Nachbedingung (postcondition): beschreibt den Zustand des ADT-Objekts nach Beendigung der Operation.
•
Nur diese Methoden haben Zugriff auf die Daten (Datenkapselung, Zugriffsschutz).•
Daten und zugehörige Funktionen werden an einer Stelle im Programm zusammen gefasst. Daraus resultiert eine bessere Pflegbarkeit, Wiederverwendbarkeit und einfachere Fehlereingrenzung
•
Die Implementierung der Methoden und die interne Datenstruktur wird vor dem Benutzer verborgen (Geheimnisprinzip).
•
ADTs können durch eine Invariante
gekennzeichnet sein. Die darf durch nichts und niemanden geändert werden.
–
Beispiel: Die Elemente eines ADT "sortiertes Array" sind vor und nach jeder Operation dieses ADT sortiert.
•
ADTs können in objektorientierten Programmen durch Klassen
realisiert werden.
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 3
Abstrakter Datentyp (ADT)
•
ADT-Beispiele bisher: Klassen Counter, Time, Motorboot, Handy, string, …•
Neues Beispiel:
ADT Notenspiegel zur Erfassung und Auswertung der Noten einer
Prüfung
Fach: ProgrammierenNote Anzahl1 42 5…5 3Durchschnittsnote: 2.3Durchfallquote: 17%
ExamResult
Attribute (?)KonstruktorDestruktorshow():voidmean():floatrecord(mark:int):voidfailRatio():float
getMarkCount(mark:int):intsetMarkCount(mark:int,
count:int):void
Attribute - unbekannt,d.h. abstrakt.
Geheimnisprinzip: Zugriff von aussen nur lesend
über Akzessor-Methoden)Abstrakte Methoden - weil sie unabhängig von der konkreten
Attributstruktur sind
Akzessormethoden nicht abstrakt weil abhängig von konkreter
Attributstruktur.
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 4
Abstrakter Datentyp -
Akzessormethoden
•
sollen Schutzfunktionen bieten für die sonst ungeschützte Datenstruktur•
bieten gezielten Zugriff auf eine Klasse–
lesend (get...)• private: oder
public : <Typ>getAttribut1() const
<Typ>get(<Attributidentifikator>) const
–
schreibend (set...)• private: void set(<Attributidentifikator>,<Attributwert>)
//Deklarationclass ExamResult {private:
int count1, count2, count3,count4, count5;
public:ExamResult();
~ ExamResult();void show();float mean();void record(int);int getMarkCount(int mark);
private:void setMarkCount(int mark ,int count);
};
const;const;
Aufgabe: Suchen Sie die read-only Methoden und deklarieren Sie diese als solche!
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 5
Abstrakter Datentyp - Notenspiegel
// Anwendungvoid main() {
ExamResult math;math.record(2);math.record(5);math.record(3);math.record(2);…math.show();cout << math.mean();cout << math.getMarkCount(1);
}
Erhöht count2 um 1
Kein Bezug zur Attributstruktur!
//DefinitionExamResult:: ExamResult() {
for( int mark = 1; mark <= 5; mark++)setMarkCount(mark,0);
}ExamResult::~ExamResult() { }
void ExamResult::setMarkCount( int mark, int count ) { //Akzessor switch(mark) { case 1: count1 = count; case 2: count2 = count; case 3: count3 = count; case 4: count4 = count; case 5: count5 = count; default: cout << "Fehler"; }
}
Was fehlt noch?
break;break;break;break;break;
break; // optional
Was fehlt hier?
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 6
float ExamResult::mean() { //abstraktint weightedSum(0), count(0);for ( int mark =1; mark <=5 ; mark++ ) {weightedSum += getMarkCount(mark)* mark; count += getMarkCount(mark);
}return weightedSum / count;
}
Abstrakter Datentyp - Notenspiegel
void ExamResult::record( int mark ) { //abstraktsetMarkCount ( mark, getMarkCount(mark) + 1);
}
void ExamResult::show() { //abstraktfor ( int mark=1 ; mark<=5 ; mark++ )cout << mark << setw(4) << getMarkCount(mark) << endl;
}
Vorbedingung?
int ExamResult::getMarkCount(int mark){ switch(mark) { case 1: return count1; case 2: return count2; case 3: return count3; case 4: return count4; case 5: return count5; default: cout << "Fehler"; }
}
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 7
Datenstruktur Reihe / Array / Feld
•
ist eine Zusammenfassung von Objekten desselben Typs
•
Maximale Objektanzahl liegt zur Compile-Zeit fest und ist zur Laufzeit nicht veränderbar
•
Gab es schon in C ( -> C-Arrays; primitiv). In C++ gibt es etwas besseres:
Definition
von C-Arrays: <Datentyp><Arrayname>[<AnzahlElemente>];
Beispiel int intArray[5];oder
besserconst int MAX_I = 5;int intArray[MAX_I];
muß ein Ausdruck mit konstantem Ergebnis sein
const int MAX_M=5;class ExamResult {int markList[5];oder
besserint markList[MAX_M];…
};
//globale Konstante
•
Deklaration von C-Arrays in Klassena)
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 8
Datenstruktur Reihe / Array / Feld
b) class ExamResult {public:enum { MAX_M=5 };…
private:int markList[MAX_M];…
};
Aufzählungstyp definiert symbolische Konstante 'MAX_M' mit Gültigkeitsbereich 'ExamResult' (Andere Möglichkeit gibt es nicht!)
Zugriff auf Konstante
'MAX_M' im Namensbereich 'ExamResult' von aussen
void main() {ExamResult math;if (ExamResult::MAX_M …)…
}
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 9
Datenstruktur Array
•
Zugriff auf Array-Objekte mit Index-Operator [] und Hardwarehintergrund
•
bietet keinerlei Schutzfunktionen (z.B. Kapselung, Indexüberwachung)
?
[0][1][2][3][4]
[-1]
[5]
•
Schutzfunktionen müssen die Zugriffsfunktionen übernehmen. Dazu wird die benannte Konstante 'MAX_M'
benötigt:
markList[-1] = 3;cin >> i; //Eingabe 4markList[i+1] = 5;
if ( i>=0 && i<MAX_M ) markList[i] = 6;
Speicher
Adressen100104108112116120124
int markList[MAX_M]; markList[0] = 4;markList[2] = markList[0];markList[markList[0]-1] = 15;
cin >> markList[1]; //Eingabe 8
3
5
=3
4
415
8
• Index muss vom Ganzzahltyp sein; gültiger Indexbereich 0 … MAX_M - 1 wird vom Compiler nicht überwacht!
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 10
Datenstruktur Array
•
Initialisierung von Arrays
a) außerhalb von Klassen
const int MAX_I = 5;int intArray1[MAX_I] = { 2,4,7,3,1 };int intArray2[] = { 1,3,8,4,2 };int intArray3[MAX_I] = { 10,5 };
Es wird ein passendes Array erzeugtNachteil: Benannte Konstante MAX_I fehlt!
Rest wird mit 0 initialisiert
b) innerhalb von Klassen
•
Zuweisung im KonstruktorExamResult:: ExamResult() { //Konstruktor
for ( int mark=0 ; mark<MAX_M ; mark++ )markList[mark] = 0;
}
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 11
Datenstruktur Array
•
Zuweisung bei ArraysintArray1 = intArray2;
–
Abhilfe: Elementweises
kopierenfor( int i=0 ; i<MAX_I ; i++ ) intArray1[i] = intArray2[i];
•
Bestimmung der Array-Größe in Bytesconst int MAX_I = 5;int fieldCount, sizeArray, sizeDouble;double priceRoster[MAX_I];cout << (sizeArray = sizeof(priceRoster));cout << (sizeDouble = sizeof(double));cout << (fieldCount = sizeArray/sizeDouble);
Ausgabe4085
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 12
class ExamResult {private:int count1, count2, count3, count4, count5;
public: …};
Datenstruktur Reihe in ADT Notenspiegel einführen
•
Modifikation der Attribute
int ExamResult::getMarkCount(int mark) { // Akzessor switch(mark) { case 1: return count1; case 2: return count2; case 3: return count3; case 4: return count4; case 5: return count5; default: cout << "Fehler"; }
}
•
Modifikation der Zugriffsfunktionen
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 13
Datenstruktur Reihe in ADT Notenspiegel einführen
•
Modifikation der abstrakten Methoden–
nicht nötig weil abstrakt
•
Vorteil des ADTs mit abstrakten Methoden–
bei Änderung der internen Datenstruktur müssen nur die Zugriffsfunktionen angepasst werden.
void ExamResult::setMarkCount(int mark, int count ) { switch(mark) { case 1: count1 = count; break; case 2: count2 = count; break;case 3: count3 = count; break; case 4: count4 = count; break;case 5: count5 = count; break;
default: cout << "Fehler"; }
}
•
Modifikation der Zugriffsfunktionen
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 14
Noch ein Anwendungsbeispiel zu Arrays
•
Die Qualität des Mensaessens wird evaluiert. Dazu werden 40 Studis befragt,
die Noten zwischen 1 (furchtbar) und 10 (hervorragend) abgeben können. Das Umfrageergebnis ist in einem Array zu speichern und auszuwerten.
#include <iostream>#include <iomanip>using namespace std;
void main () {const int SAMPLE_SIZE=40, MAX_M=11;int survey[SAMPLE_SIZE] = {1, 2, 6, 4, 8, 5, 9, 7, 8, 10, 1, 6, 3, 8, 6, 10, 3, 8, 2, 7, 6, 5,7, 6, 8, 6, 7, 5, 6, 6, 5, 6, 4, 8, 6, 8, 9, 6, 7, 4};int frequency[MAX_M] = { 0 };
for( int stud=0 ; stud<SAMPLE_SIZE ; ++stud )++frequency[survey[stud]];
cout << setw(8) << "Note" << setw(15) << "Haeufigkeit\n";for( int mark=1; mark<=MAX_M-1 ; ++mark )
cout << setw(8) << mark << setw(15) << frequency[mark] << endl;return;
}
Note Haeufigkeit1 22 23 24 35 46 117 58 79 2
10 2
Ausgabe:
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 15
Mehrdimensionale Array
int matrix[5][10];
int m[2][3] = {{1,2,3},{4,5,6}};
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
erstgenannte Dimensionentspricht äußerster Klammer
2-dimensionales Feldoder1-dimensionales Feld mit 5 1-dimensionalen Feldern als Objekten
enum Day {MO,TU,WE,TH,FR,SA,SU}enum Subject {PG1, PG1L, CN1, …}Subject timetable[ ][ ];timetable[ ][ ] = PG1;timetable[ ][ ] = CN1;//Stundenplan zeilenweise druckenfor( int block=0; block < 5; block++ ){for( Day d=MO; d<=SU; d++)
cout << timetable[block][d];cout << endl;
}
StundenplanMo Di Mi Do Fr Sa So
1 CN12 CN13 PG1 PG14 PG1L5 PG1L
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 16
Array als Funktions-
bzw. Methodenparameter
#include <iostream>#include <ctime>#include <cstdlib>using namespace std;
void main(){
const int MAX_N = 1000;int randomNumber[Anzahl];for (int i=0; i< MAX_N; i++){randomNumber[i] = rand();// oderint max = 5;randomNumber[i] = rand() % max;// oderint min = -4;randomNumber[i] = rand() % (max-min)+min;
}cout << mean(randomNumber, MAX_N) << endl;
}
//für rand(); srand()
double mean ( int array[], int max );
srand(time(0));
// Bereich [0...max)
// Bereich [min...max)
time(0) liefert Sekunden seit 1.1.1970
srand() initialisiert Zufallszahlengenerator; sonst erzeugt rand() nach jedem Programmstart die gleiche Zufallsfolge
liefert gleichwahrscheinliche unsigned int Zufallszahlen im Zahlbereich [0…RAND_MAX]
Ein Array wird als Parameter an eine Funktion übergeben durch Angabe des Namens ohne []
Die Arraygröße wird i.A. auch übergeben. Die Funktion kann diese nicht selbst bestimmen.
stdlib.h: RAND_MAX 0x7fff (32767)
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 17
Arrays als Funktions-
bzw. Methodenparameter
double mean( int array[], int MAX_N){
löng sum(0);for( int n=0; i<MAX_N ; n++)sum += array[n];
return sum/MAX_N;}
Merke: • Für Arrays gibt es kein "call by value" bzw. "return by value".
Arrays können nicht Ergebnistyp einer Funktion/Methode sein
Problem: Wie schützt man Array-Elemente vor unbeabsichtigter Modifikation durch eine Funktion?
• Übergabe als "read-only"-Parameter mit const ("Principle of least privilege")
hier wird immer mit Orginal gearbeitet!
Hier wird nur Adresse des 1. Elements übergeben (Simulierter call-by-reference)
const const
Die []-Klammer sagt dem Compiler, dass hier ein Array und keine Variable vom Typ int übergeben wird
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 18
Zeichenketten (C-Strings)
•
sind ein Erbe von C•
sind 1-dimensionale char-Arrays mit '\0' als Endemarke
#include <iostream>using namespace std;void main() {char Gruss1[8];char Gruss2[]="Hallo";Gruss2[4]='i';char Gruss3[8]="Hallo";char Gruss4[8]={'H','a','l','l','o','\0'};char Strasse[12],Name[8];cin >> Name; //Eingabe: "Schmachter"cin >> Strasse; // Eingabe: "Fetzenstrasse"cout << Name;
//besser
cin.getline(Name,12);
Gruss3 = "Tschau"; }
liest max. 11 Zeichen ein und hängt Endemarke '\0' an. Stehen danach noch weitere Zeichen im Eingabepuffer, wird das ios::failbit gesetzt.
Achtung: Weder Compiler noch cin überwachen hier die Indexgrenzen! Deshalb Gefahr von Pufferüberlauf
? ? ? ? ? ? ? ?0 7
nicht initialisiert
'H' 'a' 'l''l' 'o' '\0' Länge automatisch
'H' 'a' 'l''l' 'o' '\0' ? ? nur teilweise belegt
nehmen max. 11 bzw. 7 Zeichen und '\0' auf
Ausgabe:
cout überwacht keine Indexgrenzen. Ausgabe endet bei '\0'-Zeichen!
Variablen können auch L-Werte sein.
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 19
Übungsaufgaben
1.
Finden und korrigieren Sie die Fehler in folgenden Programmsegmenten– int b[10] = {0}
for ( int i = 0; i <= 10; i++) b[i] = 1;– int a[2][2] = {{1,2},{3,4}};
a[1,1] = 5;– char str[5];
cin >> str; //user-Eingabe: hallo
2.
Schreiben Sie eine Anwendung zur Berechnung des Skalarprodukts der Vektoren a=(2,1,3) und b=(2,4,1). Die Berechnung übernimmt die Funktion inner_product, die zwei Vektoren beliebiger Dimension als Parameter erhält und das Ergebnis zurück liefert.
3.
Schreiben Sie eine Funktion strcat, die 2 Strings als Parameter übergeben bekommt und den 2. String an den ersten String anhängt. Schreiben Sie eine Anwendung, die 2 Strings von der Konsole einliest, diese Funktion verwendet und die das Ergebnis ausgibt.
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 20
Lösung Aufgabe 2: Berechnung des Skalarprodukts zweier Vektoren
#include <iostream>using namespace std;
int inner_product( const int[], const int[], int ); //Prototyp
void main (){const int DIM = 10;int a[DIM] = {2,1,3}, b[DIM] = {2,4,1};cout << inner_product( a, b, DIM) << endl;
}
long inner_product( const int a[], const int b[], int dim ){int dotProduct = 0;for( int i=0; i< DIM; i++ )dotProduct += a[i]*b[i];
return dotProduct;}
Lösung im Skript!
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 21
Lösung Aufgabe 3: Verbinden (Concatenation) zweier Strings
#include <iostream>using namespace std;namespace myNamespace {void strcat( char ziel[], const char quelle[] ){int i = 0;while( ziel[i++] );--i;
int j = 0;while( ziel[i++] = quelle[j++] );
}}
void main() {const int SIZE = 50;char str1[SIZE] = "Harry ", str2[SIZE] = "Potter";myNamespace::strcat(str1,str2);cout << str1 << endl;
}
'\0' im Zielstring suchen; danach zeigt i hinter dieses Zeichen
Funktion strcat gibt's im Namensraum std schon!
// Erste Einfügestelle in ziel suchen
// quelle ab Einfügestelle in ziel einfügen
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 26
string -
Appetithäppchen aus der C++ Küche
string vorname("Angela"), nachname("Merkel"), name;cout << vorname.length() << endl; cout << vorname.find('e') << endl; cout << vorname.find_last_of('l') << endl; cout << vorname.find("ge") << endl;name = vorname + ' ' + nachname;cout << name << endl;cout << vorname.compare("Angelika") << endl;
if( vorname<"Angelika" ) /*…*/;
vorname = string("Willi");cout << vorname << endl; string str, str1 = "Writing ", str2 = "print 10 and then 5 more";str.append(str1); cout << str << endl; str.append(str2,6,3); cout << str << endl; str.append("dots are cool",5); cout << str << endl; str.append("here: "); cout << str << endl;str.append(10,'.'); cout << str << endl;
// Ausgabe 6// Ausgabe 3// Ausgabe 4// Ausgabe 2
// Ausgabe Angela Merkel
// Ausgabe Willi
s1.compare(s2) liefert 0 als Rückgabewert, wenn die Zeichenketten gleich sind, einen negativen Wert, wenn s1 lexikografisch vor s2 steht und einen positiven Wert wenn umgekehrt.
Außerdem können Strings mit den üblichen Vergleichs- operatoren == != < > >= und <= verglichen werden
// Autom. Längenanpassung bei name!
WritingWriting 10Writing 10 dotsWriting 10 dots here:Writing 10 dots here: ..........
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 27
STL-Funktionen unterstützen auch C-Arrays
#include <iostream>#include <algorithm>#include <numeric>using namespace std;
const int SIZE = 10;
void show( int a[] ) {for ( int i=0; i<SIZE; i++ ) cout << a[i] << ' ';cout << endl;}
void main () {int a1[SIZE] = { 1,2,3,4,5,6,7,8,9,10 };int a2[SIZE], a3[SIZE];
std::fill( &a2[0], &a2[SIZE], 1 ); cout << "a2: "; show(a2);
// für accumulate
// Ersetzt jedes Element im Bereich durch eine Kopie des // übergebenen Objekts (<algorithm>)
a2: 1 1 1 1 1 1 1 1 1 1Ausgabe:
1 1 1 1 1 1 1 1 1 1
A2 A6 AA AE B2 B6 BA BE C2 C6 CA Adressen im Speicher
a2[0
]
a2[1
0]
a2[1
]
a2[2
]
// '&' Adress-Operator (Achtung: Nicht verwechseln mit "call by reference"! )
In der STL sind Element-Bereiche immer als ein rechtsseitig offenes Intervall definiert: [1. Element, … , 1.Element nach dem Ende)
"Element one past the end"
// Füll-Objekt
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 28
STL-Funktionen unterstützen auch C-Arrays
std::copy( &a1[0], &a1[SIZE], &a3[0] );cout << "a1: "; show(a1);cout << "a3: "; show(a3);
std::swap_ranges( &a1[0], &a1[SIZE], &a2[0] ); cout << "a1: "; show(a1);cout << "a2: "; show(a2);
cout << std::accumulate( &a1[0], &a1[SIZE], 0 ) << endl;
// Tauscht Elemente 2er Bereiche aus (<algorithm>)
a1: 1 2 3 4 5 6 7 8 9 10a3: 1 2 3 4 5 6 7 8 9 10a1: 1 1 1 1 1 1 1 1 1 1a2: 1 2 3 4 5 6 7 8 9 1055
Ausgabe:
"Ziel"-Bereich
1 2 3 4 5 6 7 8 9 10
a1[0
]
a1[1
0]
a1[1
]
a1[2
]
1 2 3 4 5 6 7 8 9 10
"Quell"-Bereich
1. Element des "Ziel"-Bereichs
a3[0
]
// Kopiert Elemente von einem Bereich in einen anderen (<algorithm>)
// 1. El. des 2. Tausch-Bereiches
// Anfangswert
// Addiert alle Elemente eines Bereichs // zum Anfangswert (<algorithm>)
ZielQuelle
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 29
STL-Funktionen unterstützen auch C-Arrays
std::partial_sum( &a2[0], &a2[SIZE], &a3[0] );cout << "a3: "; show(a3);
std::reverse( &a3[0], &a3[SIZE] ); cout << "a3: "; show(a3);
std::random_shuffle( &a3[0], &a3[SIZE] ); cout << "a3: "; show(a3);
}
// Invertiert die Reihenfolge der Elemente im Bereich
// Ordnet Elemente des Bereichs zufällig um.
a3: 55 45 36 28 21 15 10 6 3 1 a3: 1 3 6 10 15 21 28 36 45 55vorher: nachher:
// Berechnet die Partialsummen der Arrayelemente// und legt sie im Bereich beginnend bei a3[0] ab.
a3: 21 15 36 3 28 55 6 10 45 1 nachher:
a3: 1 3 6 10 15 21 28 36 45 55
1=1+2=
1+2+3=usw.
a2: 1 2 3 4 5 6 7 8 9 10
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 30
C++ STL hat was besseres als C-Arrays: Klasse vector
Klasse vector•
ist ein vordefinierter abstrakter Datentyp (#include <vector>)
für komfortable
1-dimensionale Arrays•
gehört zu den Containerklassen. Container enthalten und verwalten (einfügen, hervorholen, suchen, sortieren, löschen) eine Menge von Objekten.
•
ist ein physikalisch sequentieller Container, d.h. die Datenelemente sind in einem zusammenhängenden Speicherbereich abgelegt (wie bei C-Arrays)
•
ist ein homogener Datentyp, dh. alle seine Elemente sind vom gleichen Typ•
ist eine dynamische Datenstruktur, d.h. Objekte können zur Laufzeit ihre Größe ändern
•
ist für wahlfreien Zugriff (random access) optimiert; Zugriff auf Elemente mit []- Operator
•
wird benutzt, wenn Daten schnell sortiert, gelesen und geschrieben werden müssen.
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 31
Schnittstelle der Klasse std::vector
•
Declarations– vector <type> v;
• Erzeugt leeren vector v• type: int, float, Account etc.
– vector <type> v(n);•
Erzeugt vector aus n Elementen des default-Werts des Typs type
– vector<type> v(&a[0], &a[SIZE]) •
Erzeugt vector v und initialisiert die Elemente mit den Werten aus dem angegebenen Bereich
• vector Memberfunctions– v.size()
•
Aktuelle Anzahl gespeicherter Elemente– v.clear()
•
Löscht alle Containerelemente– v.push_back(value)
•
Element am Containerende einfügen (in allen Sequenz-Containern definiert).
– v.front(), v.back()•
Gibt Referenz (return by reference!) auf 1. bzw. letztes Element im Container zurück.
– v[elementNumber] = value;•
weist dem Element den Wert value zu.•
Laufzeitfehler bei unzul. Index– v.at(elementNumber) = value;
•
Wie oben, jedoch out_of_bounds Ausnahme (exception) bei unzul. Index
– v.reserve(n);•
reserviert Speicher für max. n Elemente– v.capacity()
•
gibt an, wieviele Elemente max. gespeichert werden können ohne dass der Container wachsen (reallocieren) muss
•
Reallocation verdoppelt den reservierten Speicherplatz
–
und noch viel mehr …
(siehe: http://msdn.microsoft.com/de-
de/library/9xd04bzs.aspx
)
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 32
Beispiel 1 zur Standard Library Class vector
#include <iostream>#include <vector> using std::cout;using std::cin;using std::endl;void main() {
std::vector< int > intVector;cout << "Anzahl gespeicherter Elemente zu Beginn: "
<< intVector.size()<< "\nAnzahl reservierter Speicherplaetze: " << intVector.capacity();
// Funktion push_back kennt jede Sequenz-ContainerklasseintVector.push_back( 2 );intVector.push_back( 3 );intVector.push_back( 4 );cout << "\nAnzahl gespeicherter Elemente : " << intVector.size()
<< "\nAnzahl reservierter Speicherplaetze "<< intVector.capacity() << endl;
for ( int i=0 ; i<intVector.size() ; i++ )cout << intVector[i] << ' ';
Objekt vector mit int- Elementen erzeugen.
Memberfunktionsaufruf
push_back hängt Elemente am Ende von vector an. Das Objekt verdoppelt die Anzahl reservierter Speicherplätze bei Bedarf (dynamisch)
Anzahl gespeicherter Elemente zu Beginn: 0Anzahl reservierter Speicherplaetze : 0Anzahl gespeicherter Elemente: 3Anzahl reservierter Speicherplätze: 42 3 4
Ausgabe:
Index-Operator []; Anwendung wie bei C-Arrays
gibt 3 zurück
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 33
Beispiel 1 zur Standard Library vector Class
cout << "\nErstes Element von integers: "<< intVector.front() << "\nLetztes Element von integers: " << intVector.back();
// leert integers; clear ruft erase auf.intVector.clear(); cout << "\nNach clear ist Vektor intVector "
<< ( intVector.empty() ? "leer" : "nicht leer" ) << endl
<< "size=" << intVector.size()<< "capacity=" << intVector.capacity() << endl;
const int SIZE = 6; int array[ SIZE ] = { 1, 2, 3, 4, 5, 6 };vector <int> v( &array[0], &array[SIZE] );for ( i=0 ; i<v.size() ; i++ )cout << v[i] << ' ';
cout << v[6];cout << v.at(5);cout << v.at(6);v.at(6) = 7;
vector<Time> timeVector(3);for( int i=0; i<timeVector.size(); ++i )timeVector[i].print24hFormat();
}
Erstes Element von intVector: 2Letztes Element von intVector: 4Nach clear ist Vektor intVector leersize=0 capacity=41 2 3 4 5 6
Ausgabe:
Erzeugt vector v aus integer- Elementen, die mit Werten aus Array a im Indexbereich [0,SIZE) initialsiert sind.
gibt true zurück, wenn intVector leer ist.
// Index ok// Laufzeitfehler: Index nicht im zul. Bereich! -> Exception wird ausgeworfen.
// Laufzeitfehler: Unzulässiger Index
// Erzeugt Vector aus 3 Time-Objekten mit default-Wert (Standardkonstr.)
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 34
Bsp. 2: STL-Funktionen unterstützen auch vector-Objekte
#define _SECURE_SCL 0#define _HAS_ITERATOR_DEBUGGING 0
#include <iostream>#include <algorithm>#include <numeric> // for accumulate#include <vector>using namespace std;const int SIZE = 10;
void show( const vector<int>& v ) {for ( int i=0; i<v.size(); ++i ) cout << v[i] << ' ';cout << endl;
}
void main () {const int SIZE = 6; int array[ SIZE ] = { 1, 2, 3, 4, 5, 6 };vector <int> v1( &a1[0], &a1[SIZE] );
vector <int> v2(SIZE,0), v3(SIZE,0);
std::fill( &v2[0], &v2[SIZE], 1 ); std::fill( v2.begin(), v2.end(), 1 );cout << "v2: "; show(v2);
// Erzeugt vector v1 mit Elementen des Arrays a bis zu (aber nicht // einschließlich) a[SIZE] : v1 = { 1,2,3,4,5,6 }
// Erzeugt vectors mit SIZE Elementen vom Wert 0: v2 = v3 = { 0,0,0,0,0,0 }
// Anwendung von fill analog zur Anwendung mit Arrays: v2 = { 1,1,1,1,1,1 }
v2: 1 1 1 1 1 1Ausgabe:
Nur für dieses Beispielprogramm verwenden: Preprozessor- Konstanten, die den Übersetzungsvorgang steuern (sonst Laufzeitfehler wegen Bereichsüberschreitung)
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 35
STL-Funktionen unterstützen auch vector-Objekte
std::copy( &v1[0], &v1[SIZE], &v3[0] );cout << "v3: "; show(v3);
std::copy( v1.begin(), v1.end(), v3.begin() );
std::swap_ranges( v1.begin(), v1.end(), v2.begin() ); cout << "v1: "; show(v1);
cout << std::accumulate( v1.begin(), v1.end(), 0 ) << endl;
std:: partial_sum( v2.begin(), v2.end(), v3.begin() );cout << "v3: "; show(v3);
std::reverse( v3.begin(), v3.end() ); cout << "v3: "; show(v3);
std::random_shuffle( v3.begin(), v3.end() ); cout << "v3: "; show(v3);
}
v1: 1 2 3 4 5 6v2: 1 1 1 1 1 1
v1: 1 1 1 1 1 1v2: 1 2 3 4 5 6
vorher: nachher:
Ausgabe: 21 weil 0+(1+2+3+4+5+6)=21
v3: 1 3 6 10 15 21
1=1+2=
1+2+3=usw.
v3: 21 15 10 6 3 1 v3: 1 3 6 10 15 21vorher: nachher:
v3: 21 15 10 6 3 1 v3: 21 10 6 3 1 15
// random_shuffle mischt die Elemente
// copy kopiert einen Elementbereich:
// vector-Objekte sind gut vorbereitet: begin() und end() sind Akzessoren, // welche die Referenzen auf das 1. bzw. one-past-the-end Element zurückliefern.
// gleiche Wirkung wie vorherige Anweisung
Ausgabe: 1 2 3 4 5 6
FB InformatikProf. Dr. R.Nitsch
19.05.2009 C++ Array - ADT 39
So, das war´s erst mal!
top related