A továbbiakban tárgyalt deklarációk mindegyike az std
névtérben található, a fóliákon úgy szerepelnek, mintha érvényben lenne az using namespace std
direktíva.
using
, kötelező kiírni a teljes neveket, pl. std::string
C sztringeknél (0
-val lezárt char*
tömb) helyett gyakran string
típussal ábrázoljuk a szövegeket C++ nyelven.
Előnyök
string
különállóchar*
mutathat ugyanoda, módosítás után mindkettő látja a változástHátrány: nagyobb tárigény
+
, +=
: szövegek összefűzésérelength()
: szöveg hosszastring s;
for (char c ='a'; c <= 'z'; ++c) s += c;
// "abc..."
string s2 = s + "0123456789";
+
operátorralstring s;
s += 65; // karakter hozzáfűzése
// eredmény: "a"
Pár: két, valamilyen szempontból összetartozó értéket fog össze
pair<char, string> p('a', "bcd");
cout << p.first;
cout << p.second;
// kimenet: "abcd"
iostream
(kimenet/bemenet) és az fstream
(fájlok) fejlécekben érhetőek elistream
: bemeneti folyamostream
: kimeneti folyamifstream
, ofstream
: fájlból olvasó/fájlba író folyamcin
: sztenderd bemeneti folyamcout
: sztenderd kimeneti folyamcerr
: sztenderd hibafolyamifstream ifs("a.txt");
>>
és <<
: beolvasás és kiírásfriend
függvényként)ifstream&
(illetve ofstream&
), hogy tovább lehessen olvasni és írnihex
vagy noskipws
eof()
: megadja, hogy a folyam véget ért-eendl
: sorvége (kiírásnál gyakori)// gyakori beolvasási séma
while (cin >> adat) {
...
}
STL (Standard Template Library): a nyelv részévé vált könyvtár
Az STL fő céljai
Sorozat jellegű tárolók
vector
: dinamikus tömb, amelybe beszúrhatóak és törölhetőek elemekoperator[]
: elem elérése konstans időben, határellenőrzés nélkül// az STL osztályokat általában
// a megegyező nevű fejléc tartalmazza
#include <vector>
vector<int> v(10); // 10 elemű vektor
for (int i = 0; i < 10; ++i) v[i] = i;
Sorozat jellegű tárolók
vector
at(int)
: elem elérése konstans időben, határellenőrzéssel (out_of_range
kivételt vált ki)vector<int> v(3); // elemek: v[0], v[1], v[2]
int i = v[3]; // nincs hiba, i értéke ismeretlen
int j = v.at(3); // out_of_range kivétel
Sorozat jellegű tárolók
list
: kétszeresen láncolt lista#include <list>
list<int> l;
for (int i = 9; i >= 0; --i) l.push_front(i);
// l ≡ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// a push_front a tároló elejére helyezi az elemet
// a push_back a tároló végére helyezi az elemet
Asszociatív tárolók: az elemek nincsenek sorba rendezve
set
: halmaz, egy elem legfeljebb egyszer szerepelhet bennemultiset
: egy elem többször is szerepelhet benneset<int> s; multiset<int> m;
s.insert(1); m.insert(1); // egy elem beszúrása
s.insert(2); m.insert(2);
s.insert(2); m.insert(2);
// x 1 2 3
// s.count(x) 1 1 0
// m.count(x) 1 2 0
s.erase(2); m.erase(2);
// s.count(x) 1 0 0
// m.count(x) 1 0 0
Asszociatív tárolók
map
: kulcs-elem párokat tartalmaz, a kulcsoknak rendezetteknek kell lenniük (operator<
)operator[]
létre is hozza az elemet (az alapértelmezett konstruktorral), ha még nem szerepeltmultimap
: egy pár többször is szerepelhet bennemap<string, int> m;
m["abc"] = 1;
m["def"] = 2;
if (m["xyz"] == 0) { ... }
// nem jó, létrejön az "xyz" kulcsú elem,
// pont 0 értékkel
if (m.find("xyz") != m.end() && m["xyz"] == 0) { ... }
// ez megvizsgálja azt is, létezik-e a kulcs
// kihasználtuk, hogy && rövidzáras
Bejáró (iterátor): a tároló egy elemére mutat, egy mutatóhoz nagyon hasonlóan
++
(pre- és posztfix egyaránt): a tároló következő elemére mutat--
: a ++
ellentéte (csak kétirányú bejáróra értelmezett)*
(prefix): visszaadja a mutatott elemet (hasonlóan a mutatók feloldásához)->
: taghivatkozás a mutatott elemen belül, mint mutatóknálBejáró
begin()
: a tároló első elemére mutatend()
: a tároló utolsó utáni elemére mutatrbegin()
, rend()
: ha visszafelé is bejárható a tároló, a tároló hátulról nézve első/utolsó utáni elemére mutat// minden kulcshoz tartozó érték megnövelése eggyel
for (map<string, int>::iterator it = m.begin();
it != m.end(); ++it) {
++(it->second);
}
Algoritmusok
algorithm
fejléc szükséges hozzáAlgoritmusok leírásai
Függvényobjektum vagy funktor: állapottal rendelkező függvény
operator()
felül van definiálva// itt még nincsen szükség függvényobjektumra
void kiiro(pair<string, int> p) {
cout << p.first << " " << p.second << endl;
}
// minden elemre meghívjuk a kiiro függvényt
for_each(m.begin(), m.end(), kiiro);
Függvényobjektum
struct kiiro
{
kiiro(ostream& o) : os(o) {}
void operator()(pair<string, int> p) {
os << p.first << " " << p.second << endl;
}
private:
ostream& os;
};
for_each(m.begin(), m.end(), kiiro(cout));
Függvényobjektum
find_if(l.begin(), l.end(), bind1st(less<int>(), 3));
// bind1st: a függvény második argumentumát rögzíti
// (? < ?) ===> (3 < ?)
// az első, háromnál nagyobb elem bejáróját adja vissza
// ha nincs ilyen elem, l.end() az eredmény
count_if(v.begin(), v.end(), bind2st(less<int>(), 6));
// a vektor hatnál kisebb elemeinek száma
// feltétel: (? < 6)
Előre definiált függvényobjektumok
vector<int>::iterator vit =
remove(v2.begin(), v2.end(), 1);
// ha v2 kezdetben [1 1 2 1 3] ===> [2 3|2 1 3]
// a függőleges vonal jelzi a visszaadott bejárót,
// de v2 teljes hossza még mindig öt
vi.erase(vit, vi.end());
// eltünteti a felesleges elemeket
Előre definiált függvényobjektumok
list<int> l;
copy(istream_iterator<int>(cin),
istream_iterator<int>(),
back_inserter(l)); // lista beolvasása
copy(l.begin(), l.end(), ostream_iterator<int>(cout));
// lista kiírása
copy(l.rbegin(), l.rend(), ostream_iterator<int>(cout));
// lista kiírása fordított sorrendben