Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych. Autor artykułu: mgr Jerzy Wałaszek, wersja1.0 |
©2010 mgr
Jerzy Wałaszek |
Język C++ wyposażono w specjalną bibliotekę STL (ang. Standard Template Library - biblioteka standardowych szablonów), która ułatwia programowanie z dynamicznymi strukturami danych. Z biblioteką STL spotykamy się już na samym początku pracy w C++ - strumienie cin i cout są obiektami tej biblioteki i udostępniają wygodny sposób komunikacji z konsolą znakową. Biblioteka STL definiuje tzw. klasy kontenerów, czyli obiektów, które mogą przechowywać dane dowolnego typu. Dzisiaj zapoznamy się z klasą szablonową vector oraz z jej funkcjami składowymi.
W programowaniu często wykorzystujemy tablice dynamiczne do przechowywania danych, których ilości nie jesteśmy w stanie dokładnie przewidzieć w trakcie pisania programu. Tablice dynamiczne tworzyliśmy przy pomocy wskaźników oraz operatora new. Jednakże tak utworzona tablica posiadała bardzo ograniczone możliwości - wszelkie operacje na danych programista musiał definiować sam. W bibliotece STL jest klasa szablonowa vector, która pełni funkcję tablic dynamicznych. Aby w swoim programie uzyskać dostęp do tej klasy, musimy dołączyć plik nagłówkowy vector oraz określić przestrzeń nazw std:
... #include <vector> ... using namespace std;
Tablicę dynamiczną z wykorzystaniem klasy vector możemy utworzyć na kilka różnych sposobów (podsumowanie jest na końcu rozdziału). Najprostszym sposobem jest utworzenie pustej tablicy:
vector<typ_elementów> nazwa_tablicy;
Taka tablica będzie przechowywała dane o określonym typie elementów. Na początku tablica nie zawiera żadnego elementu. Możemy się o tym przekonać wywołując jej funkcję składową size(), która zwraca aktualnie przechowywaną przez tablicę liczbę elementów.
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Tworzenie pustej tablicy //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { vector<int> T; // tworzymy pustą tablicę cout << T.size() << endl; return 0; } |
0 |
Wynikiem działania programu jest 0, tyle bowiem elementów przechowuje nasza tablica T.
Spytasz, po co komu pusta tablica? Teraz jest pusta, ale zaraz coś do niej wstawimy. Klasa vector posiada wiele funkcji składowych, które obsługują dane umieszczone w tablicy. Funkcja składowa push_back(v) dopisuje wartość v do końca danych, które przechowuje tablica. Poniższy program wprowadza do tablicy pięć liczb - wielokrotności 3:
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Dopisywanie na koniec tablicy //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { vector<int> T; // tworzymy pustą tablicę unsigned i; for(i = 1; i <= 5; i++) T.push_back(3 * i); cout << T.size() << endl; return 0; } |
5 |
Teraz wynikiem działania programu jest liczba 5, ponieważ nasza tablica T przechowuje 5 wprowadzonych do niej liczb. Dostęp do danych może być uzyskany na kilka różnych sposobów:
T[indeks] - za pomocą indeksów, indeks musi być w zakresie od 0 do T.size() - 1
T.at(indeks) - za pomocą funkcji składowej at(). W tym przypadku sprawdzany jest zakres indeksów i, jeśli jest on niewłaściwy, funkcja generuje wyjatek.
T.front() - pierwszy element udostępnia funkcja składowa front().
T.back() - ostatni element udostępnia funkcja składowa back().
Poniższy program demonstruje zastosowanie tych funkcji:
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Dostęp do danych //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { vector<int> T; // tworzymy pustą tablicę unsigned i; // wpisujemy 3 6 9 12 15 for(i = 1; i <= 5; i++) T.push_back(3 * i); // wyświetlamy zawartość tablicy za pomocą indeksów: for(i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; // wyświetlamy zawartość tablicy za pomocą funkcji at() for(i = 0; i < T.size(); i++) cout << "T.at(" << i << ") = " << T.at(i) << endl; cout << endl; // zmieniamy zawartość drugiego elementu za pomocą indeksu T[1] = 21; // zmieniamy zawartość trzeciego elementu za pomocą funkcji at() T.at(2) = 32; // zmieniamy zawartość pierwszego i ostatniego elementu T.front() = 123; T.back() = 456; // wyświetlamy pierwszy i ostatni element tablicy cout << "T.front() = " << T.front() << endl << "T.back() = " << T.back() << endl << endl; // jeszcze raz wyświetlamy zmienioną tablicę for(i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; return 0; } |
T[0] = 3 T[1] = 6 T[2] = 9 T[3] = 12 T[4] = 15 T.at(0) = 3 T.at(1) = 6 T.at(2) = 9 T.at(3) = 12 T.at(4) = 15 T.front() = 123 T.back() = 456 T[0] = 123 T[1] = 21 T[2] = 32 T[3] = 12 T[4] = 456 |
Zwróć uwagę, iż funkcje składowe at(), front() i back() zwracają odwołanie do elementu tablicy, zatem w programie zachowują się jak sam element - można np. użyć ich po lewej stronie operatora przypisania:
T.at(2) = 32; T.front() = 123; T.back() = 456;
Zamiast pustej tablicy możemy utworzyć tablicę zawierającą określoną liczbę elementów o zadanej wartości. W tym celu stosujemy zapis:
vector<typ_elementów> nazwa(liczba_elementów, wartość_elementów);
Poniższy program tworzy tablicę 10 elementową typu double i do każdego elementu wstawia liczbę pi = 3.1415926535
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Tablica o określonej zawartości //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <iomanip> #include <vector> using namespace std; int main() { // tworzymy tablicę 10 elementową // elementy są typu double // każdy element początkowo zawiera 3.1415926535 vector<double> X(10, 3.1415926535); unsigned i; cout << setprecision(10) << fixed; // pierwszy element podwajamy X.front() *= 2; // ostatni element potrajamy X.back() *= 3; for(i = 0; i < X.size(); i++) cout << "X[" << i << "] = " << X[i] << endl; return 0; } |
X[0] = 6.2831853070 X[1] = 3.1415926535 X[2] = 3.1415926535 X[3] = 3.1415926535 X[4] = 3.1415926535 X[5] = 3.1415926535 X[6] = 3.1415926535 X[7] = 3.1415926535 X[8] = 3.1415926535 X[9] = 9.4247779605 |
Jak to możliwe. Pamiętasz z poprzednich zajęć, gdy mówiliśmy, że klasa może posiadać kilka różnych konstruktorów? Konstruktory te muszą jedynie różnić się parametrami. Tak więć:
vector<typ> T;
wywołuje konstruktor bezparametrowy, który tworzy pustą tablicę.
vector<typ> T(n, v);
wywołuje inny konstruktor, który posiada dwa parametry n - liczbę elementów, v - wartość elementu. Ten konstruktor tworzy tablicę o pożądanej zawartości. To całe czary. Klasa vector posiada jeszcze dwa inne konstruktory, które umożliwiają utworzenie nowej tablicy na podstawie innej, którą wskażemy. Pierwszy z nich tworzy po prostu kopię innej tablicy. Składnia jest następująca:
vector<typ> nazwa(inna_tablica);
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Kopia tablicy //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { // Tworzymy pierwszą tablicę vector<int> T1; // wypełniamy ją 10 liczbami parzystymi for(int i = 2; i <= 20; i += 2) T1.push_back(i); // tworzymy w T2 dokładną kopię tablicy T1 vector<int> T2(T1); // wyświetlamy zawartość T2 for(unsigned i = 0; i < T2.size(); i++) cout << "T2[" << i << "] = " << T2[i] << endl; cout << endl; return 0; } |
T2[0] = 2 T2[1] = 4 T2[2] = 6 T2[3] = 8 T2[4] = 10 T2[5] = 12 T2[6] = 14 T2[7] = 16 T2[8] = 18 T2[9] = 20 |
Ostatni sposób tworzenia tablicy opiera się na tzw. iteratorach. Iteratory w STL są wskaźnikami (zmiennymi przechowującymi adresy innych zmiennych), które mogą wskazywać kolejne elementy przechowywane w klasie. Zmienną iteratora dla klasy vector tworzymy następująco:
vector<typ>::iterator nazwa_iteratora;
Adres pierwszego elementu tablicy uzyskujemy za pomocą funkcji składowej begin(). Druga funkcja składowa end() daje adres poza ostatni element tablicy - czyli nie wskazujący już żadnego elementu, który przechowuje tablica:
Adresy udostępniane przez funkcje składowe begin() i end() możemy wykorzystać w iteratorze:
iterator = T.begin(); // iterator wskazuje T[0] iterator = T.begin() + 1; // iterator wskazuje T[1] iterator = T.begin() + 2; // iterator wskazuje T[2] ... iterator = T.end() - 1; // iterator wskazuje ostatni element
Poniższy program demonstruje sposób wykorzystania iteratora do uzyskania dostępu do kolejnych elementów tablicy.
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Iterator //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { // Tworzymy tablicę 10 elementów o wartości zero vector<int> T(10, 0); // tworzymy iterator vector<int>::iterator it; // tablicę wypełniamy kolejnymi setkami int v = 0; for(it = T.begin(); it != T.end(); it++) * it = (v += 100); // wyświetlamy zawartość tablicy for(it = T.begin(); it != T.end(); it++) cout << "* it = " << * it << endl; cout << endl; return 0; } |
* it = 100 * it = 200 * it = 300 * it = 400 * it = 500 * it = 600 * it = 700 * it = 800 * it = 900 * it = 1000 |
Czwarty sposób tworzenia tablicy vector pozwala utworzyć ją jako kopię fragmentu innej tablicy tego samego typu (tj. przechowującej elementy takiego samego typu). Do określenia wielkości tego fragmentu wykorzystujemy dwa iteratory it1, i it2:
vector<typ> nazwa(it1, it2);
Iterator it1 musi wskazywać na pierwszy element do skopiowania. Iterator it2 wskazuje poza ostatni element do skopiowania. Kopiowane elementy są od it1 do elementu poprzedzającego it2. Poniższy program demonstruje tę opcję:
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Kopiowanie fragmentu tablicy //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { // Tworzymy tablicę bazową vector<int> T1; // wypełniamy ją liczbami od 0 do 9 for(int i = 0; i < 10; i++) T1.push_back(i); // tworzymy dwa iteratory vector<int>::iterator it1, it2; // it1 ustawiamy na T1[3] it1 = T1.begin() + 3; // it2 ustawiamy na T1[7] it2 = T1.begin() + 7; // tworzymy T2 jako kopię od T1[3] do T1[6] vector<int> T2(it1,it2); // wyświetlamy obie tablice for(unsigned i = 0; i < T1.size(); i++) { cout << "T1[" << i << "] = " << T1[i]; if(i < T2.size()) cout << " T2[" << i << "] = " << T2[i]; cout << endl; } cout << endl; return 0; } |
T1[0] = 0 T2[0] = 3 T1[1] = 1 T2[1] = 4 T1[2] = 2 T2[2] = 5 T1[3] = 3 T2[3] = 6 T1[4] = 4 T1[5] = 5 T1[6] = 6 T1[7] = 7 T1[8] = 8 T1[9] = 9 |
Używając iteratorów musimy wiedzieć jedną ważną rzecz na temat klasy vector. Przechowywane elementy są umieszczone w pamięci jeden obok drugiego w spójnym bloku. Na początku klasa rezerwuje pewien określony obszar pamięci, który służy jej do składowania kolejnych elementów tablicy, w miarę jak są one do niej wstawiane. Ale w pewnym momencie może okazać się, że przydzielony początkowo obszar pamięci jest zbyt mały, aby pomieścić kolejne elementy. Co wtedy robi klasa vector? Rezerwuje w pamięci większy blok i przenosi do niego zawartość obecnej tablicy. Następnie likwiduje starą tablicę oddając zajętą przez nią pamięć do systemu. Powoduje to zmianę adresów elementów. Jeśli przygotowałeś sobie iterator, to przestaje on być ważny i nie można go używać już do wskazywania elementów tej tablicy.
Uwaga: Po operacjach zmieniających rozmiar tablicy iteratory należy ponownie załadować, gdyż dane w tablicy mogą zmienić swój adres. |
Ostatni element usuwamy z tablicy za pomocą funkcji składowej pop_back(). Rozmiar tablicy maleje o 1. Tracą ważność iteratory.
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Usuwanie ostatniego elementu //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { // Tworzymy tablicę vector<int> T; // wypełniamy ją liczbami od 1 do 9 for(int i = 1; i <= 9; i++) T.push_back(i); // wyświetlamy tablicę usunięciem for(unsigned i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; // z końca tablicy usuwamy trzy elementy T.pop_back(); T.pop_back(); T.pop_back(); // wyświetlamy tablicę po wstawieniu for(unsigned i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; return 0; } |
T[0] = 1 T[1] = 2 T[2] = 3 T[3] = 4 T[4] = 5 T[5] = 6 T[6] = 7 T[7] = 8 T[8] = 9 T[0] = 1 T[1] = 2 T[2] = 3 T[3] = 4 T[4] = 5 T[5] = 6 |
Do usuwania dowolnego elementu z tablicy stosujemy funkcję erase() w sposób następujący:
tablica.erase(iterator);
Iterator wskazuje element do usunięcia. Po tej operacji tablica zawiera o jeden element mniej. Elementy leżące ponad pozycją iteratora zostają przesunięte w kierunku początku tablicy. Iteratory tracą ważność.
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Usuwanie elementu //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { // Tworzymy tablicę vector<int> T; // wypełniamy ją liczbami od 1 do 9 for(int i = 1; i <= 9; i++) T.push_back(i); // tworzymy iterator, ustawiając go na T[3] vector<int>::iterator it = T.begin() + 3; // wyświetlamy tablicę przed usunięciem for(unsigned i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; // usuwamy T[3] z tablicy T.erase(it); // wyświetlamy tablicę po usunięciu for(unsigned i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; return 0; } |
T[0] = 1 T[1] = 2 T[2] = 3 T[3] = 4 T[4] = 5 T[5] = 6 T[6] = 7 T[7] = 8 T[8] = 9 T[0] = 1 T[1] = 2 T[2] = 3 T[3] = 5 T[4] = 6 T[5] = 7 T[6] = 8 T[7] = 9 |
Z tablicy możemy również usunąć ciąg elementów, posługując się dwoma iteratorami:
tablica.erase(it1, it2);
it1 - wskazuje pierwszy element do usunięcia
it2 - wskazuje poza ostatni element do usunięcia
Rozmiar tablicy maleje o liczbę usuniętych z niej elementów. Tracą ważność iteratory.
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Usuwanie kilku przyległych elementów //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { // Tworzymy tablicę vector<int> T; // wypełniamy ją liczbami od 1 do 9 for(int i = 1; i <= 9; i++) T.push_back(i); // wyświetlamy tablicę przed usunięciem for(unsigned i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; // tworzymy dwa iteratory, ustawiając je na T[3] i T[7] vector<int>::iterator it1 = T.begin() + 3; vector<int>::iterator it2 = T.begin() + 7; // usuwamy T[3]...T[6] z tablicy T.erase(it1,it2); // wyświetlamy tablicę po usunięciu for(unsigned i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; return 0; } |
T[0] = 1 T[1] = 2 T[2] = 3 T[3] = 4 T[4] = 5 T[5] = 6 T[6] = 7 T[7] = 8 T[8] = 9 T[0] = 1 T[1] = 2 T[2] = 3 T[3] = 8 T[4] = 9 |
Do tablicy możemy wstawiać elementy na trzy różne sposoby za pomocą funkcji składowej insert():
tablica.insert(iterator, wartość);
Na pozycji wskazywanej przez iterator tablica zostaje rozsunięta i w powstałe miejsce jest wstawiana podana wartość. Rozmiar tablicy rośnie o 1. Tracą ważność iteratory.
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Wstawianie elementu //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { // Tworzymy tablicę vector<int> T; // wypełniamy ją liczbami od 1 do 9 for(int i = 1; i <= 9; i++) T.push_back(i); // wyświetlamy tablicę przed wstawieniem for(unsigned i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; // tworzymy iterator, ustawiając go na T[3] vector<int>::iterator it = T.begin() + 3; // na pozycji T[3] wstawiamy liczbę 1234 T.insert(it, 1234); // wyświetlamy tablicę po wstawieniu for(unsigned i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; return 0; } |
T[0] = 1 T[1] = 2 T[2] = 3 T[3] = 4 T[4] = 5 T[5] = 6 T[6] = 7 T[7] = 8 T[8] = 9 T[0] = 1 T[1] = 2 T[2] = 3 T[3] = 1234 T[4] = 4 T[5] = 5 T[6] = 6 T[7] = 7 T[8] = 8 T[9] = 9 |
tablica.insert(iterator, liczba_komórek, wartość);
Na pozycji wskazywanej przez iterator zostanie wstawiona podana liczba komórek o zadanej wartości. Rozmiar tablicy rośnie o liczbę wstawionych komórek. Tracą ważność iteratory.
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Wstawianie kilku elementów //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { // Tworzymy tablicę vector<int> T; // wypełniamy ją liczbami od 1 do 9 for(int i = 1; i <= 9; i++) T.push_back(i); // wyświetlamy tablicę przed wstawieniem for(unsigned i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; // tworzymy iterator, ustawiając go na T[3] vector<int>::iterator it = T.begin() + 3; // na pozycji T[3] wstawiamy 5 razy liczbę 1234 T.insert(it, 5, 1234); // wyświetlamy tablicę po wstawieniu for(unsigned i = 0; i < T.size(); i++) cout << "T[" << i << "] = " << T[i] << endl; cout << endl; return 0; } |
T[0] = 1 T[1] = 2 T[2] = 3 T[3] = 4 T[4] = 5 T[5] = 6 T[6] = 7 T[7] = 8 T[8] = 9 T[0] = 1 T[1] = 2 T[2] = 3 T[3] = 1234 T[4] = 1234 T[5] = 1234 T[6] = 1234 T[7] = 1234 T[8] = 4 T[9] = 5 T[10] = 6 T[11] = 7 T[12] = 8 T[13] = 9 |
Istnieje również możliwość wstawienia fragmentu innej tablicy. W tym przypadku używamy trzech iteratorów:
tablica.insert(it1, it2, it3);
it1 - wskazuje pozycję wstawiania w tablicy.
it2 - wskazuje początkowy element w innej tablicy
it3 - wskazuje poza ostatni do kopiowania element w innej tablicy
Kopiowane będą elementy od it2 do elementu poprzedzającego it3.
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Kopiowanie fragmentu innej tablicy //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { // Tworzymy tablicę nr 1 vector<int> T1; // wypełniamy ją liczbami od 1 do 9 for(int i = 1; i <= 9; i++) T1.push_back(i); // Tworzymy tablicę nr 2 vector<int> T2; // wypełniamy ją setkami od 100 do 900 for(int i = 100; i <= 900; i += 100) T2.push_back(i); // tworzymy trzy iteratory vector<int>::iterator it1, it2, it3; // it1 ustawiamy na T1[3] it1 = T1.begin() + 3; // it2 ustawiamy na T2[4] it2 = T2.begin() + 4; // it3 ustawiamy na T2[7] it3 = T2.begin() + 7; // W T1 na pozycji 3 wstawiamy T2[4]...T2[6] T1.insert(it1, it2, it3); // wyświetlamy T1 for(unsigned i = 0; i < T1.size(); i++) cout << "T1[" << i << "] = " << T1[i] << endl; cout << endl; // wyświetlamy T2 for(unsigned i = 0; i < T2.size(); i++) cout << "T2[" << i << "] = " << T2[i] << endl; cout << endl; return 0; } |
T1[0] = 1 T1[1] = 2 T1[2] = 3 T1[3] = 500 T1[4] = 600 T1[5] = 700 T1[6] = 4 T1[7] = 5 T1[8] = 6 T1[9] = 7 T1[10] = 8 T1[11] = 9 T2[0] = 100 T2[1] = 200 T2[2] = 300 T2[3] = 400 T2[4] = 500 T2[5] = 600 T2[6] = 700 T2[7] = 800 T2[8] = 900 |
Ostatnią na dzisiaj operacją jest wymiana zawartości dwóch tablic. Realizuje to funkcja składowa swap():
tablica1.swap(tablica2);
Po tej operacji w tablicy1 będziemy mieli zawartość tablicy2, a w tablicy2 będzie to, co wcześniej było w tablicy1. Ciekawostką jest fakt, iż dane wcale nie są wymieniane w pamięci - klasy wymieniają się jedynie adresami tablic. Dzięki temu czas operacji jest stały i nie zależy od liczby przechowywanych w tablicach elementów.
// Biblioteka STL // Klasa szablonowa vector //------------------------- // Wymiana zawartości tablic //------------------------- // (C)2011 Koło Informatyczne // I LO w Tarnowie //--------------------------- #include <iostream> #include <vector> using namespace std; int main() { // Tworzymy tablicę nr 1 vector<int> T1; // wypełniamy ją liczbami od 1 do 5 for(int i = 1; i <= 5; i++) T1.push_back(i); // Tworzymy tablicę nr 2 vector<int> T2; // wypełniamy ją setkami od 400 do 900 for(int i = 400; i <= 900; i += 100) T2.push_back(i); // wymieniamy zawartości obu tablic T1.swap(T2); // wyświetlamy T1 for(unsigned i = 0; i < T1.size(); i++) cout << "T1[" << i << "] = " << T1[i] << endl; cout << endl; // wyświetlamy T2 for(unsigned i = 0; i < T2.size(); i++) cout << "T2[" << i << "] = " << T2[i] << endl; cout << endl; return 0; } |
T1[0] = 400 T1[1] = 500 T1[2] = 600 T1[3] = 700 T1[4] = 800 T1[5] = 900 T2[0] = 1 T2[1] = 2 T2[2] = 3 T2[3] = 4 T2[4] = 5 |
Poniżej podsumowujemy opisane funkcje oraz kilka innych, które mogą być użyteczne w trakcie pracy z klasą vector. Najlepiej wydrukuj tabelkę i noś ją przy sobie.
Tworzenie tablicy | |
vector <typ> tablica; | pusta tablica |
vector <typ> tablica(n , v); | tablica o n elementach, każdy o wartości v |
vector <typ> tablica(inna_tablica); | kopia innej tablicy o takiej samej zawartości |
vector <typ> tablica(it1, it2); | kopia fragmentu innej tablicy. it1 - iterator wskazujący pierwszy element do skopiowania it2 - iterator wskazujący poza ostatni element do skopiowania |
Tworzenie zmiennej typu iterator | |
vector <typ> :: iterator nazwa; | |
Dostęp do elementów tablicy | |
tablica[indeks] | poprzez indeksowanie - nie sprawdza zakresów indeksów |
tablica.at(indeks) | poprzez funkcję składową, która sprawdza zakresy indeksów. Jeśli indeks wykracza poza rozmiar tablicy, generowany jest wyjątek. |
tablica.front() | odwołanie do pierwszego elementu |
tablica.back() | odwołanie do ostatniego elementu |
Rozmiar tablicy | |
tablica.size() | zwraca liczbę elementów przechowywanych w tablicy |
tablica.empty() | jeśli tablica nie przechowuje żadnego elementu, zwraca true. Inaczej zwraca false. |
tablica.max_size() | zwraca maksymalny rozmiar tablicy - czyli liczbę elementów, którą tablica może przechować |
Funkcje związane z iteratorami | |
tablica.begin() | zwraca iterator do pierwszego elementu tablicy |
tablica.end() | zwraca iterator poza ostatni element w tablicy. Iterator ten nie wskazuje żadnego elementu w tablicy. |
Wstawianie danych do tablicy | |
tablica.push_back(v) | dopisuje wartość v na końcu tablicy. Rozmiar tablicy rośnie o 1. Iteratory tracą ważność. |
tablica.insert(it,v) | wstawia na pozycję iteratora it wartość v. Rozmiar tablicy rośnie o 1. Iteratory tracą ważność. |
tablica.insert(it, n, v) | wstawia od pozycji iteratora it n wartości v. Rozmiar tablicy rośnie o n. Iteratory tracą ważność. |
tablica.insert(it1, it2, it3) | wstawia na pozycji iteratora it1 fragment
innej tablicy, zdefiniowany przez iteratory it2 i it3: it2 - wskazuje pierwszy element do wstawienia it3 - wskazuje poza ostatni element do wstawienia Rozmiar tablicy rośnie o liczbę wstawionych elementów. Iteratory tracą ważność. |
Usuwanie danych z tablicy | |
tablica.clear() | usuwa z tablicy wszystkie elementy. Po tej operacji rozmiar tablicy wynosi 0. Iteratory tracą ważność. |
tablica.pop_back() | usuwa z tablicy ostatni element. Rozmiar tablicy zmniejsza się o 1. Iteratory tracą ważność. |
tablica.erase(it) | usuwa element wskazywany przez iterator it. Rozmiar tablicy zmniejsza się o 1. Iteratory tracą ważność. |
tablica.erase(it1, it2) | usuwa ciąg przyległych elementów. it1 - wskazuje pierwszy element do usunięcia w tym ciągu. it2 - wskazuje poza ostatni element do usunięcia. Rozmiar tablicy zmniejsza się o liczbę usuniętych elementów. Iteratory tracą ważność. |
Wymiana zawartości tablic | |
tablica1.swap(tablica2) | wymienia zawartość tablicy1 z tablicą2. Iteratory pozostają ważne. |
Pozostałe funkcje składowe | |
tablica.resize(n) | zmienia rozmiar tablicy na n komórek. Jeśli tablica posiadała wcześniej większy rozmiar, to elementy ponad n są usuwane. Jeśli rozmiar był mniejszy, to na końcu tablicy zostają wstawione puste elementy do osiągnięcia rozmiaru n. Iteratory tracą ważność. |
tablica.resize(n,v) | działa jak powyżej, dodatkowe elementy są inicjowane na wartość v. |
tablica.reserve(n) | rezerwuje dla tablicy obszar do przechowywania przynajmniej n elementów. Funkcja ta zapewnia, iż tablica nie będzie zmieniać swojego położenia w pamięci, jeśli jej rozmiar nie przekroczy n. Najlepiej wywołać ją przed zapisem elementów do tablicy. |
tablica.assign(n,v) | pozwala przypisać tablicy nową zawartość. Stara zawartość jest usuwana, a na jej miejsce powstaje n komórek o wartości v. |
tablica.assign(it1, it2) | usuwa bieżącą zawartość tablicy i na jej miejsce
kopiuje fragment innej tablicy zdefiniowany przez iteratory: it1 - wskazuje pierwszy element do skopiowania it2 - wskazuje poza ostatni element do skopiowania |
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe