logo

Istisnoli holatlar va ular bilan ishlash

Yuklangan vaqt:

08.08.2023

Ko'chirishlar soni:

0

Hajmi:

149.8681640625 KB
Mavzu: Istisnoli holatlar va ular bilan ishlash
Reja:
1. Istisnoli holatlarni dasturlash. Istisnoli holatlar sinf sifatida. 
2. Qt dasturlash muhitida istisnoli holatlarni yaratish va ushlash.
  1. Istisnoli holatlarni dasturlash. Istisnoli holatlar sinf sifatida. 
Istisnolarni qayta ishlash
Istisno   holat   (inglizcha   "exception")   yoki   istisno   -   bu   dasturda   ro'y   bergan
alohida yoki g'ayritabiiy narsa.  Ko'pincha, istisno bu har  qanday xato yuz beradi,
lekin   bu   shart   emas:   masalan,   nostandart   vaziyatlar   to'plami   yoki   atipik   ishlov
berishni talab qiladigan vaziyat bo'lishi mumkin.
Agar   dasturda   hal   qilib   bo'lmaydigan   vaziyat   yuzaga   kelsa   (yoki   dastur
foydalanadigan   kutubxona   funktsiyasida),   istisno   bekor   qilinadi.   Bu   shuni
anglatadiki, dasturni  odatiy davom  ettirish o'rniga, boshqarish  ushbu istisnoni  hal
qilish   uchun   maxsus   ishlab   chiqilgan   algoritmning   boshqa   bo'limiga   o'tkaziladi.
Dasturning ushbu boshqa tarmog'i - istisnosiz ishlov beruvchi - dasturni shunchaki
to'xtatib qo'yishi mumkin yoki dastur ishlashni davom ettirishi uchun biror narsani
o'zgartirishi   mumkin.   Bundan   tashqari,   kutubxonada   biron   bir   istisno   ro'y   bersa
ham,   istisno   ishlov   beruvchisi   ushbu   kutubxonadan   foydalanadigan   dasturda   -
kodning   ma'lum   bir   nostandart   vaziyatni   to'g'ridan-to'g'ri   keltirib   chiqaradigan
qismida va shuning uchun uni qayta ishlashda yaxshiroq yordam berishi mumkin.
Bitta kod blokiga tashlangan istisno boshqa blokda joylashgan kerakli ishlov
beruvchini   topishi   uchun,   istisno   indikator   tashlanganida   tashlanadi.   Indikator   bu
ma'lum bir turdagi ob'ekt yoki o'zgaruvchidir. Agar istisno bekor qilinsa, tavsifida
kutilayotgan   ko'rsatkichning   bir   xil   turi   ko'rsatilgan   ishlov   beruvchi   tanlanadi.
Ishlov   beruvchilar   istisnolarni   indikatorning   ma'lumot   turlari   bo'yicha   ajratadilar
va shuning uchun eng ko'p uchraydigan holatlarda indikator sifatida ushbu maqsad
uchun maxsus berilgan muayyan sinf ob'ekti ko'rsatiladi.
Istisno vaziyatlarni dasturlash.
Istisnolardan   foydalanmoqchi   bo'lgan   dasturchi   maxsus   try{}   blokda   istisno
yuzaga kelishi mumkin bo'lgan kodga murojaat qilishi kerak. Ushbu blokdan so'ng,
istisnosiz ishlaydigan kod joylashtirilgan catch() {} bloki kerak. Masalan, agar f()
funktsiyasining   ba'zi   bir   qismlarida   istisno   ro'y   berishi   mumkin   bo'lsa,   uni
boshqarish uchun quyidagi qurilishni yozishingiz kerak bo'ladi:
f ( ) {
//   agar mos keladigan vaziyat yuzaga kelsa, istisno yaratiladi
if (.... ) throw  индикатор ;
.....
}
.....
try
{
//istisnoli vaziyat yuzaga keltirishi mumkin bo’lgan dastur kodi:
f ( );
}
catch ( индикатор )
{
//istisnoli holatni qayta ishlaymiz
.....
}
Istisno   ishlov   beruvchisi   har   doim   try{}   blokidan   keyin   darhol   amal   qiladi.
Tutib   bo'lgandan   keyin   catch   blok   ishlov   berayotgan   istisnoning   ko'rsatkichini
ko'rsatadi.   Istisno   tashlash   uchun   siz   maxsus   otishni   ishlatishingiz   kerak,   undan
keyin indikator kerak.
Yuqorida   aytib   o'tilganidek,   ishlov   beruvchiga   qo'shimcha   ma'lumotlarni
berish   uchun,   siz   catch()   blokida   ma'lumotlar   turini   emas,   balki   o'zgaruvchini
qabul   qilishingiz   kerak.   Istisno   tashlamasdan   oldin,   siz   uni   ma'lum   ma'lumotlar
bilan   boshlashingiz   va   keyin   ushbu   ma'lumotlarni   ishlov   beruvchida   o'qishingiz
mumkin.
Xatolarni qayta ishlash usullari
Shunday   qilib,   xato   faqat   funktsiyani   lokal   ravishda   hal   qila   olmaydigan
muammolar   sifatida   tushunilishi   kerak.   Ushbu   holatlarda,   funktsiya   biron   bir tarzda   muammoni   chaqiruvchini   xabardor   qilishi   kerak,   buning   turli   xil   usullari
mavjud:
xato   kodini   qaytarish.   Masalan,   agar   tarmoq   orqali   xabar   yuborish   paytida
ulanish uzilgan bo'lsa,  yuborish funktsiyasi  qaytarilishi  mumkin va agar  yuborish
muvaffaqiyatli bo'lsa, nolga teng bo'ladi;
bila   turib   noto'g'ri   natijani   qaytarish.   Masalan,   xatolik   yuz   bergan   taqdirda
(xotirani   ajratib   bo'lmaydigan)   xotirani   ajratadigan   malloc   funktsiyasi   nolni
qaytaradi, boshqa hollarda - ajratilgan qismning boshlang'ich manzili;
har qanday yaroqli qiymatni qaytarish va global xato bayrog'ini o'rnatish (C +
+ da, global o'zgaruvchini ishlatishingiz mumkin buning uchun.
avariya   holatida   dasturni   tugatish(C   ++   da,   bu   tugatish   yoki   chiqish
funktsiyalari yordamida amalga oshiriladi);
istisnoni ishlab chiqish;
Albatta, o'chirishdan tashqari, siz har doim vaziyatning tavsifini jurnal fayliga
yozishingiz mumkin (Cer + oqimi) va uni namoyish qilishingiz mumkin.
G'ayritabiiy   tugatish   xato   bilan   ishlashning   eng   yomon   usuli   hisoblanadi.
dasturchi aslida biron bir narsani tuzatishga qodir emasligiga ishora qiladi.
Buyruqlar   ketma-ketligi   nuqtai   nazaridan   xato   kodini   qaytarish   noto'g'ri
qiymatni qaytarish yoki global ob'ektga xato bayrog'ini o'rnatishdan farq qilmaydi.
Ushbu   barcha   holatlarda,   kirish   ma'lumotlarini   to'g'ri   ishlashni   bilmaydigan
funktsiya   ushbu   majburiyatlarni   to'g'ridan-to'g'ri   uni   chaqirgan   kodga   o'tkazadi.
Ko'pincha bu yaxshi ishlaydi, ammo:
agar murojaat kodi xato kodini qayta ishlamasa (oxir-oqibat, buni qilish shart
emas),   u   hisob-kitoblarni   davom   ettiradi,   ammo   noto'g'ri   ma'lumotlar   bilan.
Bunday vaziyat darhol yuzaga chiqmaydi, chunki siz noto'g'ri natija olishingiz yoki
butunlay boshqa joydan favqulodda to'xtash joyini olishingiz mumkin. Masalan, Qt
kutubxonasida satrni butun songa aylantirish funktsiyasi mavjud:
int QString::toInt(bool * ok = 0, int base = 10) const Xatolik yuz berganda, u nolni qaytaradi va ok daliliga noto'g'ri tayinlaydi (bu
ixtiyoriy).   Agar   bizning   kodimiz   bu   funktsiyani   butun   son   bo'lmagan   satr   uchun
chaqirsa, u nolni natija sifatida qabul qiladi (juda to'g'ri, ammo noto'g'ri qiymat);
Xatoni   to'g'ridan-to'g'ri   funktsiyani   chaqiradigan   kodda   to'g'ri   hal   qilish   har
doim ham mumkin emas. Natijada quyidagicha narsa bo'ladi:
bool foo(QString str) {
  bool ok;
  string.toInt(&ok);
  if (false == ok) {
    return false;  }
  // ... some actions
}
bool bar() {
  QString str;
  // ... some actions
  if (false == foo(str)) 
    return fasle;
  }}
Istisno sinfi.
                      C   ++   standart   kutubxonasida   stdexcept   sarlavhasi   faylida  e'lon   qilingan
standart   istisno   ko'rsatkichlari   sinflarining   ierarxiyasi   mavjud.   Ushbu
ko'rsatkichlardan o'zingizning dasturingizda foydalanish mumkin.
Har bir indikator sinfining maqsadi jadvalda keltirilgan. 2. Qt dasturlash muhitida istisnoli holatlarni yaratish va ushlash.
Istisnoli   vaziyatlar   dastur   algoritmining   ba'zi   xatti-harakatlari   to'g'ri
bajarilmagan   hollarda   yuzaga   kelishi   mumkin.   Masalan,   mavjud   bo'lmagan   qator
indeksida murojaat ro'y berdi, o'qish uchun ochilgan fayl mavjud emas va hokazo.
Bunday   holatlarda   sizning   dasturingiz   "muvozanatini"   yo'qotmasligi   va   ishlashni
davom   ettirishi   uchun,   ushbu   vaziyatlarni   hisobga   olgan   holda,   sizni   ushlab
turishga   imkon   beradigan   istisnolar   kerak   bo'ladi.   Shunga   o'xshash   vaziyatlarni
tahlil qiling va ishlang. Оператор try...catch
Ushbu bayonot rejadan tashqari xatolarga ega bo'lishi mumkin bo'lgan alohida
harakatlar uchun xizmat qiladi, keyinchalik ularni tutib olish qismida bajariladigan
tashlab   ketilgan   istisnolarni   ushlash   imkoniyati   mavjud.   Umuman   olganda,   try   ...
catch iborasi quyidagicha:
try {
shubxali dastur kodi
}
catch (xato) {
xatoni qayta ishlash amallari
}
Shunday   qilib,   sinash   tanasida   ba'zi   "shubhali"   harakatlar   mavjud   bo'lib,
ularning   bajarilishi   xatoga   olib   kelishi   mumkin.   Agar   bu   sodir   bo'lsa,   uni
keyinchalik qayta ishlash uchun tutib olish qismiga o'tish amalga oshiriladi. Faylni
ochish   misolidan   foydalanib,   istisnolarni   qo'lga   olish   va   ishlov   berish   misolini
ko'rib   chiqamiz.   Aytaylik,   bizda   maxsus   fayl   bor.   Bizning   holda,   biz   faqat   xato
kodini ko'rsatamiz va faylni yopamiz.
var file = new File("file.dat");
try {
file.open(File.ReadOnly);
}
catch(e) {
print("Code error:" + e);
}
Qt   o'zi   istisnolarni   ishlab   chiqarmaydi.   Buning   o'rniga   xato   kodlari
qo'llaniladi.   Bundan   tashqari,   ba'zi   sinflar   foydalanuvchiga   ko'rsatilishi   kerak bo'lgan   xato   xabarlarini   oladi,   masalan   QIODevice   ::errorString   ()   yoki
QSqlQuery::lastError().   Buning   tarixiy   va   amaliy   sabablari   bor   -   istisnolardan
foydalanish kutubxonaning hajmini 20% ga oshirishi mumkin.
Qt-ning konteyner sinflari odatda istisno-betaraf. Ular foydalanuvchi o'zlariga
tegishli   bo'lgan   T   turida   yuzaga   keladigan   har   qanday   istisnoni   ichki   holatini
saqlab qolishadi.
Masalan:
QList<QString> list;
 ...
 try {
     list.append("hello");
 } catch (...) {
 }
Ushbu   qoidaning   istisnolari   bu   vazifani   bajarish   yoki   nusxa   ko'chirish
konstruktsiyalarida   istisnolarni   chiqarib   yuboradigan   turdagi   konteynerlardir.
Ushbu   turlar   uchun   qiymatni   qaytarish   uchun   konteynerni   o'zgartiradigan
funktsiyalar foydalanish uchun xavfli:
MyType s = list.takeAt(2);
Agar  s-ga tayinlash paytida  istisno yuzaga  kelsa,  2-indeksdagi  qiymat  allaqachon
idishdan olib tashlangan, ammo s-ga hali tayinlanmagan. U tiklanish imkoniyatisiz
yo'qoladi.Buni yozishning to'g'ri usuli:
MyType s = list.at(2);
 list.removeAt(2);
                Agar   topshiriq  istisno   qilsa,   konteyner   hali   ham   qiymatni   o'z   ichiga   oladi,
hech qanday ma'lumot yo'qoladi.
Shuni   yodda   tutingki,   aniq   Qt   sinflari   ularning   tayinlash   bayonotlarida   istisno
qilmaydi   yoki   nusxa   ko'chiruvchi   konstruktorlarga   berilmaydi,   shuning   uchun
yuqoridagi cheklov qo'llanilmaydi.
Istisnodan keyin tiklanish        Hozirgi vaqtda Qt-ga tashlangan istisnolardan qutqarish uchun yagona qo'llab-
quvvatlanadigan foydalanish holati (masalan, xotira etishmasligi tufayli) hodisadan
chiqib ketish va dasturdan chiqishdan oldin bir oz tozalash kerak.
Odatdagi foydalanish holati:
QApplication app(argc, argv);
 ...
 try {
     app.exec();
 } catch (const std::bad_alloc &) {
      // прибираемся здесь, например, сохраняем сессию
     // и закрываем все конфигурационные файлы.
      return  0; // завершаем приложение
 }
          Istisno   bekor   qilinganidan   so ' ng ,  oyna   serveriga   ulanish   allaqachon   yopiq  
bo ' lishi   mumkin .  Istisno aniqlanganidan keyin GUI funktsiyasini chaqirish xavfli.
void func(int i){
if(i==0)throw(<about_error>);}
int main(){
try{
func(0);}
catch(...){ // }
return 0;
}
Throw operatori
Chiqarish bayoni bilan siz o'zingizning istisnolaringizni keyinroq ularni sinab
ko'rish ... qo'lga olish uchun topshirishingiz mumkin. Istisno raqam, satr yoki hatto
o'z sinfining ob'ekti bo'lishi mumkin. Umuman olganda istisno qilish quyidagicha:
        throw error;            Foydalanilgan ea dabiyotlar ro’yxati
1. Sh.A.Nazirov, R.V.Qobulov, M.R.Babajanov «C va C++ TILI»
2. Informatika fanidan o’quv qo’llanma //TATU 489 b. Toshkent, 2012.
3. C/C++.   Программирование   на   языке   высокого   уровня   /   Т.   А.
Павловская. — СПб.:Питер, 2003. —461 с: ил.
4. Программирование на языке С++ в среде Qt Creator:
5. / Е. Р. Алексеев, Г. Г. Злобин, Д. А. Костюк,О. В. Чеснокова,
6. А. С. Чмыхало — М. : ALT Linux, 2015. — 448 с.
7. Жасмин   Бланшет,   Марк   Саммерфилд   Qt   4:Программирование   GUI   на
C++
8. М.Шлее, Qt 5.10. Профессиональное программирование на С++. - СПб.:
БХВ-Петербург, 2018. - 1072 с.

Mavzu: Istisnoli holatlar va ular bilan ishlash Reja: 1. Istisnoli holatlarni dasturlash. Istisnoli holatlar sinf sifatida. 2. Qt dasturlash muhitida istisnoli holatlarni yaratish va ushlash.

1. Istisnoli holatlarni dasturlash. Istisnoli holatlar sinf sifatida. Istisnolarni qayta ishlash Istisno holat (inglizcha "exception") yoki istisno - bu dasturda ro'y bergan alohida yoki g'ayritabiiy narsa. Ko'pincha, istisno bu har qanday xato yuz beradi, lekin bu shart emas: masalan, nostandart vaziyatlar to'plami yoki atipik ishlov berishni talab qiladigan vaziyat bo'lishi mumkin. Agar dasturda hal qilib bo'lmaydigan vaziyat yuzaga kelsa (yoki dastur foydalanadigan kutubxona funktsiyasida), istisno bekor qilinadi. Bu shuni anglatadiki, dasturni odatiy davom ettirish o'rniga, boshqarish ushbu istisnoni hal qilish uchun maxsus ishlab chiqilgan algoritmning boshqa bo'limiga o'tkaziladi. Dasturning ushbu boshqa tarmog'i - istisnosiz ishlov beruvchi - dasturni shunchaki to'xtatib qo'yishi mumkin yoki dastur ishlashni davom ettirishi uchun biror narsani o'zgartirishi mumkin. Bundan tashqari, kutubxonada biron bir istisno ro'y bersa ham, istisno ishlov beruvchisi ushbu kutubxonadan foydalanadigan dasturda - kodning ma'lum bir nostandart vaziyatni to'g'ridan-to'g'ri keltirib chiqaradigan qismida va shuning uchun uni qayta ishlashda yaxshiroq yordam berishi mumkin. Bitta kod blokiga tashlangan istisno boshqa blokda joylashgan kerakli ishlov beruvchini topishi uchun, istisno indikator tashlanganida tashlanadi. Indikator bu ma'lum bir turdagi ob'ekt yoki o'zgaruvchidir. Agar istisno bekor qilinsa, tavsifida kutilayotgan ko'rsatkichning bir xil turi ko'rsatilgan ishlov beruvchi tanlanadi. Ishlov beruvchilar istisnolarni indikatorning ma'lumot turlari bo'yicha ajratadilar va shuning uchun eng ko'p uchraydigan holatlarda indikator sifatida ushbu maqsad uchun maxsus berilgan muayyan sinf ob'ekti ko'rsatiladi. Istisno vaziyatlarni dasturlash. Istisnolardan foydalanmoqchi bo'lgan dasturchi maxsus try{} blokda istisno yuzaga kelishi mumkin bo'lgan kodga murojaat qilishi kerak. Ushbu blokdan so'ng, istisnosiz ishlaydigan kod joylashtirilgan catch() {} bloki kerak. Masalan, agar f() funktsiyasining ba'zi bir qismlarida istisno ro'y berishi mumkin bo'lsa, uni boshqarish uchun quyidagi qurilishni yozishingiz kerak bo'ladi: f ( )

{ // agar mos keladigan vaziyat yuzaga kelsa, istisno yaratiladi if (.... ) throw индикатор ; ..... } ..... try { //istisnoli vaziyat yuzaga keltirishi mumkin bo’lgan dastur kodi: f ( ); } catch ( индикатор ) { //istisnoli holatni qayta ishlaymiz ..... } Istisno ishlov beruvchisi har doim try{} blokidan keyin darhol amal qiladi. Tutib bo'lgandan keyin catch blok ishlov berayotgan istisnoning ko'rsatkichini ko'rsatadi. Istisno tashlash uchun siz maxsus otishni ishlatishingiz kerak, undan keyin indikator kerak. Yuqorida aytib o'tilganidek, ishlov beruvchiga qo'shimcha ma'lumotlarni berish uchun, siz catch() blokida ma'lumotlar turini emas, balki o'zgaruvchini qabul qilishingiz kerak. Istisno tashlamasdan oldin, siz uni ma'lum ma'lumotlar bilan boshlashingiz va keyin ushbu ma'lumotlarni ishlov beruvchida o'qishingiz mumkin. Xatolarni qayta ishlash usullari Shunday qilib, xato faqat funktsiyani lokal ravishda hal qila olmaydigan muammolar sifatida tushunilishi kerak. Ushbu holatlarda, funktsiya biron bir

tarzda muammoni chaqiruvchini xabardor qilishi kerak, buning turli xil usullari mavjud: xato kodini qaytarish. Masalan, agar tarmoq orqali xabar yuborish paytida ulanish uzilgan bo'lsa, yuborish funktsiyasi qaytarilishi mumkin va agar yuborish muvaffaqiyatli bo'lsa, nolga teng bo'ladi; bila turib noto'g'ri natijani qaytarish. Masalan, xatolik yuz bergan taqdirda (xotirani ajratib bo'lmaydigan) xotirani ajratadigan malloc funktsiyasi nolni qaytaradi, boshqa hollarda - ajratilgan qismning boshlang'ich manzili; har qanday yaroqli qiymatni qaytarish va global xato bayrog'ini o'rnatish (C + + da, global o'zgaruvchini ishlatishingiz mumkin buning uchun. avariya holatida dasturni tugatish(C ++ da, bu tugatish yoki chiqish funktsiyalari yordamida amalga oshiriladi); istisnoni ishlab chiqish; Albatta, o'chirishdan tashqari, siz har doim vaziyatning tavsifini jurnal fayliga yozishingiz mumkin (Cer + oqimi) va uni namoyish qilishingiz mumkin. G'ayritabiiy tugatish xato bilan ishlashning eng yomon usuli hisoblanadi. dasturchi aslida biron bir narsani tuzatishga qodir emasligiga ishora qiladi. Buyruqlar ketma-ketligi nuqtai nazaridan xato kodini qaytarish noto'g'ri qiymatni qaytarish yoki global ob'ektga xato bayrog'ini o'rnatishdan farq qilmaydi. Ushbu barcha holatlarda, kirish ma'lumotlarini to'g'ri ishlashni bilmaydigan funktsiya ushbu majburiyatlarni to'g'ridan-to'g'ri uni chaqirgan kodga o'tkazadi. Ko'pincha bu yaxshi ishlaydi, ammo: agar murojaat kodi xato kodini qayta ishlamasa (oxir-oqibat, buni qilish shart emas), u hisob-kitoblarni davom ettiradi, ammo noto'g'ri ma'lumotlar bilan. Bunday vaziyat darhol yuzaga chiqmaydi, chunki siz noto'g'ri natija olishingiz yoki butunlay boshqa joydan favqulodda to'xtash joyini olishingiz mumkin. Masalan, Qt kutubxonasida satrni butun songa aylantirish funktsiyasi mavjud: int QString::toInt(bool * ok = 0, int base = 10) const

Xatolik yuz berganda, u nolni qaytaradi va ok daliliga noto'g'ri tayinlaydi (bu ixtiyoriy). Agar bizning kodimiz bu funktsiyani butun son bo'lmagan satr uchun chaqirsa, u nolni natija sifatida qabul qiladi (juda to'g'ri, ammo noto'g'ri qiymat); Xatoni to'g'ridan-to'g'ri funktsiyani chaqiradigan kodda to'g'ri hal qilish har doim ham mumkin emas. Natijada quyidagicha narsa bo'ladi: bool foo(QString str) { bool ok; string.toInt(&ok); if (false == ok) { return false; } // ... some actions } bool bar() { QString str; // ... some actions if (false == foo(str)) return fasle; }} Istisno sinfi. C ++ standart kutubxonasida stdexcept sarlavhasi faylida e'lon qilingan standart istisno ko'rsatkichlari sinflarining ierarxiyasi mavjud. Ushbu ko'rsatkichlardan o'zingizning dasturingizda foydalanish mumkin. Har bir indikator sinfining maqsadi jadvalda keltirilgan.