Teskari iteratorlar - Tiplarni dinamik tarzda aniqlash. Reja: Tiplarni dinamik tarzda aniqlash

|
Tiplarni dinamik tarzda aniqlash. Reja: Tiplarni dinamik tarzda aniqlash
|
bet | 51/143 | Sana | 20.07.2024 | Hajmi | 0,81 Mb. | | #268096 |
Bog'liq Tiplarni dinamik tarzda-fayllar.orgTeskari iteratorlar. Bu iteratorlar konteynerning elementlarini teskari olishni amalga oshiradi. Buning uchun reverse_iterator tipi ishlatiladi. Bu tipdagi iteratorlarga konteynerning elementlarini olish uchun rbegin() i rend() funksiyalaridan foydalaniladi.
#include "stdafx.h" #include #include using namespace std; int main()
{
int myints[] = { 1, 2, 3, 4, 5 };
vector v (myints, myints+ sizeof(myints)/sizeof(myints[0]));
for (vector::reverse_iterator iter = v.rbegin(); iter != v.rend(); ++iter) std::cout << *iter << " | ";
cout << endl; system("pause");
return 0;
}
|
Agar konteynerni o‘zgartirishdan himoyaya qilish va teskarisi kerak bo‘lsa, const_reverse_iterator tipidagi iteratordan va uning crbegin() va crend() funksiyalaridan foydalanish maqsadga muvofiqdir. Yuqoridagi dasturga quyidagi fragmentni yozish yetarli bo‘ladi.
for (vector::const_reverse_iterator iter = v.crbegin(); iter != v.crend();
++iter)
std::cout << *iter << " | ";
|
Shuningdek iteratorlari qo‘shima amallarga ham ega (list va forward_list konteynerlaridan tashqari):
iter + n - n ta pozitsiya keyingi elementni ko‘rsatuvchi iteratorni qaytaradi.
iter – n - n ta pozitsiya oldingi elementni ko‘rsatuvchi iteratorni qaytaradi.
iter += n - iteratorni n - chi pozitsiyaga o‘tkazadi
iter -= n - iteratorni n - chi pozitsiyaga o‘tkazadi
iter1 - iter2 - iter1 va iter2 lar orasidagi pozitsiyalar sonini qaytaradi
[>], [>=], [<], [<=] - taqqoslash amallari. Agar iterator oxiriga yaqin elementni ko‘rsatsa boshqasidan katta.
5.9-dastur. Iteratorning qo‘shimcha amallaridan foydalanish.
#include "stdafx.h" #include #include using namespace std; int main()
{int myints[] = { 1, 2, 3, 4, 5 };
vector v (myints, myints+ sizeof(myints)/sizeof(myints[0])); for (auto i = v.begin(); i < v.end(); i++)
{cout << *i << " | ";}
cout << endl;
auto it1 = v.begin(); auto it2 = it1 + 2;
cout << "it1 + 2 => " << *it2 << endl; auto it3 = v.end() - 3;
cout << "it1 - 3 => " << *it3 << endl; it2 += 2 ;
cout << "it2 + 2 => " << *it2 << endl; it3 -= 2;
cout << "it3 - 2 => " << *it3 << endl;
cout << "it2 - it1 => " << it2 - it1 << endl; cout << "(it1 < it2) => " << (it1 < it2) << endl;
|
cout << "(it1 >= it2) => " << !(it1 < it2) << endl; cout << "(it1 != it2) => " << !(it1 == it2) << endl;
cout << "(it1 == it2) => " << (it1 == it2) << endl; cout << "(it1 != it2) => " << (it1 != it2) << endl; cout << endl;
system("pause"); return 0;
}
|
5.9-dastur.Output
|
1 | 2 | 3 | 4 | 5 |
it1 + 2 => 3
it1 - 3 => 3
it2 + 2 => 5
it3 - 2 => 1
it2 - it1 => 4 (it1 < it2) => 1 (it1 >= it2) => 0 (it1 != it2) => 1 (it1 == it2) => 0
(it1 != it2) => 1
|
Taqqoslash amallari uchun ko‘chirib o‘tish iteratorlari va bazaviy iteratorlar uchun baʻzi C++ dasturlashda farqlari bor.
5.1-jadval. Taqqoslash amallari yozish uslublari.
Ko‘chirib o‘tish iteratorlari uchun.
|
Ekvivalent bazaviy iteratorlari uchun.
|
move_ita == move_itb
|
basic_ita == basic_itb
|
move_ita != move_itb
|
!(basic_ita == basic_itb)
|
move_ita < move_itb
|
basic_ita < basic_itb
|
move_ita <= move_itb
|
!(basic_itb < basic_ita)
|
move_ita > move_itb
|
basic_itb < basic_ita
|
move_ita >= move_itb
|
!(basic_ita < basic_itb)
|
Xotirani taqsimlovchilar va ularga qo‘yilgan talablar. Dinamik xotira bilan ishlashda maxsus truklarni, fragmentlardan foydalanish bo‘lmasa, ko‘pigina algoritmlardan foydalanish samarasiz bo‘lshi mumkin. Bunga misol sifatida ikkita holatni ko‘rib chiqamiz. new va delete operatorlarining qayta aniqlanib yuklanishida sintaktik konstruktorlar kichikroq bo‘ladi va dastur lokalizatsiya qilish oddiy bo‘ladi. Shuningdek protsessordagi amallar tizimida ham qayta aniqlash sodir bo‘ladi.
Avvalo, xotirani ishlashini tezlashtirishda aqlli allocator qanchalik foydasi borligini aniqlash lozim. Buning uchun oddiy test misollarini (C++ va S#) tillarida ko‘rib chiqaylik ( bu xotira bilan ishlash uchun yaxshi menejer hisoblanadi va obʻyektlarni avlodlarga ajratadi, turli o‘lchamdagi obʻyektlar uchun turli pullardan (joylar) foydalanadi).
C++ dagi dastur
|
class Node { public:Node* next;};
// ...
for (int i = 0; i < 10000000; i++) { Node* v = new Node();}
|
C++ dagi dastur
|
class Node
{public Node next;}
// ...
for (int l = 0; l < 10000000; l++)
{var v = new Node();}
|
Dasturlar sharsimon vakum usulini qo‘llab ham vaqt bo‘yicha solishtirilsa 10 barovar (62 ms va 650 ms) farq bo‘lmoqda. Shuningdek C# ishini tugutdi, ammo C++ da esa yaxshigini xotira ajratilan, bu hali o‘chirish kerak.
|
| |