logo

C++ dasturlash tilining regex, type info va forward_list kutubxonalari funksiyalari bilan ishlash

Yuklangan vaqt:

12.08.2023

Ko'chirishlar soni:

0

Hajmi:

328.9423828125 KB
1Mavzu:  C++ dasturlash tilining  regex,  type info 
va forward_list kutubxonalari funksiyalari bilan 
ishlash.
                             Reja:
1. regex ning C++ dagi funksiyalari.
2. type info C++ dagi funksiyalari.
3. forward_list  C++ dagi funksiyalari. 21. Regular expression va undan C++ da foydalanish
Regex  berilgan belgilar to'plamini ichidan siz bergan ifoda bo'yicha belgilar 
to'plamini olish. Unchalik tushunarsiz bo'ldimi? Shoshilmang, hozir uni amaliyotda 
ko'ramiz va u o'ylaymanki sizga yoqib qoladi :) Oddiy bir misol, sizga gap berilgan, o'sha
gap ichidan e-mail manzillarini ko'rsatib berishingiz kerak. Qoyil, siz buni qiynalmasdan 
bajara olasiz! Lekin qanday? Siz beixtiyor harflar va raqamlar aralashgan 
ifoda(username) va undan keyin keladigan kuchukcha belgisi va domen yozilgan belgilar
to'plamini e-mail manzil deb ko'rsatasiz(masalan ,   cppcoder24@gmail.com ) va siz  e-mail 
ni topishda o'z qolipingizdan foydalandingiz(<username>@<domen>). Ya'ni e-mail 
manzilni qanday formada bo'lishini bilasiz. Endi shuni dasturimizga tatbiq qilib ko'ramiz.
Agar siz qidirish tizimlaridan, so'zni qidirish va uni boshqasi bilan almashtirish 
funksiyalaridan, oddiy matn muxarrirlaridan foydalangan bo'lsangiz, demak siz uni 
amaliyotda ko'rgansiz! Shuningdek, regex dan parollarni kuchli-kuchsiz tuzilganini 
tekshirishda ham ishlatishadi. Regex da qidirish belgilardan iborat ifoda yordamida 
amalga oshiriladi, bu ifoda qolip vazifasini bajaradi.
C++ da kod yozib ko'rganlar juda yaxshi bilishadi, unda ma'lumotlarni to'g'ri 
ekanligini tahlil qilish bir muncha murakkab jarayon. Masalan, foydalanuvchidan son 
kiritishni so'radingiz, kiritiladigan narsani siz string da olib, uni haqiqatda sonmi-yo'qmi 
bilmoqchisiz. Har bir dasturchi bu jarayonda o'zining tekshirish algoritmini yozib 
chiqishga majbur bo'ladi. Lekin C++ 11 da regex kirib keldi va bu endi muammo emas! 
C++ 11 ECMAScript, awk, grep va yana bir nechta regular expression grammatikasini 
qo'llab-quvvatlaydi, biz ECMAScript sintaksisini ko'rib o'tamiz. Regex kutubxonasini 
kodimizda import qilamiz:
#include <regex>bu orqali biz regex dan kodimizda foydalana olishimiz mumkin. 
Lekin bu C++11 va undan yuqorida ishlaydi.
DIQQAT! Namunadagi kodlar main funksiyasi ichiga yoziladi:
#include <iostream>
#include <regex>
using namespace std;
int main() 3{
Endi c++ da kod yozib, uni sinab ko'rish uchun biror muhitni oching :)C++ 11 ni 
sozlash . Sozlashni Code::Blocks muhitida ko'rib o'tamiz. Birorta konsol proyekt ochib, 
yuqorida turgan paneldan Settings->Compiler ni tanlaymiz.  Va uni quyidagi rasmdagidek
sozlab olamiz:
Ok ni bosamiz. Tayyor.
Dev muhitini ishlatadiganlar diqqatiga. Yuqoridagi paneldan Tools->Compiler Options 
ga kiramiz, bizga kompilyator sozlamalari oynasi ochiladi: 4Va rasmda ko'rsatilgan bo'limdan ISO C++ 11 ni tanlab, OK ni bosamiz, Tayyor
Regex da ifodalar tuzish.
    Regex da belgilar to'plamini ichidan o'zimizga kerakli qismini olish uchun ifoda 
tuzishni o'rganib chiqishimiz kerak. Ifodani belgilar yordamida tuzamiz. Biz tuzgan ifoda
o'ziga mosini o'sha belgilar to'plami ichidan topib beradi. Ifodani belgilar to'plamidan 
tuzamiz, o'z navbatida belgilarimiz oddiy va maxsus(metacharacter) bo'ladi. Oddiy 
belgilardan foydalansak, ular berilgan matn ichidan o'ziga o'xshaganlarni topib beradi. 
Maxsus belgilar biroz boshqacharoq ishlaydi. Biz ifodani tuzayotganda uni
Raw String   qilib tuzganimiz ma'qul. Nima ekanligini keyinroq tushuntirib beraman. 
Maqolani shu joyiga kelganda, mavzudan biroz chetga chiqib, raw string ni ozroq 
tushuntirib bersam,
Raw string o'zi anglatib turgandek "chala" string. Uni oddiy string tipida qo'shtirnoqlarni  5boshlanishiga R harfini qo'yib hosil qilamiz, qo'shtirnoq ochilgandan keyin ochiq qavs va
yopilishidan oldin yopiq qavs qo'yish shart. Keling, namuna ko'raylik:
string s="Salom!\n Havo ajoyib-a?!";
string s1=R"(Salom!\n Havo ajoyib-a?!)";
cout<<s<<endl;
cout<<"=====\n";
cout<<s1<<endl;Natija:
Salom!
  Havo ajoyib-a?!
=====
Salom!\n	
 Havo	 ajoyib-a?!
Ko'rib turganingizdek, \n da enter tashlanishi kerak edi, raw string esa shunaqa 
joylarini inkor qila oladi
\ - bu shunchaki backslash va uni raw stringda shunchaki ishlatish mumkin, stringda 
backslash ni ishlatish uchun \\ yozishimiz kerak.
 
Ifodamiz albatta regex tipida bo'lishi kerak. Ifoda yozishdan oldin ba'zi 
metacharacterlar(maxsus belgilar) bilan tanishib chiqsak:
. - nuqta har qanday belgini topib beradi
\d - har qanday raqamni topib beradi(decimal). Ushbu metacharacterga ekvivalent: 
[[:digit:]]
\D - \d ni teskarisi, raqam bo'lmagan belgini topib beradi. Ushbu metacharacterga 
ekvivalent [^[:digit]]
\s - bo'shliqni topadi(space, tab)
\S - \s ni teskarisi.
\w - alphanumeric(harf yoki raqam) va tagchiziq belgisini topadi.
\W - \w ni teskarisi.
+ biror x belgidan keyin ushbu belgini qo'yish orqali ushbu x belgi 1 yoki ko'p marta 
qatnashishi kerakligini bildirgan bo'lamiz.
| - or(yoki), buni biz 2 ta belgi orasiga qo'llash orqali ulardan biri kelganini 
aniqlashimiz mumkin bo'ladi.
[belgilar to'plami] - ushbu burchakli qavslar ichida belgilar kategoriyasini kiritamiz. 
Ichidagi belgilardan duch kelganini topadi. Masalan, agar [abc] desak, unda a, b, yoki c 
belgisini topadi. 6X dan Y gacha bo'lgan oraliqlarni [X-Y] tarzida belgilaymiz. Masalan: [a-z] - a, b, c, 
d, ... z belgilar ichidan uchraganini topib beradi, agar [0-9] desak, unda raqamlarni 
topadigan bo'ladi.
regex_match (string s, match m, regex rgx) - matndan ifodaga mos qismini qidiradi, 
topilsa true, aks holda false qaytaradi. Parametrlariga ortiqcha izoh berishim shartmas 
deb o'ylayman - 3 ta argument oladi, biri string tipida, 2-si regex bo'lishi kerak. m 
argumenti haqida keyinroq gaplashamiz, hozircha u unchalik muhimmas va argument 
berilishi shartmas.
Maxsus belgilar bilan biroz bo'lsa-da tanishib oldik. Ho'p, bu yaxshi, lekin men matn 
ichidan aytaylik nuqta(.) ni qidirmoqchiman, lekin u metacharacter bo'lsa, unda buni 
qanday qilaman? Biz maxsus belgilarni oldiga backslash qo'yish orqali ularni maxsus 
qobilyatidan maxrum qilib qo'yamiz, javob: \. orqali nuqtani topishimiz mumkin.
Maxsus belgilardan qanday foydalanishni esa quyidagi misolda ko'rib o'tamiz:
Aytaylik, sizga string tipida ma'lumot berilgan, ushbu ma'lumotni int tipiga o'girishda 
xatolik bo'lish-bo'lmasligini topishingiz kerak. Kiritiladigan ifodalar masalan 007, +07, 7 
yoki -007, -7 ko'rinishida bo'lishi mumkin. +-12 kiritsak xatolik beradi. Endi asosiy 
fokusni kod yozishga qaratamiz, regex da o'rgangan ayrim metacharacterlarimiz yetarli:
regex ifoda(R"((\+|-)?[0-9]+)");
string input;
cout<<"\nSon kiriting: ";
cin>>input;
if(regex_match(input, ifoda))
{
  cout<<"Integer!";
}else{
   cout<<"Xatolik!";
  }
Menimcha ko'pchilik regex tipidagi ifodamizga unchalik tushunmadi, uni bo'laklab 
tahlil qilamiz. Raw string ligi uchun biz R"()" ichiga ifodani yozamiz. Endi, son oldida + 
yoki - kelishi kerak, buni qavs ichida (+|-) deb yozishimiz mumkin edi, lekin biz + ni 
metacharacter ekanligini hisobga olib, uni maxsus qobilyatidan maxrum qilamiz: (\+|-) 
bo'ldi. ? belgisi 0 yoki 1 marta qatnashsin degani, uni boyagi tuzgan ifodamizdan keyin 
qo'llasak, + yoki - belgisi 0 yoki 1 marta qatnashsin degan bo'lamiz. [0-9] esa 0 dan 9 
gacha kelgan raqam degani, undan keyin agar + qo'ymasak, u faqat bir xonali sonlar 
uchun ishlaydi. [0-9]+ ifodamiz 0 dan 9 gacha oraliqdagi raqamlar 1 yoki ko'p marta 
qatnashsin deganini ifodalaydi. Endi barchasini umumlashtiramiz: (\+|-)?[0-9]+ --> + 
yoki - belgisi 0 yoki 1 marta qatnashgan holda 0 dan 9 gacha bo'lgan raqam 1 yoki ko'p  7marta bo'lsin. Hozir bularni o'qib, bu AbraKadabraga tushunmadingizmi? Unda o'zingiz 
metacharacterlar tasnifiga qarab boshqattan hijjalab tahlil qilib ko'ring.
Metacharacterlarga yaxshi e'tibor berganlar fahmlab ulgurishgan: [0-9] ni [\d] bilan 
almashtirishimiz mumkin, bu natijaga ta'sir qilmaydi. \d nima qilishini yuqoridan 
topishingiz mumkin.
ifoda o'zgaruvchisiga regex da ifodamizni yozmasdan, uni shundayligicha 
regex_match funksiyamizga berib qo'ysak ham bo'laveradi:
regex_match(input, regex(R"((\+|-)?[0-9]+)"))
Endi biroz kirishib oldik deb o'ylayman, shu joyida raw string ni nega 
qo'llayotganimizga qisqacha izoh berib ketsam. C++ da shunchaki oddiy string ga regex 
ifodasini kiritsak u xunuklashib ketadi. Keling, ifoda o'zgaruvchisidagi scriptimizni oddiy
stringga o'giramiz: (\\+|-)?[0-9]+ Nega 2 ta backslash? Yuqorida aytganimdek, 
backslashni o'zini stringga berish uchun \\ ni yozish kerak. Ho'p, bunda bitta backslashga 
farq qilyabdi ifodamiz, lekin agar ko'p marta maxsus belgilarni oddiy belgi sifatida 
ifodamizga kiritmoqchi bo'lsak-chi? Unda ularni oldiga backslash qo'yishimiz kerak 
ularni maxsus qobilyatini bekor qilish uchun, keyin shu backslashni o'ziga ham yana bitta
backslash qo'llashimiz kerak, bu o'qishni birmuncha qiyinlashtiradi, tinchgina raw 
stringdan foydalanib qo'yaveraylik ;)
Endi e-mail uchun regex ifoda yozib ko'ramiz:
regex pattern_email(R"(([\w\.-]+)@([\w\.-]+))"
Endi tahlil qilib ko'rsak: ([\w\.-]+)@([\w\.-]+) ifodamizni to'lig'i. 1-qavsda kelgan 
burchakli qavs ichida biz belgilar kategoriyamizni tuzdik: \w - harf yoki raqam, \. - 
nuqta(agar oddiy nuqta bo'lsa maxsus qobiliyatidan foydalanib qo'yadi :) ), chiziqcha(- 
bir o'zi oddiy belgi bo'lib keladi, oraliqlarda boshqacha), Shulardan keyin kuchukcha va 
yana boyagi ifodamiz. Bu orqali yuqorida o'ylab qo'ygan <username>@<domen> 
qolipimizni yaxshiroq tushuntirdik.
Regex da ba'zi funksiyalar.
Ifoda tuzishni biroz o'rganib oldik, endi ba'zi funksiyalarni ko'rib o'tsak.
regex_match()   - ushbu funksiya haqida yuqorida aytib o'tgandim. m argumentiga 
kelsak, u berilayotgan belgilar to'plami string yoki char massiv shaklida bo'lishiga qarab 
smatch yoki cmatch tipida bo'ladi, o'ziga ifoda bo'yicha topilgan ma'lumotni oladi, 
masalan:
string mystr;
 regex pattern_email(R"(([\w\.-]+)@([\w\.-]+))");
 smatch mch;
 cin>>mystr;
 if(regex_match(mystr, mch, pattern_email)) 8   for(auto x: mch) cout<<x;agar mystr char massiv bo'lsa, mch o'zgaruvchisining tipi 
cmatch bo'lishi kerak.
smatch/ cmatch ni shunchaki chop etolmaysiz, buning uchun chiqarish operatorini 
qayta yuklashga to'g'ri keladi. Yaxshisi, sikldan foydalaning, yoki nom.str() qilib ko'ring, 
bunda nom smatch/cmatch tipidagi o'zgaruvchi
regex_search(s, m,	 rgx)   - bu ham xuddi match ga o'xshaydi, berilgan satr ichidan rgx 
ifodaga mosini qidiradi, agar bo'lsa uni m ga beradi.
regex_replace()   - 3 ta argument oladi: birorta matn, regex ifoda, va almashtiriladigan 
so'z. Matnda ifodaga mos belgilar bo'lsa, ularni almashtiriladigan so'z bilan almashtirib 
qaytaradi. Namuna:
string mystr="998901234567 2532 24462334 998907777777";
 regex regexp(R"([0-9]{9,12})");
 cout<<regex_replace(mystr, regexp, "telefon raqam");Natija:
telefon raqam 2532 24462334 telefon raqam
ifodamizda [0-9] ni tushundingiz, {9,12} - shakli: {x, y}, o'zidan oldin kelgan belgini 
minimal x marta, maksimal y marta takrorlanishi kerakligini bildiradi, ifodamizda esa 
o'sha 0-9 gacha raqamlar minimal 9 marta, maksimal 12 marta qatnashsin degani. Agar 
biz uni shunchaki {9,} qilsak, unda kamida 9 marta qatnashsin degani bo'ladi.
Yuqoridagi namuna telefon raqamlar uchun yana ozroq mukammallashtirishingiz 
mumkin bo'ladi, masalan \+?9989[01349][0-9]{7} qilib. E'tibor qilgan bo'lsangiz, 
yuqorida {9,} ifodasi birorta belgi kamida 9 marta qatnashsin deganini bildiradi 
degandik. bunda esa {7} faqat 7 marta qatnashsin degani, vergulga e'tibor bering.
regex_iterator()   - keling, buni ko'rishdan oldin quyidagi matnni tahlil qilib ko'ramiz: 
"Men kecha o'zimning e-mailim emailnom@gmail.comdan support@gmail.comga xat 
yubordim" matnidagi barcha email larni oladigan dastur tuzaylik. Buni regex_search 
bilan eplasa bo'ladi dersiz, lekin u qolipga tushadigan ma'lumotlarni birinchisini oladi-da,
bizga hammasi kerak! Balkim, sikl yordamida regex_search, regex_match va 
regex_replace larni qo'llamoqchidirsiz, yomonmas. Lekin regex_iterator bilan kodlash bu
ishda oson (iterator - takrorlovchi degani)! regex_iterator char massiv bilan ishlash 
uchun, string bilan esa sregex_iterator ishlaydi. Biz string da ish ko'ramiz, sababi string 
bilan ishlashda C-string(const char *) ga qaraganda bir qancha ustunlik tomonlari bor, 
shuning uchun namunani sregex_iterator da ko'rib o'tamiz. Biz har bir topilgan 
ma'lumotni chop etishimiz uchun sikldan foydalanamiz, faqat bunda sanagichimiz 
sregex_iterator turida bo'ladi. Har doimgidek namuna kodini ko'rsataman, so'ng uni tahlil
qilamiz:
regex regexp(R"(([\w\.-]+)@([\w\.-]+))");
sregex_iterator it(mystr.begin(), mystr.end(), regexp); 9sregex_iterator it_end;
while(it!=it_end)
{
  smatch i=*it;
  cout<<i.str()<<endl;
  ++it;
}
 3-qatordan boshlasak. Tahlil qilinishi kerak bo'lgan matn stringda, shuning uchun 
sregex_iterator dan foydalanamiz. Shu tipda it degan o'zgaruvchi olyabmiz, u matnimiz 
boshidan oxirigacha regexp qolipimiz bo'yicha ma'lumot qidiradi. Umuman olganda, 
iteratorni pointer bilan umumiy xususiyatlari ko'p, lekin bir muncha murakkab. Siz uni 
xuddi pointer kabi oshirishingiz mumkin. sregex_iterator va regex_iterator ning o'ziga 
xos xususiyati shunda-ki, ushbu tiplarda o'zgaruvchi e'lon qilsangiz va unga hech narsani 
o'zlashtirmasangiz, u avtomatik ravishda oxiriga o'tdi deb qaraladi. 3-qatordagi iteratorga
qarshi 4-qatordagisini sinab ko'ramiz: ular bir-biriga teng bo'lguncha it o'zgaruvchisini 
smatchga o'zlashtirib chop etamiz, it ni bittaga oshiramiz, va ekranda e-mail manzillarni 
ko'rishimiz mumkin!
2.   MA'LUMOTLAR TIPI (TYPEINFO)
        Shu paytgacha ma'lumotlar tipi deganda butun son va kasrli son bor deb kelgan edik. 
Lekin bu bo'limda maylumotlar tipi tushunchasini yahshiroq ko'rib chiqish kerak 
bo'ladi. Chunki funksiyalar bilan ishlaganda   argument kiritish va qiymat qaytarishga 
to'g'ri keladi.  
    Agar   boshidan  boshlaydigan  bo'lsak,  kompyterda hamma  turdagi  ma'lumotlar  0  va  1
yordamida kodlanadi. Buning sababi shuki, elektr uskunalar uchun ikki holat tabiyi-dir,
tok oqimi bor yoki yo'q, kondensatorda zaryad bor yoki yo'q va hakozo. Demak biz bu
holatlarni  oladigan jihozlarni  bir  quti  deb faraz qilsak, quti ichida yo narsa bo'ladi, yo
narsa   bo'lmaydi.   Mantiqan   buni   biz   bir   yoki   nol   deb   belgilaymiz.   Bu   kabi   faqat   ikki
holatga   ega   bo'lishi   mumkin   bo'lgan   maylumot   birligiga   biz   BIT   deymiz.   Bu   birlik
kichik   bo'lgani   uchun   kompyuterda   bitlar   guruhi   qo'llaniladi.   Bittan   keyingi   birlik   bu
BAYT   (byte).   Baytni   sakkizta   bit   tashkil   etadi.   Demak   bir   bayt   yordamida   biz   256   ta
holatni kodlashimiz mumkin bo'ladi. 256 soni ikkining sakkizinchi darajasiga tengdir.
Bitimiz ikki holatga ega bo'lgani uchun biz kompyuterni ikkili arifmetikaga asoslangan
deymiz.   Ammo   agar   kerak   bo'lsa,   boshqa   sistemaga   asoslangan   mashinalarni   ham
qo'llash   mumkin.   Masalan   uchli   sanoq   sistemasiga   asoslangan   kompyuterlar   bor.
Informatika faniga ko'ra esa, hisoblash mashinasi uchun eng optimal sanoq sistemasi  e 10ga   teng   bo'lar   ekan.   Demak   amaldagi   sistemalar   ham   shu   songa   iloji   borisha   yaqin
bo'lishi kerakdir.  
  C/C++ da baytga asoslangan  tip char dir. char tipi butun son tipida bo'lib, chegaraviy
qiymatlari -128 dan +127 gachadir. Bu tip lotin alifbosi harflarini va y ana qo'shimcha
bir guruh simvollarni kodlashga qulay bo'lgan. Lekin hozirda milliy alifbelarni kodlash
uchun   16   bitlik   UNICODE   qo'llanilmoqda.   U   yordamida   65536   ta   simvolni   ko'rsatish
mumkin. char tipida o'zgaruvchi e'lon qilish uchun dasturda
char g, h = 3, s;
  kabi yozish kerak. O'zgaruvchilar vergul bilan ayriladi. E'lon bilan bir vaqtning o'zida
boshlang'ich   qiymat   ham   berish   imkoni   bor.   Mashina   ichida   baytdan   tashkil   topgan
boshqa kattaliklar ham bor. Ikki baytdan tuzilgan     kattalik so'z (word) deyiladi, unda 16
bit   bo'ladi.   4   ta   bayt   guruhi   esa   ikkili   so'z   (double   word)   bo'ladi.   Bu   birlik   32   bitli
mashimalarda qo'llaniladi. Hozirda qo'llanilmoqda bo'lgan mashinalar asosan 32 bitlidir,
masalan Pentium I/II/III sistemalari. C++ da butun sonlarning ikki tipi bor. Biri char -
uni   ko'rib   chiqdik.   Ikkinchisi   int   dir.   Mashinalarning   arhitekturasi   qanday   kattalikda
bo'lsa, int tipining ham kattakigi huddi shunday bo'ladi. 16 bitlik mashinalarda int 16 bit
edi.   Hozirda   esa   int   ning   uzunligi   32   bitdir.   int   (integer   -   butun   son)   tipi   charga
o'hshaydi. Farqi bir baytdan kattaligidadir. 16 bitli int ning sig'imi -32768 dan +32767
gachadir. 32 bitli int esa -2 147 483 648 dan +2 147 483 647 gacha o'rin egallaydi. Bu
ikki butun son tipidan tashqari C++ da ikki tur vergulli, (nuqtali) yani haqiqiy son tipi
mavjud. Bulardan biri float, hotirada 4 bayt joy egallaydi. Ikkinchisi esa double, 8 bayt
kattalikka   ega.   Bularning   harakteristikalari   quyidagi   jadvalda   berilgan.   Ushbu   tiplar
bilan   ishlaganda   unsigned(ishorasiz,   +/-   siz),   signed   (ishorali)   long   (uzun)   va   short
(qisqa)   sifatlarini   qo'llasa   bo'ladi.   unsigned   va   signed   ni   faqat   butun   son   tiplari   bilan
qo'llasa   bo'ladi.   unsigned   qo'llanganda   sonning   ishorat   biti   bo'lmaydi,   ishorat   biti
sonning kattaligini bildirish uchun qo'llaniladi. Masalan char tipida 8 chi, eng katta bir
odatda   ishorat   bitidir.   Biz   unsigned   char   ch;   desak,   ch   o'zgaruvchimizga   faqat   0   va
musbat   qiymatlarni   berishimiz   mumkin.   Lekin   oddiy   char   [-128;127]   ichida   bo'lsa,
unsigned   char   [0;255]   orasidagi   qiymatlarni   oladi,   chunki   biz   ishorat   biti   ham
qo'llamoqdamiz. Huddi shunday unsigned int da (4 baytli) qiymatlar [0;4 294 467 296]
orasida yotadi.
signed   ni   ishlatib   esa   biz   ochiqchasiga   butun   sonimizning   ishorati   bo'lishi   kerakligini
bildiramiz.   Normalda   agar   signed   yoki   unsigned   qo'yilmasa,   tipimizning   ishorasi
bo'ladi.   long int   bilan qo'llanilganda 16 bitli int 32 ga aylanadi. Bu agar mashina 16 bitli
bo'lsa,   mashina   32   bitli   arhitekturaga   ega   bo'lsa,   int   ning   kattaligi   4   bayligicha
qolaveradi. long double tipi esa 10 bayt joy oladi. Short sifati int bilan qo'llanilganda 32
bit   emas,   16   bit   joy   egallashga   boshlaydi.   Tezlikni   oshirish   maqsadida   kam   joy
egallaydigan   ma'lumot   tiplarini   qo'llash   maqsadga   muofiqdir.   Agar   tipning   nomi
yozilmagan bo'lsa, o'zgaruvchi int tipiga ega deb qabul qilinadi.
  11Ma'lumot                               Sinonimlar               Keng tarqalgan    
tiplarining nomlari                                           harakteristikalari    
 
long double                                                       10 bayt, +/-3.4e-4932...+/-3.4e4932
double                                                                       8 bayt,       +/-1.7e-308...+/-1.7e308
float                                                                               4 bayt,           +/-3.4e-38...+/-3.4e38
unsigned long int                                     unsigned long                          
long int                                                                     long
unsigned int                                                       unsigned
int
unsigned short int                                     unsigned short
short int                                                                     short
unsigned char                      
short
char
      char   va   int   dan tashqari C++ da yana bir necha integral tiplar mavjud. Bulardan biri 
bool tipidir. bool tipi faqat ikki farqli qiymat olishi mumkin. Bittasi true (to'g'ri) 
ikkinchisi false (noto'g'ri). bool tipi mantiqiy arifmetika amallarini bajarganda juda qo'l 
keladi. bool tipi boshqa bir integral tipga asoslangan bo'lishiga qaramasdan (int yoki 
char), yuqoridagi ikki qiymatdan tashqari boshqa qiymat ololmaydi. bool tipi 
o'zgaruvchilari to'g'ri shaklda initsalizatsiya qilinmagan taqdirda, ularning qiymati hato 
ravishda na true va na false bo'lishi mumkin.Yana boshqa bir integral tip bu   wchar_t   dir
(wide char type - keng simvol tipi). U ham ko'pincha boshqa bir butun son tipiga 
asoslanadi - bir baytdan kattaroq bo'lishi kerakligi uchun short int 
qo'llaniladi. wchar_t   simvollar kodlanishida qo'llaniladi. Masalan C++ da UNICODE ni
odatda wchar_t bilan kodlaymiz. Hozirda wchar_t ning kattaligi 16 bit, lekin yuqori 
kattaligi necha bit bo'lishi kerakligi standartda belgilanmagan.   Butun sonlarni C++ da 
bir necha asosda berish mumkin. Hech qanday belgi qo'yilmasdan     yozilgan son o'nlik 
asosda (decimal) deb qabul qilinadi.
Sakkizli asosdagi (octal) sonni berish uchun sondan oldin 0o yoki 0O belgilarini qo'yish
kerak.O'n   oltilik   sistemadagi   (hexadecimal)   sonlar   oldiga   0x   yoki   0X   lar   yoziladi.
Sakkizli   sistemada   qo'llaniladin   raqamlar   to'plami   0,1,2,3,4,5,6   va   7   dir.   O'n   oltilik
asosda   0   dan   9   gacha   sonlar,   10   -   a,   11   -   b,   12   -   c,   13   -   d,   14   -   e   va   15   uchun   f 12qo'llaniladi.   Harflar   katta   bo'lishi   ham   mumkin.   Harflarning   registorining   (katta-
kichikligi) farqi yo'q. Misol beraylik:
 
char d = 10, j = 0o11; // d 10 ga teng, j 9 ga teng.
int f = 0X10;                     // f 16 ga teng        
      Butun son va kasr son tiplaridan tashqari C++ da void (bo'sh, hech narsa) tipi ham 
mavjud. Bu tipning oladigan qiymatlari bo'sh to'plamga tengdir. Void tipidagi ma'lumot 
chala tugallangan hisoblanadi. Boshqa turdagi ma'lumotni void ga keltirish mumkindir. 
Bu tip bilan ishlashni dasturlarimizda ko'rib chiqamiz.
 
MA'LUMOTLAR TIPINI KELTIRISH (DATA CASTING)
        Gohida bir turdagi o'zgaruvchining qiymatini boshqa tipdagi o'zgaruvchiga berish 
kerak bo'ladi. Bu amal ma'lumot tipini keltirish (data type casting) deyiladi. Ko'p 
hollarda bu amal avtomatik ravishda, kompilyator tarafidan bajariladi. Masalan ushbu 
parchani ko'raylik:
  char c = 33;
int k;
k = c;
        Bu yerda k ning sig'imi c nikidan kattaroqdir. Shuning uchun c ning qiymatini k ga 
berishda hech qanday muammo paydo bo'lmaydi. Quyidagi misolni ko'raylik:
  int i = 5;
float f = 9.77;
float result;
  result = f + i;
        C++ ning kompilyatori ikki turdagi o'zgaruvchilar bilan ishlay olmaydi. Shu sababli 
ifodadagi sig'imi kichik bo'lgan o'zgaruvchilar ifodadagi qatnashgan eng katta sig'imga 
o'tqaziladi. Bu ham avtomatik tarzda bajariladi. i o'zgaruvchimiz qiymati 
vaqtinchalik   float   tipidagi o'zgaruvchiga beriladi. Bu vaqtinchalik o'zgaruvchi esa f ga 
qo'shiladi. Chiqqan javob result ga beriladi. Yuqorida ko'rib chiqqanlarimiz kompilyator
tarafidan bajariladi. Bu kabi tip o'zgarishlarini avtomatik konversiya(implicit 
conversion) deymiz. Lekin gohida to'g'ri kelmaydigan tiplarni birga qo'llashga to'g'ri 
keladi. Masalan   float   tipiga double tipni o'tqazish, char ga int va hokazo. Bu hollarda 
ochiq konversiya (explicit conversion) amalini bajarishimiz kerak. Buni bajarishning  13ikki uslubi bor. Birinchisi C da qo'llaniladigan yo'l, ikkinchisi C++ uslubi. C da tipni 
keltirish uchun o'zgaruvchi oldiga kerakli tipni () qavslar ichida yozamiz.
 
int k = 100;
char s;
  s = (char)k;
      Yuqorida k ning qiymatini char tipidagi vaqtinchalik o'zgaruvchiga berildi, keyin s ga
ushbu o'zgaruvchi qiymatini berildi.Bu yerda etibor berilishi kerak bo'lgan narsa shuki,
100   char   ga   ham   to'g'ri   keladi.   Agar   k   ning   qiymati   char   oladigan   qiymattan
kattaroq/kichikroq bo'ladigan bo'lsa, bu hato olib keladi. Shu sababli C dagi tip keltirish
nisbatan havfli hisoblanadi. Lekin albatta bilib qo'llanilsa katta yordam beradi. C++ da
ma'lumotlar   tipini   keltirish   uchun   mahsus   operatorlar   kiritildi.   C   uslubidagi   keltirish
hamma   sharoitda   qo'llanilar   edi.   C++   ning   keltirish   operatorlari   esa   faqat   o'ziga
ajratilgan   funksiyalarni   bajaradi.   Undan   tashqari   ular   C   dagi   keltirishlardan   ko'ra
kuchsizroqdir. Shu sababli hato ehtimoli kamaytirildi. Yana bir afzallik tarafi shundaki,
yangi stildagi keltirish operatorlari tip tekshirishlarini bajarishadi, agar noto'g'ri keltirish
bajarilsa, bu sintaktik hatoga olib keladi.
Ular quyida berilgan:
  static_cast
dynamic_cast
const_cast
reinterpret_cast
  static_cast ni ko'rib chiqaylik.
  int k = 200;
char h;
  h = static_cast<char>(k);
 
    static_cast   dan   keyin   kerakli   tip   nomi   <>   qavslar   ichida   beriladi,   va   tipi   o'zgarishi
kerak   bo'lgan   o'zgaruvchi   ()   qavslar   ichida   parametr   sifatida   beriladi.               Static_cast
kompilyatsiya   davrida   tip   keltirishlarida   qo'llaniladi. dynamic_cast   esa   dastur   ishlash
davrida tip keltirishlari uchun qo'llaniladi. 14const_cast   esa   o'zgaruvchilardan   const   (o'zgarmas)   va   volatile   (o'zgaruvchan,
uchuvchan)   sifatlarini   olib   tashlashda   qo'llaniladi.   Odatda   const   o'zgaruvchining
qiymatini   o'zgartirib   bo'lmaydi.   Ushbu   holda   const_castqo'llaniladi.   reinterpret_cast  
odatiy   bo'lmagan   keltirishlarni   bajarishda   qo'llaniladi   (masalan   void*   ni   int   ga).
reinterpret_cast   o'zgaruvchining   bitlarini   boshqa   ma'noda   qo'llashga   imkon   beredi.   Bu
operator   bilib   ishlatilinishi   kerak.   Ushbu   operatorlar   bilan   keyinroq   yanada   yaqin
tanishamiz.
 
MATEMATIK KUTUBHONA FUNKSIYALARI
        Standart kutubhonaning matematik funksiyalari ko'pgina amallarni bajarishga imkon 
beradi. Biz bu kutubhona misolida funksiyalar bilan ishlashni ko'rib chiqamiz.   Masalan 
bizning dasturimizda quyidagi satr bor bo'lsin:
 
double = k;
int m = 123;
k = sin(m);
  kompilyator uchbu satrni ko'rganida,standart kutubhonadan sin funksiyasini chaqiradi.
Kirish   qiymati   sifatida   m   ni   berdik.   Javob,   yani   funksiyadan   qaytgan   qiymat   k   ga
berildi.Funksiya   agumentlari   o'zgarmas   sonlar   (konstanta)   o'zgaruvchilar,   ifodalar   va
boshqa mos keluvchi qiymat qaytaradigan funksiyalar bo'lishi mumkin. Masalan:
  int g = 49, k = 100;
cout << "4900 ning ildizi -> "<< sqrt( g * k );
  Ekranda:
 
4900 ning ildizi -> 70;
  Matematik funksiyalar aksariyat hollarda double tipidagi qiymat qaytarishadi.Kiruvchi 
argumentning tipi sifatida esa double ga keltirilishi mumkin bo'lgan tip beriladi. Bu 
funksiyalarni ishlatish uchun math.h (yangi ko'rinishda cmath)e'lon faylini include bilan
asosiy dastur tanasiga kiritish kerak.Quyida matematik funksiya-lar kutubhonasining 
bazi bir a'zolarini beraylik. x va y o'zgaruvchilari double tipiga ega.
Funksiya           Aniqlanishi                                                                   Misol
  15ceil(x)             x ni x dan katta yoki unga teng b-n                   ceil(12.6) = 13.0
                          eng kichik butun songacha yahlitlaydi               ceil(-2.4) = -2.0
cos(x)               x ning trigonometrik kosinusi (x radianda)     cos(0.0)       = 1.0
exp(x)               e ning x chi darajasi (eskponetsial f-ya)       exp(1.0)       =     2.71828
                                                                                                                  exp(2.0)       = 7.38906
fabs(x)             x ning absolut qiymati                                             x>0 => abs(x) = x
                                                                                                                  x=0 => abs(x) = 0.0
                                                                                                                  x<0 => abs(x) = -x
floor(x)           x ni x dan kichik bo'lgan eng katta                   floor(4.8) = 4.0
                          butun songacha yahlitlaydi                                     floor(-15.9) = -16.0
fmod(x,y)         x/y ning qoldig'ini kasr son tipida beradi     fmod(7.3,1.7) = 0.5
log(x)               x ning natural lagorifmi (e asosiga ko'ra)     log(2.718282) = 1.0
log10(x)           x ning 10 asosiga ko'ra lagorifmi                       log10(1000.0) = 3.0
pow(x,y)           x ning y chi darajasini beradi                             pow(3,4) = 81.0      
                                                                                                                  pow(16,0.25) = 2
sin(x)               x ning trigonometrik sinusi (x radianda)         sin(0.0)       = 0.0
sqrt(x)             x ning kvadrat ildizi                                               sqrt(625.0) = 25.0
tan(x)               x ning trigonometrik tangensi (x radianda)     tan(0.0) = 0 163. forward_list sinfi.
forward_list sinfining shabloni:
template <class T,
class Allocator = std::allocator<T>
> class forward_list;
forward_list - konteynerdan elementlarni kiritish va olib
tashlash mexanizmini ta'minlaydigan sinf. Tez tasodifiy kirish
qo'llab-quvvatlanmaydi. U bir yo'naltirilgan ro'yxat sifatida
amalga oshiriladi va C tilidagi shunga o'xshash dastur bilan
solishtirganda qo'shimcha xarajatlarga ega emas: std :: list dan
farqli o'laroq, ushbu turdagi konteyner ikki tomonlama
iteratsiyani qo'llab-quvvatlamaydi.
27. forward_list sinfining o’lchamlari va jarayonlari
Nomi
Izoh
merge
Ikkita tartiblangan ro'yxatlarni birlashtirish.
splice_after Elementlarni boshqa forward_listdan ko'chiradi.
remove
remove_if
reverse
unique
sort
Ma'lum belgilarga javob beradigan elementlarni olib
tashlaydi.
Elementlarning tartibini o'zgartiradi.
Ketma-ket takrorlanadigan elementlar o'chiriladi.
Elementlarni tartiblash.
28.
Masala:
Berilgan int turidagi to’plam qiymatlarining 17raqamlari yig’indisini Z to’plamga joylashtiruvchi va
ularni ekranga chiqaruvchi dastur tuzing.
Masalani yechish g‘oyasi:
forward_list konteyneri to’plami yaratiladi.
forward_list ning push_front( ) iteratoridan foydalanib,
A to’plamga qiymatlar o’zlashtiriladi. Z to’plamga esa A
to’plam qiymatlarini raqamlari yig’indisi yoziladi.
29. Dasturi
30. list sinfi
list sinfi shabloni:
template < class T,
class Allocator = std::allocator<T>
> class list;
List - bu konteynerning har qanday pozitsiyasidan elementlarni
tezda kiritish va olib tashlashni qo'llab-quvvatlaydigan sinf. Tez
tasodifiy kirish qo'llab-quvvatlanmaydi. Ikkala bog'langan
ro'yxat sifatida amalga oshiriladi. std::forward_list-dan farqli
o'laroq, ushbu konteyner ikki tomonlama iteratsiyani
ta'minlaydi, shu bilan birga foydalanilgan xotiraga nisbatan
unumli emas. 18                   Foydalanilgan manbalar:
https://en.cppreference.com/w/cpp/regex/
https://www.informit.com/articles/article.aspx?p=2079020#:~:text=The%20new%20C
%2B%2B11,few%20lines%20of%20C%2B%2B%20code.
http://www.cplusplus.com/reference/regex/ECMAScript/

1Mavzu: C++ dasturlash tilining regex, type info va forward_list kutubxonalari funksiyalari bilan ishlash. Reja: 1. regex ning C++ dagi funksiyalari. 2. type info C++ dagi funksiyalari. 3. forward_list C++ dagi funksiyalari.

21. Regular expression va undan C++ da foydalanish Regex berilgan belgilar to'plamini ichidan siz bergan ifoda bo'yicha belgilar to'plamini olish. Unchalik tushunarsiz bo'ldimi? Shoshilmang, hozir uni amaliyotda ko'ramiz va u o'ylaymanki sizga yoqib qoladi :) Oddiy bir misol, sizga gap berilgan, o'sha gap ichidan e-mail manzillarini ko'rsatib berishingiz kerak. Qoyil, siz buni qiynalmasdan bajara olasiz! Lekin qanday? Siz beixtiyor harflar va raqamlar aralashgan ifoda(username) va undan keyin keladigan kuchukcha belgisi va domen yozilgan belgilar to'plamini e-mail manzil deb ko'rsatasiz(masalan , cppcoder24@gmail.com ) va siz e-mail ni topishda o'z qolipingizdan foydalandingiz(<username>@<domen>). Ya'ni e-mail manzilni qanday formada bo'lishini bilasiz. Endi shuni dasturimizga tatbiq qilib ko'ramiz. Agar siz qidirish tizimlaridan, so'zni qidirish va uni boshqasi bilan almashtirish funksiyalaridan, oddiy matn muxarrirlaridan foydalangan bo'lsangiz, demak siz uni amaliyotda ko'rgansiz! Shuningdek, regex dan parollarni kuchli-kuchsiz tuzilganini tekshirishda ham ishlatishadi. Regex da qidirish belgilardan iborat ifoda yordamida amalga oshiriladi, bu ifoda qolip vazifasini bajaradi. C++ da kod yozib ko'rganlar juda yaxshi bilishadi, unda ma'lumotlarni to'g'ri ekanligini tahlil qilish bir muncha murakkab jarayon. Masalan, foydalanuvchidan son kiritishni so'radingiz, kiritiladigan narsani siz string da olib, uni haqiqatda sonmi-yo'qmi bilmoqchisiz. Har bir dasturchi bu jarayonda o'zining tekshirish algoritmini yozib chiqishga majbur bo'ladi. Lekin C++ 11 da regex kirib keldi va bu endi muammo emas! C++ 11 ECMAScript, awk, grep va yana bir nechta regular expression grammatikasini qo'llab-quvvatlaydi, biz ECMAScript sintaksisini ko'rib o'tamiz. Regex kutubxonasini kodimizda import qilamiz: #include <regex>bu orqali biz regex dan kodimizda foydalana olishimiz mumkin. Lekin bu C++11 va undan yuqorida ishlaydi. DIQQAT! Namunadagi kodlar main funksiyasi ichiga yoziladi: #include <iostream> #include <regex> using namespace std; int main()

3{ Endi c++ da kod yozib, uni sinab ko'rish uchun biror muhitni oching :)C++ 11 ni sozlash . Sozlashni Code::Blocks muhitida ko'rib o'tamiz. Birorta konsol proyekt ochib, yuqorida turgan paneldan Settings->Compiler ni tanlaymiz. Va uni quyidagi rasmdagidek sozlab olamiz: Ok ni bosamiz. Tayyor. Dev muhitini ishlatadiganlar diqqatiga. Yuqoridagi paneldan Tools->Compiler Options ga kiramiz, bizga kompilyator sozlamalari oynasi ochiladi:

4Va rasmda ko'rsatilgan bo'limdan ISO C++ 11 ni tanlab, OK ni bosamiz, Tayyor Regex da ifodalar tuzish. Regex da belgilar to'plamini ichidan o'zimizga kerakli qismini olish uchun ifoda tuzishni o'rganib chiqishimiz kerak. Ifodani belgilar yordamida tuzamiz. Biz tuzgan ifoda o'ziga mosini o'sha belgilar to'plami ichidan topib beradi. Ifodani belgilar to'plamidan tuzamiz, o'z navbatida belgilarimiz oddiy va maxsus(metacharacter) bo'ladi. Oddiy belgilardan foydalansak, ular berilgan matn ichidan o'ziga o'xshaganlarni topib beradi. Maxsus belgilar biroz boshqacharoq ishlaydi. Biz ifodani tuzayotganda uni Raw String qilib tuzganimiz ma'qul. Nima ekanligini keyinroq tushuntirib beraman. Maqolani shu joyiga kelganda, mavzudan biroz chetga chiqib, raw string ni ozroq tushuntirib bersam, Raw string o'zi anglatib turgandek "chala" string. Uni oddiy string tipida qo'shtirnoqlarni

5boshlanishiga R harfini qo'yib hosil qilamiz, qo'shtirnoq ochilgandan keyin ochiq qavs va yopilishidan oldin yopiq qavs qo'yish shart. Keling, namuna ko'raylik: string s="Salom!\n Havo ajoyib-a?!"; string s1=R"(Salom!\n Havo ajoyib-a?!)"; cout<<s<<endl; cout<<"=====\n"; cout<<s1<<endl;Natija: Salom!   Havo ajoyib-a?! ===== Salom!\n  Havo  ajoyib-a?! Ko'rib turganingizdek, \n da enter tashlanishi kerak edi, raw string esa shunaqa joylarini inkor qila oladi \ - bu shunchaki backslash va uni raw stringda shunchaki ishlatish mumkin, stringda backslash ni ishlatish uchun \\ yozishimiz kerak. Ifodamiz albatta regex tipida bo'lishi kerak. Ifoda yozishdan oldin ba'zi metacharacterlar(maxsus belgilar) bilan tanishib chiqsak: . - nuqta har qanday belgini topib beradi \d - har qanday raqamni topib beradi(decimal). Ushbu metacharacterga ekvivalent: [[:digit:]] \D - \d ni teskarisi, raqam bo'lmagan belgini topib beradi. Ushbu metacharacterga ekvivalent [^[:digit]] \s - bo'shliqni topadi(space, tab) \S - \s ni teskarisi. \w - alphanumeric(harf yoki raqam) va tagchiziq belgisini topadi. \W - \w ni teskarisi. + biror x belgidan keyin ushbu belgini qo'yish orqali ushbu x belgi 1 yoki ko'p marta qatnashishi kerakligini bildirgan bo'lamiz. | - or(yoki), buni biz 2 ta belgi orasiga qo'llash orqali ulardan biri kelganini aniqlashimiz mumkin bo'ladi. [belgilar to'plami] - ushbu burchakli qavslar ichida belgilar kategoriyasini kiritamiz. Ichidagi belgilardan duch kelganini topadi. Masalan, agar [abc] desak, unda a, b, yoki c belgisini topadi.