O’ZBEKISTON RESPUBLIKASI OLIY VA O’RTA MAXSUS TA’LIM VAZIRLIGI NAMANGAN DAVLAT UNIVERSITETI X.E.XOLMIRZAYEV, M.N.IKROMOVA, M.M.BAHROMOVA ALGORITMIK TILLAR VA DASTURLASH O’QUV QO’LLANMA 5130200- Amaliy matematika yo’nalishi talabalari uchun Namangan 2022 Algoritmik tillar va dasturlash. Ma’ruza mashg’ulotlari uchun o’quv qo’llanma. X.E.Xolmirzayev, M.N.Ikromova, M.M.Bahromova Annotatsiya Algoritmik tillar va dasturlash o‘quv bakalavriat ta’lim yo’nalishi talabalari qo‘llanmasi Amaliy matematika uchun mo‘ljallangan bo‘lib, asosiy maqsadi-tinglovchilarga «Algoritmik tillar va dasturlash» fani doirasida berilgan mavzularni mustaqil o’zlashtirishga, C# dasturlash tili bo’yicha bilimlarini mustahkamlashga qaratilgan. Аннотация Данное учебное пособие предназначено студентам бакалавриата направления Прикладная математика, пособие помогает студентам самостоятельному усвоению материала по курсу «Алгоритмический язык и программирование», а также укреплять знания по языку программирования С#. Annotation This textbook is intended for undergraduate students of Applied Mathematics, the manual helps students to independently assimilate the material on the course "Algorithmic language and programming", as well as strengthen their knowledge of the C# programming language. Taqrizchilar: S.S.Beknazarova – Muhammad Al-Xorazmiy nomidagi TATU «Audiovisual texnologiyalar» kafedrasi professori, t.f.d., professor. A.Imomov – NamDU «Informatika» kafedrasi dotsenti, f.-m.f.n., dotsent . Mundarija Kirish ......................................................................................................................... 3 1-Ma`ruza: Dasturlash tillari ..................................................................................... 6 2-Ma`ruza: C# va .Net Core platformasi. C# dasturlash tilining tuzilishi. ............. 13 3-Ma’ruza: Identifikatorlar, literallar, o‘zgaruvchilar va berilganlar turlari. .......... 18 4-Ma`ruza: C# tilining amallari. Consoleda kiritish-chiqarish. .............................. 27 5-Ma’ruza: Turni boshqa turga keltirish. ................................................................ 46 6-Ma`ruza: Shart operatorlari. ................................................................................. 52 7-Ma`ruza: Takrorlash operatorlari. ........................................................................ 65 8-Ma`ruza: Massivlar. ............................................................................................. 76 9-Ma`ruza: Satrlar. .................................................................................................. 97 10-Ma’ruza. Metodlar............................................................................................ 116 11-Ma’ruza. Metodning massivli parametrlari va params kalit so`zi ................... 123 12-Ma’ruza. Rekursiv va qayta yuklanuvchi metodlar ......................................... 127 13-Mavzu: Qiymatlar turlari va havola turlar ....................................................... 136 Foydalanilgan adabiyotlar ..................................................................................... 146 Kirish Raqamli texnologiyalar shu qadar shiddat bilan rivojlanmoqdaki, inson turmush tarzi va hatto tafakkurini ham butunlay o’zgartirib yubormoqda. Endilikda, bu texnologiyalarni kundalik ishlarda, ish o’rnida va ishlab chiqarishda qo’llanilishi insoniyatni to’rtinchi sanoat inqilobiga olib keldi. Bu sanoat inqilobi ishlab chiqarishni aqlli tizimlar, sun’iy intellekt, kiberfizik texnologiyalarga asoslangan butunlay avtomatlashtirilgan tizimga o’tish deganidir. Ushbu sanoat inqilobining mahsuli bo`lgan texnologiyalar raqamli iqtisodiyotni ham rivojlantirishga asos bo`lib hisoblanadi. Rivojlangan raqamli iqtisodiyot esa, o’z navbatida davlat taraqqiyotini belgilab beradi. O’z taraqqiyot yo’lini tanlagan jamiyatimiz uchun raqamli bilimlarga, tafakkurga ega, strategik fikrlay oladigan [1], zamonaviy bilim va tajribalar, milliy va umumbashariy qadriyatlar asosida mustaqil va mantiqiy fikrlaydigan yoshlarni tarbiyalash [2] ustuvor yo‘nalishlardan biridir. Raqamli dunyo talablariga javob bera oladigan yoshlar qanday bilim va malakalarga ega bo’lishi kerak degan masala butun dunyo oldidagi dolzarb masaladir, chunki, jahonda raqamli texnologiyalardan nafaqat foydalanuvchi, balki ishlab chiqaruvchi tomonidan ham yuqori malakali mutaxassislarga talab juda katta. Ko‘pchilik ilmiy adabiyotlarning tahliliga, shuningdek ilg‘or ta’lim tizimlari va xalqaro tashkilotlari(YUNESKO, IXRT, Jahon banki) fikriga ko’ra XXI asr insoni uchun ijodiy tafakkur, tanqidiy tafakkur, mantiqiy tafakkur, muammolarni hal etish, hamkorlikda ishlash kabi malakalar zarur ekanligini ko‘rsatmoqda. “Xo’sh qanday qilib ushbu barcha malaka va kompetentsiyalarni shakllantirish mumkin”degan savol uyg’onadi. Yana jahonda olib borilayotgan ishlarni o’rganish natijasida ularni bir tushuncha “Compyutation thinking”-ingliz tilida, “Вычислительное мышление” rus tilidagi atama bilan bog’liqligi ma’lum bo’ldi. Compyutation thinking fanga birinchi kompyuterlar yaratilishi davridan “Algorithmik thinking”algoritmik tafakkur, keyinroq sun’iy intellekt asoschilaridan biri S.Papert tomonidan kiritilgan Protsessual tafakkur atamasi bilan ma’lum bo’lgan. Protsessual tafakkurni S.Papert quyidagicha ta’riflagan: «Protsessual tafakkur protseduralarni ishlab chiqish, taqdim etish, sinovdan o‘tkazish va otladka qilishdan iborat qadamli ko‘rsatmalarni o‘z ichiga oladi va bunday qadamli ko‘rsatmalar har biri formal shaklda tarjima qilinib, maxsus kompyuter yoki avtomat qurilmasi tomonidan bajariladi». Lekin bu tushuncha tor doirada qolib ketgan va 2006 yilga kelib J.Ving tomonidan “Compyutation thinking” atamasi bilan butun dunyo olimlarini diqqatiga sazovor bo’lgan. Uning ta’rificha, Raqamli tafakkur - tegishli soha mutaxasisi yoki kompyuter tomonidan qulay shaklda qo‘yilgan muammo va uning mumkin bo‘lgan yechimlarini hal etishga qaratilgan tafakkur jarayoni»[11] Ma’lum vaqt o‘tib, 2011 yilda J.Ving kelgusi tadqiqotlar asosida yangicha ta’rif beradi: «Raqamli tafakkur muammolarni shakllantirish, ularni yechish, muammolar yechimini axborotni qayta ishlovchi vositalar hal eta oladigan shaklda tasvirlashda ishtirok etuvchi tafakkur jarayoni». Ta’riflardan ko’rinib turibdiki, J.Ving tomonidan tushunchaga 2011 yil berilgan ta’rif bir muncha kengaygan. Hozirda ushbu tushuncha turli soha mutaxasislari, xususan, AT sohasi mutaxassislarini, pedagog va psixologlarni qiziqtirib kelmoqda va ular bu tushunchaga o’zlarini ta’riflarini berib kelmoqdalarki, haligacha yagona ta’rifi mavjud emas. Lekin hozirda olib borilayotgan izlanishlar uni ta’riflashdan ko’ra yosh avlodga qanday singdirish yo’llarini, yani ta’lim tizimiga qanday joriy etish masalalariga qaratilgan. Compyutation thinking tushunchasi bizda mavjud axborot madaniyati, kompyuter savodxonligi tushunchalariga yaqin lekin ularga mos tushmasligi unga yangi atama va tushuncha kiritishga undadi. Yuqoridagi “Compyutation thinking”, “Вычислительное мышление” atamalarini o’zbek tiliga “Compyuter tafakkuri” va “Hisoblash tafakkuri” deb tarjima qilinar ekan, mazmun jihatdan tor va mos emasligi ko’rinib turibdi. Shuning uchun inson raqamli texnologiyalar bilan muloqoti tufayli yuzaga kelayotgan tafakkur sifatida “Raqamli tafakkur” degan atama kiritish to’g’riroq degan fikrga keldik. Tushuncha sifatida turli ta’riflarni, ilmiy manbalarni tahlil qilinganidan so`ng, quyidagicha ta’riflash mumkin. “Raqamli tafakkur- muammoni hal etish uchun masalani axborotni qayta ishlash vositalari hal eta oladigan shaklda tasvirlash va uni qo’llab natijani olish jarayonida ishtirok etuvchi tafakkur”. Raqamli tafakkurni tashkil etuvchi komponentlari ham turli manbalarda turlicha keltirilmoqda, o’rganilgan ma’lumotlar asosida raqamli tafakkur: • abstraksiya - muammo yoki tizimni tushunishni yengillashtiradi, abstraksiya yanada sodda yechimlarga olib kelish usuli; • dekompozitsiya - masalalarni kichik va tushunarli tashkil etuvchilarga bo‘lish usuli; • algoritmik tafakkur - masalani yechimiga olib keluvchi ketma ket qadamlar sxemasini tuzish jarayoni; • avtomatlash - boshqa masalalarni unumli yechimi uchun shakllangan algoritmlarni kompyuter va texnik qurilmalarda qo‘llash; • umumlashtirish (baholash) -turli ko‘rinishdagi masalalarga shakllangan yechim va algoritmlarni moslash jarayoni. Avvaldan ma’lum yechim asosida yangi muammoni tez yechish usuli kabi komponentlardan iborat degan fikrga keldik. Olib borilayotgan ko’plab ilmiy tadqiqotlar dasturlash raqamli tafakkurni shaklantirishda asosiy yondashuvlardan biri ekanligini ko’rsatmoqda. Shuningdek, ko‘plab izlanuvchilarning fikriga ko‘ra dasturlash o‘quvchilarda raqamli tafakkurning tashkil etuvchi muammolarni hal etish, tanqidiy tafakkur, ijodiy tafakkur, algoritmik tafakkur, refleksiv tafakkur, hamkorlikda ishlash, ta’lim olishni o‘rganish kabi malakalarni rivojlantiradi. Ko‘rib turganingizdek yuqorida keltirilgan barcha malakalar XXI asr insoni uchun zarur malakalardir. Shu bilan birga kelgusida dasturlash sohasida yaxshi tayyorgarlikka ega bo’lgan mutaxassislarni yetishmasligi, 2030-yillarga kelib 57 dan ortiq kasb yo’qolib 186 ta yangi kasb paydo bo’lishini va bu kasblarning 60%i IT yechimlar uchun dasturiy vositalar yaratish malakalari bilan bo’liqligi ma’lum qilinmoqda. Shuning uchun butun dunyoda dasturlashni ta’lim tizimining barcha bo’g’inlarining hatto maktabgacha ta’limdan boshlab o’quv dasturlariga fan sifatida kiritish tendensiyasi kuzatilmoqda. 1-Ma`ruza: Dasturlash tillari. Reja: 1. Rivojlanishning ilk qadamlari 2. Protsedurali dasturlash tillari tarixi 3. Sun’iy intellekt tillari 4. Zamonaviy ob’ektga yo‘naltirilgan va vizual dasturlash tillari Tayanch so’z va iboralar: Dastur, dasturlash tili, quyi dasturlash tili, yuqori dasturlash tili, Assembler tili Eniac, Paskal, Borland Delphi, C, C++, C#, Fortran 1.1. Rivojlanishning ilk qadamlari Foydalanuvchi kompyuter bilan muloqot qilishi uchun kompyuter “tili” ni bilishi talab qilinadi. Kompyuter tushunadigan “til” dasturlash tili deb ataladi. Kompyuterda dasturlash bu – kompyuter mikroprotsessori uchun turli buyruqlar berish, qachon, qayerda nimani o'zgartirish va nimalarni kiritish yoki chiqarish haqida buyruqlar berishdir. Kompyuter dunyosida ko'plab dasturlash tillari mavjud bo'lib, dasturlash va unga qiziquvchilar soni ortib bormoqda. Biror masalani kompyuterda yechish uchun, avvalo, unga algoritm tuzilishi va bu algoritmni kompyuter tushunadigan ko`rsatmalar va qonun-qoidalar asosida yozilishi kerak bo`ladi. Bu yozuv dastur bajarishi mumkin bo`lgan ko`rsatmalarning izchil tartibidan iborat ekan. Kompyuter uchun dastur tuzish jarayoni dasturlash va dasturni tuzadigan kishi dasturchi deb ataladi. Kompyuter tushunadigan til esa dasturlash tili deb ataladi. Dasturlash mashinalari ixtiro qilingan vaqtdan boshlab to bugungacha sakkiz yarim mingdan ortiq dasturlash tillari ishlab chiqilgan. Har yili ular soni yangilari bilan oshib bormoqda. Ayrim tillardan faqatgina ishlab chiqaruvchilarning o‘zlari foydalansa, ayrimlari esa millionlab dasturchilar ixtiyoriga o‘tadi. Professional dasturchilar o‘z ishida o‘nlab dasturlash tillaridan foydalanadi. Birinchi EHMlar uchun dasturlarni dasturchilar mashina kodi tilida yozganlar. Bu juda qiyin va uzoq vaqt talab etadigan jarayon bo‘lib, dastur tuzishni boshlash va ishlatib ko‘rish orasida ancha vaqt o‘tardi. Bunday muammolarni yechish faqatgina dasturlash jarayonini rivojlantirish, optimizatsiya qilish orqaligina bajarilishi mumkin edi. Dasturchilar mehnatini iqtisod qiluvchi bunday “jihoz” o‘rnini qism dasturlari egalladi. 1944 yil avgustida releli “Mark-I” mashinasi uchun Greys Xopper (dasturchi ayol, AQShning dengiz ofitseri) boshchiligida sinx ni hisoblovchi qism dasturi yozildi. Greys Xopperdan boshqalar ham bu ishdan ortda qolmadilar. 1949 yilda Jon Mouchli (ENIAK EHM ixtirochilaridan biri) yuqori darajali dasturlash tillarining dastlabkilariga asos bo‘lgan Short Code tizimini ishlab chiqdi. 1951 yilda Greys Xopper birinchi bo‘lib A-O kompilyatorini yaratdi. Dasturlash tillari 2 ta guruhga bo'linadi, quyi va yuqori darajali dasturlash tilllari. Quyi darajali dasturlash tillari mashina tiliga yaqin til bo’lib, protsessorning buyruqlariga yo’naltirilgan va uning xususiyatlarini inobatga oluvchi tillar hisoblanadi. Ular ancha murakkab bo'lishi bilan birga protsessorning barcha imkoniyatlarini ocha oladi, dasturchidan kompyuterning tuzilishini yaxshi bilishini talab etadi. EHM (Elektron Hisoblash Mashinasi) endi yuzaga kelgan paytda programma tuzishda, faqat mashina tillarida, ya'ni sonlar yordamida EHM bajarishi kerak bo'lgan amallarning kodlarida kiritilgan. Bu holda mashina uchun tushunarli sanoq, sistemasi sifatida 2 lik, 6 lik, 8 lik sanoq sistemalari bo'lgan. Programma mazkur sanoq sistemasidagi sonlar vositasida kiritilgan. Yuqori darajali dasturlashda, mashina tillariga qaraganda mashinaga moslashgan (yo'naltirilgan) belgili kodlardagi tillar hisoblanadi. Quyi dasturlash tillari (masalan: assembler, 60 yillarda) mashina tili (010110100010101)da dastur tuzish murakkab bo’lgani uchun, dasturni o’qiy olinadigan va mazmunini kuzatish imkoniyatiga ega bo’lishi uchun belgili (simvolli) turi ishlab chiqilgan. Belgilar kodlashtirilgan tillarning asosiy tamoyillari shundaki, unda mashina kodlari ularga mos belgilar bilan belgilanadi, hamda xotirani avtomatik taqsimlash va xatolarni tashhis qilish kiritilgan. Bunday dasturlash tillari kichik tizimli ilovalar, qurilmalar drayveri, nostandart qurilmalarni moslashtirish modullarini yaratishda qo’llaniladi. Yuqori darajali dasturlash tillari kompyuter arxitekturasini inobatga olmaydigan tillar bo’lib, dastur matnlarini bir mashinadan shu dastur translyatori mavjud platformali ikkinchi mashinaga osonlik bilan ko’chirish imkoniyatini beradi. Agar algoritmik til inson tiliga qanchalik yaqin bo'lsa, unga yuqori darajali til deyiladi. Bu dasturlash tillarining semantikasi odam tiliga yaqinligi tufayli dastur tuzish jarayoni ancha oson kechadi. Pascal, Fortran va Kobol tillari universal tillar hisoblanadi. Odatda turli dasturlash ishlari uchun yuqori darajali dasturlash tilidan keng foydalaniladi. Translyator dasturlarini, ya’ni, yuqori dasturlash tillaridan mashina tiliga tarjima qilib beruvchi dasturlarning yaratilishi, turli-tuman yuqori darajali tillarning yaratilishiga imkon berdi. Ko'p ishlatiladigan dasturlash tillari. Biz hozir biladigan va ishlatadigan tillarning barchasi shu guruhga mansub. Ular insonga "tushunarli" tilda yoziladi. Ingliz tilini yaxshi biluvchilar programma kodini qiynalmasdan tushunishlari mumkin. Bu guruhga Fortran, Algol, C, Pascal, Cobol va h.k. tillar kiradi(ko`pchiligi hozirda deyarli qo`llanilmaydi). Dasturlash tillarini eng birinchi paydo bo`lganlaridan to hozirgi zamonaviylarigacha ishlatish mumkin. Lekin, hozirgi web texnologiya orqali ishlaydigan tillarda (PHP, ASP.NET, JSP) ilovali dasturlar tuzilmaydi. Chunki bunday dasturlarning ishlashi uchun yana bir amaliy dastur ishlab turishi kerak. Hozirda, amaliy dasturlar, asosan, Visual C++, C#, Borland Delphi, Borland C++, Java, Python kabi tillarda tuziladi. Eng keng tarqalgan dasturlash tili(Windows OS ida) Microsoft Visual C++ tilidir. Ko`pchilik dasturlar hozirda shu tilda tuziladi. Umuman olganda, C ga o`xshash tillar hozirda dasturlashda yetakchi. Deyarli hamma zamonaviy tillarning asosida C yotadi. Bundan tashqari, Turli kompyuter o'yinlari tuzishda yoki kichik hajmdagi dasturlar tayyorlashda LUA script yoki JavaScript tillari ham keng ishlatilmoqda. Birinchi yuqori darajali dasturlash tillari: COBOL va FORTRAN O’tgan asrning 50-yillarida Greys Xopper boshchiligida yangi dasturlash tili va kompilyatori V-Oni ishlab chiqishga kirishildi. Yangi til dasturlashni ingliz tiliga yaqin tilda bajarish imkonini berdi. Bu kompilyatorda 30ga yaqin inglizcha so‘zlardan foydalanildi. 1958 yilda V-O tizimi Flow-Matic nomini oldi va tijoriy ma’lumotlarni qayta ishlashga yo‘naltirildi. 1959 yilda COBOL (Common Business Oriented Language – umumiy tijoratga yo‘naltirilgan til) tili yaratildi. Bu til mashinadan mustaqillikka ega bo‘lgan yuqori darajali biznesga yo‘naltirilgan dasturlash tilidir. Mashinadan mustaqillikka ega bo‘lgan dasturlash tillarida yozilgan dasturlar istalgan turdagi EHMda maxsus kompilyatorlar vositasida bajarilaveradi. COBOL tilini yaratishda ham Greys Xopper maslahatchi bo‘lgan. 1954 yilda FORTRAN (FORmula TRANslation) tili yaratilayotgani haqidagi xabar chop etildi. Bu dastur IBM kompaniyasining Nyu-Yorkdagi shtab-kvartirasida yaratildi. Uni tuzuvchilardan biri Jon Bekus edi. U BNF (Bekusning normal formasi) muallifi bo‘lib, bu forma ko‘plab dasturlash tillarining sintaksisini izohlashda qo‘llaniladi. Bu vaqtda Yevropa davlatlarida mashhur til ALGOL bo‘lib, xuddi Fortran kabi u ham matematik topshiriqlarga yo‘naltirilgan edi. Unda o‘sha davrning ilg‘or texnologiyasi – tarkibli dasturlash amalda qo‘llangan. Ko‘plab dasturlash tillari o‘tgan asrning 60-70-yillarida paydo bo‘ldi. Uzoq vaqt yashagan tillar sirasiga BASIC tilini kiritish mumkin. Bu dasturlash tili 1964 yilda Jon Kemeni va Tomas Kurs boshchiligida Dartmut universitetida ishlab chiqildi. Mualliflarning fikriga ko‘ra, bu til sodda, o‘rganishga oson va murakkab bo‘lmagan hisoblashlarni bajarishga mo‘ljallangan. BASIC ko‘proq mikro EHM va shaxsiy kompyuterlarda keng tarqaldi. Dastlab bu til tarkib (struktura)li bo‘lgani uchun sifatli dasturlashni o‘rganishga qiyin bo‘ldi. 1985 yilda uning True BASIC versiyasi ishlab chiqildi. Ushbu dasturni tuzganlarning fikriga ko‘ra, bu til PASCALdan ko‘ra mukammalroq hisoblangan. 1991 yilda Visual BASICning birinchi versiyasi paydo bo‘ldi. 1.2. Protsedurali dasturlash tillari tarixi Dasturlash tillari tarixida e’tiborga sazovor voqea 1971 yilda PASCAL tilining yaratilishi bo‘ldi. Uning muallifi shveysariyalik professor Niklaus Virtdir. Virt bu tilni fransuz fizigi va matematigi Blez Paskal sharafiga qo‘ydi (Blez Paskal 1642 yili hisoblash mexanizmini ixtiro qilgan). Dastlab PASCAL o‘rganish tili sifatida tuzilgan. Bu tilda dasturlashning yorqin tomonlari ochib berilgan. Amaliyotda keng qo‘llanilishi shaxsiy kompyuterlarda Turbo PASCAL versiyasidan boshlangan. C (“Ci”) dasturlash tili amaliyot tizimlari uchun ishlab chiqilgan. U UNIX amaliyotlar tizimi bilan bir vaqtda yaratilgan. Ushbu tizim va dasturlash tilining mualliflari amerikalik dasturchilar Dennis Richi va Kennet Tompsonlardir. Dastlab Kennet Tompson UNIX amaliyotlar tizimini FORTRAN tilida yozgan. Keyinchalik C tili ishlab chiqilgandan so‘ng, 1973 yilda amaliyotlar tizimining yadrosi yordamchi dasturlar bilan C tilida qayta yozildi. Bu yuqori darajali tarkibli dasturlash tilidir. Bugungi kunda bu til nafaqat amaliyot tizimlari, balki translyatorlar, tizimli va amaliy dasturlar yaratishda qo‘llaniladi. 1.3. Sun’iy intellekt tillari O’tgan asrning 90-yillarida “Sun’iy intellekt” nomli beshinchi avlod kompyuterlarini ishlab chiqarish rejalashtirilgandi. Bu ishni asosiy dasturlash tillarida amalga oshirish amrimahol edi, shu sababli loyihada sun’iy intellekt tillari sifatida LISP va PROLOG tillari tanlandi. LISP dasturlash tili (1956-1959 yillar) asoschisi Jon Makkarti bo‘lib, u sun’iy intellektning otasi hisoblanadi. Aynan u birinchi bo‘lib “sun’iy intellekt” atamasini ishlatgan. LISP tilida asosiy element rekursiv ajratilgan funksiyalarni tushuntirish bo‘lgan. Istalgan algoritm bir nechta rekursiv bilan funksiyalar to‘plami vositasida izohlanishi isbotlangan. Ushbu tilning asosiy g‘oyalari keyinroq Seymur Papert boshchiligida Masachusets texnologiyalar institutida 70-yillarda bolalar uchun ishlab chiqilgan LOGO tilida qo‘llanildi. PROLOG tili ham 1972 yilda Fransiyada sun’iy intellekt muammolarini yechish uchun ishlab chiqildi. PROLOG tili har xil fikrlarni formal ko‘rinishda tavsiflash, mantiqni muhokama qilish, kompyuterni berilgan savollarga javob berdirishga imkoniyatli hisoblanadi. 1.4. Zamonaviy ob’ektga yo‘naltirilgan va vizual dasturlash tillari So‘nggi yillarda kompyuterning dasturiy ta’minoti rivojlanishi asosiy yo‘nalishlaridan biri, bu ob’ektga yo‘naltirilgan dasturlash sohasidir. Ob’ektga yo‘naltirilgan amaliyot tizimlari (masalan, Windows), amaliy dasturlar va ob’ektga yo‘naltirilgan dasturlash (OYD) tizimlari ham ommaviylashdi. Birinchi OYD elementi Simula-67 (1967 yil Norvegiya) tilidir. Turbo PASCALda 5,5 versiyasidan boshlab OYD vositalari paydo bo‘ldi. Turbo PASCALning rivoji yakuni sifatida BORLAND firmasi tomonidan DELPHI dasturlash tizimi yaratildi. Ushbu tizim yordamida murakkab grafik interfeysni tez va oson dasturlash imkoniyati mavjud. 1991 yilda Visual BASICning I versiyasidan boshlab bu til to‘laligicha ob’ektga yo‘naltirildi (1997 yil). 1985 yilda Bell Labs (AQSh) laboratoriyasi C++ dasturlash tili yaratilganligi xabarini berdi. Bugungi kunda bu til OYD tillari orasida mashhurdir. Bu til yordamida istalgan mashina uchun – shaxsiydan to superkompyuterlargacha dasturlar yozish mumkin. Bu tilning asoschisi Born Straustrupdir. OYD tillaridan yana biri 1995 yilda Jeyms Gosling boshchiligida Sun Microsystems kompaniyasida yaratilgan JAVA tilidir. Uni ishlab chiqishda maxsus o‘rganish talab qilmaydigan, sodda til maqsad qilingan. JAVA tili maksimal darajada C++ tiliga o‘xshash bo‘lishi uchun yaratilgan. JAVA internet uchun dasturlar tayyorlashning ideal vositasidir. So‘ngi yillarda Microsoft kompaniyasi tomonidan C++ davomchisi sifatida C# (Ci sharp) tili yaratildi. Dasturlash tillari orasida C# tili ham ko`p qo`llaniladigan tillardan biridir. C# tili 2000 yilda Microsoft kompaniyasining Anders Xeylsberg (Anders Hejlsberg) boshchiligidagi ishchi guruhi tomonidan yaratilgan. Andersom Xeylsberg IBM oilasiga mansub kompyuterlar uchun birinchi kompilyatsiya qiluvchi dasturlash tillaridan biri Turbo Pascal ni yaratgan dasturchi sifatida ko‘pchilikga tanishdir. C# dasturlash tili va C++ ning keyingi avlodi hisoblansada, C# da yoziluvchi dasturlarning asosiy konstruksiyasi Paskal tilidagi dastur konstruksiyasiga o‘xshash bo‘lsada, C# ni ushbu dasturlash tillari bilan adashtirmaslik lozim. Quyidagi jadvalda dasturlash tillari haqida ma'lumotlar keltirilgan(1.1-jadval). 1.1-jadval Dasturlash tillari haqida ma'lumot O`zlashtirish uchun savollar 1.Dastur nima? 2.Dasturlash tili deganda nimani tushunasiz? 3.Quyi darajali dasturlash tili bilan yuqori darajadagi dasturlash tillari orasidagi farq qanday? 4.Obyektga yo`naltirilgan dasturlash tillari deganda nimani tushunasiz? 5. C# qanday dasturlash tili? 2-Ma`ruza: C# va .Net Core platformasi. C# dasturlash tilining tuzilishi. Reja: 1. C# dasturlash tili haqida dastlabki ma’lumotlar va uning yaratilish tarixi. 2. C# tilining asosiy xususiyatlari. 3. .Net Framework platformasi va CLR. 4. C# dasturlash tilining tashkil etuvchilari, til alfaviti va leksemasi; Tayanch so’z va iboralar: kompilyatsiya, fayl kengaytmasi, direktevalar, leksemalar, izohlar, oqimli o’qish va yozish funksiyalari, til alfaviti, identifikatorlar, kalit so’zlar. 2.1. C# dasturlash tili haqida dastlabki ma’lumotlar va uning yaratilish tarixi. C# tili 2000 yilda Microsoft kompaniyasining Anders Xeylsberg (Anders Hejlsberg) boshchiligidagi ishchi guruhi tomonidan yaratilgan. Andersom Xeylsberg IBM oilasiga masub kompyuterlar uchun birinchi kompilyatsiya qiluvchi dasturlash tillaridan biri Turbo Pascal ni yaratgan dasturchi sifatida ko‘pchilikga tanishdir. C# dasturlash tili 2000 yilda ishlab chiqilgan, lekin uning rasmiy 1.0 versiyasi 2002 yilda ishlab chiqildi. Bunga sabab aynan shu yili Windowsning .NET platformasi 1.0 versiyasi ishlab chiqilganligidir. .NET FrameWork Windows operatsion tizimi(OT) muhitida ishlovchi barcha dasturlash tillari uchun ochiq bo‘lgan va OT ning barcha komponentalariga dasturlash tili orqali murojaat qilishni ta’minlovchi dasturlash platformasi hisoblanadi. .NET FrameWork barcha dasturlash tillari uchun umumiy bo‘lgan bazaviy sinflar va ularni bajarilishini ta’minlovchi Common Language Runtime(CLR) interpretatoridan tashkil topgan. Bunda dasturlash tili tomonidan kompilyatsiya qilingan har qanday dastur ishga tushirilganda CLR tomonidan baytkodlarga o‘zgartiriladi va xuddi Assembler singari OT da ishlash xolatiga o‘tkaziladi, ya’ni interpretatsiya qilinadi. To‘g‘ri bu jarayon dasturning ishga tushishi va yuklanish jarayonini biroz sekinlashtiradi. Lekin hozirda yaratilayotgan kompyuter texnikalari uchun bu muammo emas. C# dasturlash tili Windows ning .NET platformasi bilan birgalikda ishlashga mo‘ljallangan deyarli 100% ob’ektga mo‘ljallangan dasturlash tili hisoblanadi. 2.2. C# tilining asosiy xususiyatlari: • NET Framework sinflarini to‘liq 100% ishlatish, obyektli dasturlash va sinflarni to‘la qo‘llash, avlod qoldirish, inkapsulyatsiya, polimorfizm va virtualizatsiya metodlarini qo‘llash, operatorlarni qayta yuklash va virtual funksiyalarni yaratish va foydalanish; • Asosiy va qo‘shimcha tiplarning to‘la to‘plami va yaratish imkoniyati; • integratsiyalashgan XML-xujjatlarni avtomatik generatsiya qilish imkoniyati; • Dinamik taqsimlangan xotirani avtomatik tozalash. • Sinflar va metodlarni alohida atributlar bilan belgilab qo‘yish imkoniyati, ya’ni ayrim metod va sinflar faqatgina tekshirish(otladka) rejimida kompilyatsiya qilinadi. • Windows API ga oson murojaat qilish imkoniyati; • Xotiraga va ko‘rsatkichlarga zarurat tug‘ilganda to‘g‘ridan-to‘g‘ri murojaat qilish imkoniyati; • Xodisalarni qo‘llab quvvatlash; • Dinamik WEB - sahiflarni yaratish(ASP.NET) va h. IEEE Spectrum reytingi: 2.3. Net Framework platformasi va CLR Barcha dastur yozishga mo‘ljallangan vositalar, yozilgan dasturni to‘g‘irlovchi, mashina kodiga o‘tkazuvchi, tekshiruvchi, sozlovchi va ishga tushiruvchi qobiq dastur yoki dasturlash tili sifatida qaraladi. Dastur yozishga mo‘ljallangan dasturiy vosita quyidagilardan tashkil topgan bo‘lishi mumkin: - dastur kodini kiritishga va to‘g‘rilashga mo‘ljallangan matnli redaktor; - dasturlash tilidan kompyuter tushunadigan til mashina kodiga o‘tkazuvchi kompilyator yoki interpretator; - yozilgan dasturni tekshiruvchi va ishga tushiruvchi; - dastur yozishda ko‘p marta foydalaniluvchi qism dasturlar yoki elementlarni(funksiya, prosedura va h.) o‘z ichiga oluvchi kutubxona; - yordam tizimi va boshqa elementlar. Visual Studio.NET majmuasi dastur yozish uchun bir nechta dasturlash tillari(C#, VB.NET, C++, J#, F#) uchun muqobil ishlash, to‘g‘irlash, kompilyatsiya qilish, tekshirish, sozlash va ishga tushirish imkonini beruvchi dasturiy vositalar majmuini taqdim etadi. Dasturlashga mo‘ljallangan platforma deyilganda dastur yozishga mo‘ljallangan vositalardan farqli ravishda u faqat bitta emas balki bir nechta dastur yozish vositalariga mo‘ljallangan dasturiy vosita tushuniladi. Ana shunday platformalardan biri bu .NET platformasidir (.NET FrameWork yoki dotnet deb ham ataladi). .NET platformasi ochiq tizim hisoblanib, yuqorida nomlari keltirilgan dasturlash tillarida boshqa dasturlash tillarida ham foydalanish mumkin. .NET platformasi tarkibiga kiruvchi dasturlash tillarini o‘zaro muqobil ishlashini ta’minlash uchun dastur kodlarini bir xil tilga o‘tkazish-kompilyatsiya qilish talab etiladi. Lekin platforma dasturiy kodni aynan to‘g‘ridan to‘g‘ri mashina kodiga emas, balki operatsion tizim yoki kompyuterga bog‘liq buyruqlardan iborat bo‘lmagan oraliq til hisoblanuvchi CIL -(Common Intermediate Language, yoki shunchaki IL) kodga o‘tkazadi. Ushbu tilga o‘girilgan dasturiy kod CLR(Common Language Runtime)deb nomlanuvchi tizim yordamida ishga tushiriladi yoki interpretatsiya qilinadi. CLR ni ixtiyoriy operatsion tizim uchun realizatsiya qilish mumkin. Buning uchun .NET FrameWork (yoki dotnet)ni o‘rnatish talab etiladi. CIL kodidagi dastur ishga tushirilganda CLR tizimi CIL kodidagi dasturni konkret protsessor uchun shu zahoti bajariluvchi mashina buyruqlariga o‘tkazuvchi JIT(just in time)-kompilyatorini ishga tushiradi. Ushbu kompilyator CIL kodidagi dasturni ayni damda qaysi qismi bajarilishi lozim bo‘lsa o‘sha qismini kompilyatsiya qiladi. Dasturning kodining har bir qismi bir marta kompilyatsiya qilinadi va keyinchalik foydalanish uchun keshda saqlanadi. Shu sababli .NET platformasidan foydalanib yoziladigan dasturiy kodlar birinchi marta ishga tushirilayotganda bir oz yuklanishi qiyin kechadi. Kompilyator ishga tushirishda foydalanish uchun kompilyatsiya qilingan fayl sifatida kengaytmasi .exe yoki .dll bo‘lgan faylni bizga taqdim qiladi. Ushbu fayl CIL kodidagi dastur va metama’lumotlardan tashkil topgan bo‘ladi. Dastur ishlash jarayonida CLR faqat ruxsat etilgan operatsiyalar bajarilishini nazorat qilib boradi, xotirani taqsimlanishi va tozalab turilishini ta’minlaydi va yuzaga kelgan xatoliklarni qayta ishlaydi. Bu esa, dasturning ishonchli ishlashi va xavfsizligi ta’minlanishini bir necha barobarga oshiradi. .NET platformasi ixtiyoriy .NET tipidagi dasturlash tilida foydalanish imkonini beruvchi juda katta sinflar kutubxonasini o‘zida mujassamlashtirgan. .NET platformasi kutubxonasi sinflarini mukammal o‘rganish zarurdir, lekin anchagina mashaqqatli ish hamdir. 2.4 C# dasturlash tilining tashkil etuvchilari, til alfaviti va leksemasi; Dasturlash tilini o‘rganishni biror bir xorijiy tilni o‘rganishga qiyoslash mumkin. Xorijiy tilni o‘rganish odatda tilning alfaviti o‘rganishdan boshlanadi, so‘ngra so‘zlarni, ularning tarjimasini o‘rganishga o‘tiladi, keyin esa ana shu so‘zlardan foydalanib jumlalar, gap tuzishga o‘tiladi va sekin astalik bilan so‘z boyligini ko‘paytirib borgan holda hamda ko‘p mashq qilish, ko‘p bora muloqot qilish natijasida ushbu tilda o‘z fikrlarini erkin ifoda etishga, tilni mukammal darajada bilishga erishiladi. Shunga o‘xshash biror dasturlash tilini o‘rganishda mana shu ketma-ketlikdan foydalanish yaxshi samara beradi. Endi C# dasturlash tilining alfaviti bilan tanishsak. C# dasturlash tilida matnlarni yozishda Unicode kodirovkasidagi belgilardan foydalaniladi. Kodirovka – bu belgilar va unga mos keluvchi sonli kodlar jadvalidir. Unicode kodirovkasi bir vaqtning o‘zida barcha alfavitlardagi belgilardan foydalanish imkonini beradi. C# alfaviti quyidagilarni o‘z ichiga oladi: • lotin alfavitlar hamda ular bilan birgalikda qo‘llash uchun ostki chiziq(_); • raqamlar; • maxsus belgilar, masalan +, *, { i & ; • bo‘sh va tabulyatsiya belgilari; • qatorni ko‘chirish belgilari. Belgilar to‘plamidan foydalanib, leksemalar va izohlarni yoziladi. Leksema (token) — bu dasturlash tilining mustaqil holda biror ma’noni bildiruvchi eng kichik birligidir. Leksemening quyidagi ko‘rinishlari mavjud: • nom yoki ism (identifikatorlar); • kalit so‘zlar; • amal belgilari; • ajratgichlar; • literallar (konstantalar). Leksemaga misol sifatida quyidagilarni ko‘rsatishimiz mumkin: Vasia nomli identifikator, goto kalit so‘zi,+ amal belgisi va sh.k. Leksemalardan foydalangan holda operatorlar va ifodalar tashkil qilinadi. Masalan: a+b ifoda, u ikki kattalikni qo‘shishni bildiradi; int a; - bu a nomli o‘zgaruvchini e’lon qilish operatoridir. O`zlashtirish uchun savollar 1. C# qanday dasturlash tili? 2. C# tilining xususiyatlarini sanang. 3. C# tilining qanday afzalliklari bor. 4. C# alfavitiga qanday belgilarni kiritilgan? 5. Leksema nima? 3-Ma’ruza: Identifikatorlar, literallar, o‘zgaruvchilar va berilganlar turlari. Reja: 1. Identifikatorlar. 2. Kalit (xizmatchi) so‘zlar. 3. Amal belgilari. 4. Literallar (konstantalar). 5. Izohlar. 6. C# tilining tiplari tizimi. Tayanch so’z va iboralar: Identifikator, amal belgisi, literal, izoh, o`zgaruvchi turi, tiplar tizimi 3.1. Identifikatorlar Nom yoki identifikatorlar – dastur obyektlariga murojaat qilish va ularni birbiridan farqlash, ajratish uchun xizmat qiladi, qisqacha qilib aytganda identifikatsiya qiladi. Identifikatorda harflar, belgilar va ostki chiziq belgisidan foydalanish mumkin. C# dasturlash tilida katta va kichik registrdagi harflar bir biridan farq qiladi. Masalan: hacker, Hacker va hAcKeR nomlari bu 3 ta turli xil nomni bildiradi. Identifikatorning birinchi harfi faqat belgi yoki ostki chiziq bo‘lishi mumkin lekin raqam bo‘lishi mumkin emas. Identifikator uzunligi chegaralanmagan. Identifikatorni berishda probeldan foydalanish xatolikka olib keladi. A, a, abror, _matn, nt2, rv_1 – to‘g‘ri; 1a, afzal s_, 456 – xato. C# dasturlash tilida identifikator sifatida krill alfavitidagi belgilardan foydalanish mumkin. Masalan: алфа yoki alpha. Identifikatorlar o‘zgaruvchini e’lon qilishda yaratiladi va shundan so‘ng dastur qolgan qismida foydalanish mumkin. String soz=”Salom Dostim!”; //bu yerda soz – identifikator. Identifikator tanlashda u dasturlash tilining kalit so‘zlari bilan bir xil bo‘lib qolmasligini ta’minlash zarur. 3.2. Kalit (xizmatchi) so‘zlar Kalit so‘zlar – bu tilning zahira qilingan yoki avvaldan tayinlab qo‘yilgan identifikatorlari yoki kompilyator uchun maxsus vazifani bajaruvchi buyruqlaridir. C# dasturlash tilining kalit so‘zlari quyidagi 3.1- jadvalda keltirilgan. 3.1-jadval C# ning kalit so‘zlari Abstract as base bool break Byte case catch char checked Class const continue decimal default Delegate do double else enum Event explicit extern false finally Fixed float for foreach goto If implicit in int interface Internal is lock long namespace New null object operator out Override params private protected public Readonly ref return sbyte sealed Short sizeof stackalloc static string Struct switch this throw true Try typeof uint ulong unchecked Unsafe ushort using virtual void Volatile while 3.3.Amal belgilari va ajratuvchilar Amal belgilar operandlar orasida aniq bir amalni bajarishni bildiruvchi bir yoki bir nechta belgi bo‘lishi mumkin. Masalan: a += b. Bu yerda a va b operandlar, += esa amal belgisi. Amal belgisini bildiruvchi belgilar +, &&, |, < lar kabi maxsus belgilar yoki as va new kabi xizmatchi so‘zlar ham bo‘lishi mumkin. Amallar - unda qatnashuvchi operandlar soniga qarab unar(bitta), binar(ikkita) va ternar(uchta) turlarga bo‘linadi. Quyida C# da qo‘llaniladigan barcha amal belgilari keltirilgan. + - * / % & | ^ ! ~ = < > ? ++ -- && || << >> == != <= >= += -= *= /= %= &= |= ^= <<= >>= -> Ajratgichlar dastur elementlarini ajratish va aksincha guruhlash uchun qo‘llaniladi. Ular quyidagilardir: {} [] () . , : ; 3.4. Literallar (konstantalar) Literal yoki konstanta deb qiymati o‘zgarmaydigan kattaliklarga aytiladi. C# da standart mantiqiy, butun, haqiqiy, belgili va matnli qiymatga ega kattaliklar hamda null konstantasi bor. Dasturchi o‘zi e’lon qilgan konstantani tipi va qiymatini mustaqil berishi mumkin. Konstantalarning berilishi va ularga misol quyidagi 3.2-jadvalda keltirilgan. 3.2-jadval. C# ning konstantalari Konstanta Mantiqiy Tavsifi Misol true (rost) yoki false (yolg‘on) true false Butun O‘nlik: sonlar ketma-ketligi (0, 1, 2, 3, 8 0 199226 4, 5, 6, 7, 8, 9), va ularning ortidan 8u 0Lu 199226L quyidagi suffikslarni qo‘yish lozim (U, u, L, l, UL, Ul, uL, ul, LU, Lu, lU, lu) O‘n oltilik: 0x yoki 0X belgilari bilan 0xA 0x1B8 0X00FF birgalikda o‘n oltilik sanoq 0xAU 0x1B8LU sistemasidagi raqamlar (0, 1, 2, 3, 4, 5, 0X00FFl 6, 7, 8, 9, A, B, C, D, E, F), va ularning ortida quyidagi suffikslarni qo‘yiladi(U, u, L, l, UL, Ul, uL, ul, LU, Lu, lU, lu) Haqiqiy Fiksirlovchi nuqta bilan qo‘llaniluvchi 5.7 .001 35. raqamlar: va ularning ortidan 5.7F .001d 35. qo‘yiluvchi quyidagi suffikslar: F, f, D, 5F .001f 35m d, M, m Qo‘llanilishi: [raqam][.][raqam][suffiks] Eksponenta ko‘rinishidagi tartibda, 0.2E6 .11e+3 5E-10 qo‘llanilishi: 0.2E6D .11e–3 [raqam][.][raqam]{E|e}[+|–][raqam] 5E10 [suffiks] Suffiks — quyidagi belgilardan biri bo‘lishi mumkin: F, f, D, d, M, m Belgili Apostrof ichiga yozilgan belgi yoki 'A' 'yu' '*' uning kodi '\0' '\n' '\xF' '\x74' '\uA81B' Matnli satrli yoki Qo‘shtirnoq ichiga olib yozilgan "Zdes bil Vasia" belgilar ketma-ketligi "\tZnacheniye r = \xF5 \n" "Zdes bil \u0056\u0061" "C:\\temp\\file1.txt" @"C:\temp\file1.txt" null Hech qanday obyektni null ko‘rsatmaydigan bo‘sh ishorat Mantiqiy literallar 2 ta(true va false) bo‘lib, ular dasturda biror qiymatni bor yoki yo‘qligini bildiruvchi ishora sifatida keng qo‘llaniladi. Agar manfiy qiymatli butun yoki haqiqiy literallarni qo‘llash lozim bo‘lsa raqam oldidan unar o‘zgartirish amali(-) dan foydalaniladi. Masalan: -658u. Belgili literallar Unicode kodirovkasidagi ixtiyoriy belgi bo‘lishi mumkin. Belgili konstantalar 4 xil ko‘rinishda bo‘lishi mumkin: - odatiy grafik ko‘rinishda taqdim etiluvchi (apostrof va qatorni o‘tkazish belgisidan tashqari): 'A', 'yu', '*' ; - boshqaruvchi kalit belgilar (prefikslar) bilan ifodalanuvchi: '\0', '\n' ; - o‘n oltilik sanoq sistemasidagi kod ko‘rinishida: '\xF', '\x74' ; - Unicode simvolining escape ketma-ketligidagi kodi ko‘rinishida: '\uA81B'. Belgili literallar – boshqaruvchi kalit belgilari ko‘rinishida yoki o‘n oltilik sanoq sistemasidagi ko‘rinishida yoki Unicode simvolining escape ketmaketligidagi kodi ko‘rinishida ifodalanganda ularning oldida ‘\’- slash (teskari bo‘lish) belgisi qo‘yilishi shart. Boshqaruvchi kalit belgilarida ‘\’ belgisidan keyin yozilgan harflar mos ravishda maxsus vazifalarni bajaradi. Quyidagi 3.3-jadvalda boshqaruvchi kalit belgilari va ularning vazifalari keltirilgan. 3.3-jadval. Boshqaruv belgilari jadvali Kalit Tavsifi Yunikodda kodi \’ Bittalik qo‘shtirnoq, apostrofni ifodalaydi. 0×0027 \" Ikkitalik qo‘shtirnoqni ifodalaydi. 0×0022 \\ Teskari slash ni o‘zini ifodalaydi. 0x005C \0 Bo‘sh simvol. 0×0000 \a ALERT. Ovozli signal. 0×0007 \b Backspace. Bitta pozitsiya oldinga o‘tish. 0×0008 \f FORM FEED. Yangi sahifaga o‘tish. 0x000C \n Yangi qatorga o‘tish 0x000A \r Karetka(kursor)ni qaytarish 0x000D \t Gorizontal tabulyatsiya 0×0009 \v Vertikal tabulyatsiya 0x000B O‘n oltilik sanoq sistemasida ifodalangan belgili literallar \x prefiksidan boshlanadi va undan keyin belgining kodi yoziladi. Prefiksdan keyin yoziluvchi belgining sonli kodi 0-215 gacha oraliqda bo‘lishi lozim, aks holda xatolik yuzaga keladi. Unicode simvolining escape ketma-ketligidagi kodi ko‘rinishida ifodalangan belgili literallar \u yoki \U prefiksidan boshlanadi va undan so‘ng o‘n oltilik sanoq sistemasidagi kod yoziladi. Yoziluvchi o‘n oltilik sanoq sistemasidagi kod \U10000 dan \U10FFFF gacha diapazonda bo‘lishi lozim. Satrli ko‘rinishdagi literallarni ifodalashda ham boshqaruv kalitli literallardan foydalanish mumkin. Masalan bir necha qatordan iborat jumlani bitta literalga jamlangan xolatini ifodalash uchun ularni \n (qatorlarni ajratish kaliti) bilan qo‘shib yoziladi. Masalan: “Mustaqil O‘zbekiston \nhech qachon, hech kimga \nqaram bo‘lmaydi!”. Ushbu literal aslida quyidagicha ko‘rinishda: Mustaqil O‘zbekiston hech qachon, hech kimga qaram bo‘lmaydi!”. Boshqaruvchi kalit belgilarini satrli literallarda o‘z vazifasini bajarmasligi ya’ni ularni o‘chirib qo‘yish yoki oddiy qilib aytganda ular belgi ko‘rinishida qabul qilinishi uchun C# da ana shu literal @ belgisi bilan ishlatilishi lozim. Masalan, faylning joylashgan joyini ifodalash uchun mana bu ikki ko‘rinishda berilgan literallarni solishtirib ko‘ramiz: "C:\\app\\bin\\debug\\a.exe" @"C:\app\bin\debug\a.exe" Ko‘rinib turibdiki ikkinchi variantdagi literalni qo‘llash birinchisiga nisbatan qulayroq. 3.5. Izohlar Har bir dasturchi yozgan dasturiy kodini oradan bir qancha vaqt o‘tganda keyin ochib, unda nima ish qilganligini tushunib olishi uchun bir oz qiynalishi tabiiy xol. Odatda, mana shunday xolatlarning oldini olish maqsadida dasturchilar yozilgan kodda izohlardan foydalanadilar. Izohlar – dasturga yoki uning qismlariga sharhlar yozish uchun qo‘llaniladi. Kompilyator dasturni kompilyatsiya qilganida avtomatik tarzda izohlarni dastur kodidan chiqarib tashlab keyin kompilyatsiyani amalga oshiradi. C# da ikki xil ko‘rinishdagi izohlar qo‘llaniladi: bir satrli va ko‘p satrli. Bir satrli izohlar ikkita slesh(//) belgisini qo‘yib keyin yoziladi va yangi qatorga o‘tilmagunga qadar // dan keyin yozilgan barcha belgi izoh sifatida qabul qilinadi. Ko‘p satrli izoh - /* belgilaridan boshlanib, tugashida */ belgilari bilan berkitiladi. /* va */ belgilari orasiga bir yoki bir necha qator izoh yozish mumkin. 3.6. C# tilining tiplari tizimi. Ma’lumotlarning tiplari. Dastur ishlash jarayonida qayta ishlanayotgan yoki dasturda foydalanilayotgan ma’lumotlar operativ xotirada joylashadi. Kompilyator ushbu ma’lumotlarning operativ xotiradan qancha joy egallashi, qanday kodlanishi va ular ustida qanday amallar bajarish mumkinligini aniq bilishi lozim. Bularning barchasi ma’lumotlarni tiplar yordamida aniqlashtirib olish orqali amalga oshiriladi. Ma’lumotlarning tiplari – ma’lumotni taqdim etilishi, uning qabul qilishi mumkin bo‘lgan qiymatlar to‘plami bilan xaraterlanadi. Dastur bajarilishi jarayonida ma’lumotlar saqlanuvchi xotira 2 ga bo‘linadi: stek(stack) va dinamik oblast(heap, kucha ham deb ataladi). Stekda kompilyator tomonidan ajaratilib, unda ma’lumot saqlanuvchi dinamik xotira adresi saqlanadi. Ma’lumotlar esa asosan dinamik xotirada saqlanadi. Vaqti-vaqti bilan ushbu xotira dastur bajarilishi jarayonida maxsus buyruq bilan tozalab turiladi. Tiplarning klassifikatsiyasi Tiplar ularning turli belgilariga ko‘ra klassifikatsiyalanadi. Tip yaratilishiga ko‘ra oddiy va strukturali turlarga, uni yaratuvchiga ko‘ra standart va dasturchi tomonidan aniqlangan turlarga bo‘linadi. Ma’lumotlarni saqlash imkoniyatiga ko‘ra tiplar: o‘lchamli(qiymatli) va ishoratli turlarga bo‘linadi. O‘lchamli tiplar – biz avvaldan foydalanib kelganimiz standart tiplardir. Ishoratli tiplar esa – ob’ektlardir. C# da o‘lchamli tiplardan ishoratli tiplar sifatida foydalanish ham mumkin. Ya’ni ular o‘z navbatida ob’ekt sifatida ham ishlatiladi. Buning uchun System kutubxonasini proyektga bog‘lab olish lozim. C# da asosiy tiplar, butun, haqiqiy tiplar 3.4-3.6 jadvallarda keltirilgan. 3.4-Jadval C# da asosiy tiplar (CTS- Common types System) Ob’ekt o‘lchamli Tavsifi Object object CTS ning barcha tiplarining bazaviy sinfi String string Satrli tip SByte sbyte 8-razryadli ishorali butun sonlar. 128 ... 127 Byte byte 8-razryadli ishorasiz butun sonlar. 0 .. 255 Int16 int 16-razryadli ishorali butun sonlar. 32 768.. 32 767 UInt16 uint 16-razryadli ishorasiz butun sonlar. 0 .. 65 535 Int32 int 32-razryadli ishorali butun sonlar. 2 147 483 648 .. 2 147 483 647 UInt32 uint 32-razryadli ishorasiz butun sonlar. 0 ..4 294 967 295 Int64 long 64-razryadli ishorali butun sonlar. 9 223 372 036 854 775 808 .. 9 223 372 036 854 775 807 UInt64 ulong 64-razryadli ishorasiz butun sonlar. 0 .. 18 446 744 073 709 551 615 Decimal decimal 128-razryadli haqiqiy sonlar. Char char 16-razryadli belgili tip. Single float 32-razryadli haqiqiy sonlar. Double double 64-razryadli haqiqiy sonlar. Boolean bool Mantiqiy tiplar (true/false) Butun tiplar. 3.5-jadval Tip Diapazoni Formati(razryadi) System.SByte -128…127 8 bit, ishorali System.Int16 -32768…32767 16 bit, ishorali System.Int32 -2 147 483 648…2 147 483 647 32 bit, ishorali System.Int64 -263…263 64 bit, ishorali System.Byte 0…255 8 bit, ishorasiz 0…65535 16 bit, ishorasiz 0…4 294 9 67 295 32 bit, ishorasiz -9 223 372 036 854 775 808- 64 bit, ishorali (System.Short) System.Uint16 (System.Ushort) System.Uint32 (System.Uint) System.Long 9 223 372 036 854 775 807 System.Long 0 - 18 446 744 073 709 551 615 64 bit, ishorasiz Haqiqiy tiplar 3.6Jadval Belgili sonlar Tip Diapazoni System.Single 1.5*1045…3.14*1038 7-8 4 bayt System.Double -5.0*10324…1.7*10308 15-16 8 bayt xonasi(razryadi) Formati Belgili tiplar Asosiy belgili tip: System.Char; Asosiy satrli tip: System.String; C# da belgili tiplarning qiymatlari bittalik qo‘shtirnoq(apostrof) bilan, satrli tiplarning qiymatlari ikkitalik qo‘shtirnoq bilan beriladi. Masalan: String x=”f”; Char ch=’f’; Mantiqiy tip Asosiy mantiqiy tip: System.Bool; Qabul qiluvchi qiymatlari: true, false. O’zlashtirish uchun savollar 1. Til identifikatorida katta va kichik registrlar inobatga olinadimi? Va uzunligi chegaralanganmi? 2. Identifikator qanday belgilardan boshlanishi mumkin? 3. Tilda kalit so’zlar nima uchun xizmat qiladi? 4. Tilda qanday konstantalar turlari mavjud va ular qanday tavsiflanadi? 5. Tilning boshqaruv belgilari qaysilar va tavsiflari qanday? 6. C# tilining tiplari tizimi. Ma’lumotlarning tiplari. 4-Ma`ruza: C# tilining amallari. Consoleda kiritish-chiqarish. Reja: 1. O‘zgaruvchi va o‘zgarmaslar. 2. Operatsiya (amal) va ifodalar 3. C# ning asosiy amallari 4. Konsolli ilovalar, ma’lumotlarni kiritish va chiqarish. Tayanch so’z va iboralar: Ifodalar, operatorlar, arifmetik amallar, qiymat berish operatori, til ko’rsatmasi, inkrement, dekrement. 4.1. O‘zgaruvchi va o‘zgarmaslar. O‘zgaruvchilar O‘zgaruvchi - dastur bajarilishi jarayonida o‘z qiymatini bir yoki bir necha marotaba almashtirishi mumkin bo‘lgan xotiraning nomlangan qismi. Nom esa o‘zgaruvchi belgilangan so‘z, harf yoki harf va belgilar ketma ketligi bo‘lishi mumkin. Dasturda foydalaniluvchi barcha o‘zgaruvchilar aniq e’lon qilinishi lozim. Har bir o‘zgaruvchi e’lon qilinayotganda uning nomi va tipi ko‘rsatiladi. O‘zgaruvchining nomi uning qiymati joylashgan xotira qismiga murojaat qilish uchun xizmat qiladi. Tip esa ma’lumot uchun xotiradan qancha joy ajratilishi lozimligini bildiradi. O‘zgaruvchilar quyidagicha e’lon qilinishi mumkin: <o‘zgaruvchi tipi> <o‘zgaruvchi nomi> [= o‘zlashtiriluvchi qiymat]; Misollar: int a=10, c=12, abc=0; double b=11.5; //a=10; Console.Writeline(a); bool isEnabled = true; int x; double y=3.0; string hello="Hello World"; char c='s'; int a=4; int z=a+5; O‘zgaruvchini e’lon qilishda bir tipli bir nechta o‘zgaruvchilarni bitta tip yozib, so‘ngra shu tipli o‘zgaruvchilarni ketma-ket “,” bilan ajratgan xolda yozish orqali e’lon qilish hamda to‘g‘ridan-to‘g‘ri ularning boshlang‘ich qiymatini berib ketish mumkin, ya’ni ularni initsializatsiya qilib olish mumkin. O‘zgaruvchini initsializatsiya qilish deganda e’lon qilingan o‘zgaruvchiga boshlang‘ich qiymatni berish tushuniladi. Masalan: int a, b = 1; Bu yerda: a int tipidagi o‘zgaruvchi bo‘lib, uning boshlang‘ich qiymati o‘rnatilmagan, ya’ni initsializatsiya qilinmagan; b int tipidagi o‘zgaruvchi bo‘lib, uning boshlang‘ich qiymati 1 ga teng; float x = 0.1, y = 0.1f; Bu yerda: float tipidagi x va y o‘zgaruvchilarga boshlang‘ich xolda 0.1 qiymat o‘zlashtirilmoqda. Farqi, x o‘zgaruvchi initsializatsiya qilinayotganda avval uning tipi double tipidagi konstanta sifatida shakllantiriladi so‘ngra float tipiga o‘zgartiriladi, y o‘zgaruvchi esa to‘g‘ridan to‘g‘ri oraliq o‘zgartirishsiz float tipi sifatida e’lon qilinadi va 0.1 ni o‘zlashtirib oladi. O‘zgaruvchilarni e’lon qilish jarayonida ularning qiymati to‘g‘ridan-to‘g‘ri ifoda bilan berib ketish mumkin, faqat ifodada ishtirok etuvchi o‘zgaruvchilar avvalroq initsializatsiya qilingan bo‘lishi lozim, masalan: int b = 1, a = 100; int x = b * a + 25; Ba’zi xollarda o‘zgaruvchiga null (bo‘sh) qiymat o‘zlashtirish lozim bo‘ladi. string tipidagi yoki ishorat(ssilka)li tipdagi o‘zgaruvchilar to‘g‘ridan to‘g‘ri null qiymat qabul qiladi. Misol uchun: string=null; Oddiy tipdagi o‘zgaruvchilar esa to‘g‘ridan-to‘g‘ri null qiymat olmaydi. Ular bo‘sh qiymat olishi uchun tipni e’lon qilgandan so‘ng ? belgisi qo‘yish lozim bo‘ladi. int? i = null; C# da o‘zgaruvchilarni ixtiyoriy joyda e’lon qilish mumkin. using System; class ozgaruvchi { public static void Main() { int i; //o‘zgaruvchini e’lon qilish; i=10; // o‘zgaruvchiga qiymat berish Console.WriteLine(i.tostring());// ekranga chiqarish Console.ReadKey(); //biror tugma bosilguncha kutish } } C# da katta va kichik harfli o‘zgaruvchi va o‘zgarmaslarning nomlari birbiridan farqlanadi. Katta va kichik harfda yozilgan bir hil nomli o‘zgaruvchilar alohida-alohida o‘zgaruvchi va o‘zgarmaslar sifatida hisoblanadi. C# da o‘zgaruvchining avvalgi qiymatini birga oshirish uchun ketma-ket joylashgan ++, kamaytirish uchun ketma-ket joylashgan –- amal belgilaridan foydalanish mumkin. Agar ++(--) o‘zgaruvchining o‘ng tomonida joylashgan bo‘lsa, avval qiymati 1 ga oshiriluvchi(kamaytiriluvchi) o‘zgaruvchining joriy qiymati bo‘yicha hisoblash ishlari bajarilib, undan so‘ng uning qiymati 1 ga oshiriladi(kamaytiriladi). int i=1; int j=i++; … Ushbu xolda j ga avval 1 o‘zlashtiriladi. So‘ngra i ning qiymati birga oshiriladi. Ya’ni, hisoblashdan so‘ng j=1, i=2 bo‘ladi. Agar ++(--) o‘zgaruvchining chap tomonida joylashsa, u xolda o‘zgaruvchining qiymati hisoblashdan avval 1 ga oshiriladi(kamaytiriladi),so‘ngra hisoblash bajariladi. Masalan: int i=1; int j=++i; ... Ushbu xolda i ning qiymati avval 1 ga oshiriladi, so‘ngra hisoblash natijasi j ga uzatiladi. Ya’ni, hisoblash natijasida, j=2, i=2 bo‘ladi. Quyidagi xolatni ko‘ramiz: ... int i=1; Console.WriteLine(“i=”+i++); ... Ushbu dastur kodi bajarilishi natijasida, avval i ning joriy qiymati (ya’ni 1) ekranga chiqariladi, so‘ngra i ning qiymatiga 1 qo‘shiladi. Agar, o‘zgaruvchiga uni e’lon qilish vaqtida to‘g‘ridan-to‘g‘ri qiymat o‘zlashtirish, hisoblash ishlari orqali amalga oshiriladigan bo‘lsa, amal bajariluvchi operandlar barchasi, bir xil tipga ega bo‘lishi hamda natija ham e’lon qilinuvchi o‘zgaruvchi tipi diapazonidan chiqib ketmasligi lozim. Masalan: int i=15*10; //to‘g‘ri; byte j=10; int i=j*50; /* to‘g‘ri; chunki, j qabul qilish mumkin bo‘lgan qiymatlar int tipi diapazonidan chiqib ketmaydi shu sababli qabul qiladi*/; int k=15+10.0; //xato. 10.0 butun son emas; byte b=255*3; //Xato. Natija byte diapazonidan chiqib ketadi. C# dasturlash tilidagi dastur o‘zida uslub (metod) va ma’lumotlarni jamlagan sinflardan tashkil topadi. Sinf bloki ichida to‘g‘ridan to‘g‘ri e’lon qilingan o‘zgaruvchi sinfning maydoni deyiladi. Sinf ichida esa alohida blok ichida sinfning uslub(metod)lari yoziladi. Uslub ichida e’lon qilingan o‘zgaruvchi lokal o‘zgaruvchilar deyiladi. O‘zgaruvchilardan foydalanilganda ularning foydalanish chegarasi degan tushunchaga e’tibor berish lozim. O‘zgaruvchining foydalanish chegarasi uni initsializatsiya qilingan joydan boshlab, dasturning shu qismini yakunlovchi blokgacha davom etadi. Blok – bu figurali qavslar bilan chegaralangan dastur kodidir. Blokning vazifasi – operatorlarni guruhlashdan iborat. C# da har qanday o‘zgaruvchi qandaydir blok ichida e’lon qilinadi, masalan: sinf bloki ichida, sinf uslubining bloki ichida, uslubning ichida joylashgan ichki uslub ichida va h. O‘zgaruvchining nomi uning foydalanish chegarasi ichida, ya’ni u joylashgan blok ichida unikal bo‘lishi lozim. Quyidagi misolni ko‘rib o‘taylik: class X // X nomli sinfni e’lon qilish { int A; // X sinfning A nomli maydonini e’lon qilish int B; // X sinfning B nomli maydonini e’lon qilish void Y() {//--X sinfning Y nomli uslubi bloki boshlanishi--int C; // C nomli lokal o‘zgaruvchi, uning foydalanish chegarsi faqat Y uslubi bloki ichida int A; // A nomli lokal o‘zgaruvchi, uning foydalanish chegarsi faqat Y uslubi bloki ichida va X sinfning yuqorida e’lon qilingan A maydoni bilan konflikt bermaydi { //====== Y uslubining ichki bloki boshlanishi========= int D; // D nomli lokal o‘zgaruvchi, uning foydalanish chegarsi faqat ushbu ichki blok ichida int A; // Bu xato. Chunki Y uslubi ichida A nomli o‘zgaruvchidan avval foydalanilgan! S = B; // S o‘zgaruvchiga X sinfning V maydoni qiymati o‘zlashtirilmoqda S = this.A; // S o‘zgaruvchiga X sinfning A maydoni qiymati o‘zlashtirilmoqda } // ======= Y uslubining ichki bloki oxiri===== } // X sinfning Y nomli uslubi bloki oxiri--} // X sinf bloki oxiri O‘zgaruvchilar dasturda ular e’lon qilingan joyda yaratiladi va ular joylashgan blok tugashida tozalab tashlanadi. Shu blokka qayta murojaat etilganda o‘zgaruvchi yangidan yaratiladi. O‘zgarmaslar. O‘zgarmaslar dastur bajarilishi jarayonida bir marta qiymat berilgandan so‘ng qiymatini o‘zgartirib bo‘lmaydigan kattaliklardir. O‘zgarmaslarni C# da const kalit so‘zi bilan e’lon qilinadi. const double Pi = 3.14; Agar o‘zgarmas butun boshli dasturning barcha qismlarida foydalanish uchun ruxsat etilgan bo‘lsa, public kalit so‘zi bilan qo‘llaniladi. public const double Pi = 3.14; O‘zgarmaslarning qiymati ifoda ko‘rinishida berilishi ham mumkin. 4.2. Operatsiya(amal belgilari) va ifodalar Operatsiya yoki amal belgilari - bu operandlar ustida belgilangan tartibda biror amalni bajaruvchi belgi yoki belgilar ketma ketligidir. Ifoda – ma’lum bir hisoblash qoidasiga asosan amal belgilari bilan bog‘langan operandlardir. Ifodada amal belgilari yordamida bog‘langan operandlar ishtirok etadi. Operandlar o‘zgarmas, o‘zgaruvchi yoki funksiya bo‘lishi mumkin. Masalan, a + 2. Bu operandlar + belgisi bilan bog‘langan ifodadir, a va 2 esa operand. C# ning amal belgilari quyidagi 4. 1 jadvalda keltirilgan. 4.1- jadval. C# ning amal belgilari Kategoriyasi Amal Nomlanishi belgisi Birinchi daraja x() Funksiya, uslub yoki delegatni chaqirish x[] Biror to‘plam, massiv yoki majmua elementiga murojaat x++ Postfiksli inkrement x-- Postfiksli dekrement new Xotiradan joy belgilash typeof Tipni aniqlashtirish checked Tekshiriluvchi kod unchecked Tekshirilmaydigan kod + Unar qo‘shish amali - Unar ayirish amali ! Mantiqiy ayirish(emas) ~ Razryad bo‘yicha ayirish ++x Prefiksli inkrement --x Prefiksli dekrement (tip)x Tipni o‘zgartirish * Ko‘paytirish / Bo‘lish % Qoldiqli bo‘lish + Qo‘shish - Ayirish << Chapga surish >> O‘ngga surish Solishtirish(taqqoslash) < Kichik va tipni tekshirish > Katta <= Kichik yoki teng >= Katta yoki teng is Tegishlilik as Keltirish, tenglash == Teng != Teng emas & Razryadli kon’yunksiya (VA) Unar Multiplikativ Additiv Surish Tenglikni tekshirish Mantiqiy razryadli Razryadli istisno etuvchi YOKI amali Mantiqiy | Razryadli diz’yunksiya (YOKI) && Mantiqiy VA || Mantiqiy YOKI Shartli ?: Shartli operatsiya O‘zlashtirish = O‘zlashtirish *= Ko‘paytirib o‘zlashtirish /= Bo‘lib o‘zlashtirish %= qoldiqli bo‘lib o‘zlashtirish += Qo‘shib o‘zlashtirish -= Ayirib o‘zlashtirish <<= chapga surib o‘zlashtirish >>= o‘ngga surib o‘zlashtirish &= razryadli VA amalini bajarib o‘zlashtirish razryadli istisno etuvchi YOKI amalini bajarib o‘zlashtirish |= razryadli YOKI amalini bajarib o‘zlashtirish 4.1 – jadvalda keltirilgan amal belgilari - ifodalarda bajarilish ketma-ketligi kamayish tartibida joylashtirilgan, ya’ni avval yuqorida joylashgan kategoriyadagi amallar bajariladi. Agar ifodada bir nechta bitta kategoriyaga mansub operatsiyalar ketma-ket joylashgan bo‘lsa, o‘zlashtirish va shartli amallar o‘ngdan chapga qarab bajariladi, qolgan amallar esa chapdan o‘ngga qarab bajariladi. Amallarning bajarilish ketmaketligini buzish uchun oddiy qavslardan foydalaniladi. 4.3. C# da asosiy operatsiyalar. Inkrement va dekrement Inkrement va dekrement amallari operandni 1 qiymatga oshirish va kamaytirish uchun xizmat qiladi. Ularning ikki xil formasi bor bo‘lib, birinchisi prefiksli forma: bunda amal belgisi operandning old tarafida joylashadi, ikkinchisi postfiksli forma bo‘lib: bunda amal belgisi operanddan keyin joylashadi. Prefiksli formada avval ta’kidlab o‘tganimizdek, birinchi navbatda operand qiymati 1 birlikka oshiriladi(kamaytiriladi), so‘ngra operandning yangi hosil bo‘lgan qiymatidan ifodada foydalaniladi. Postfiksli formada esa operand shu jarayongacha bo‘lgan qiymati ifodada hisoblanib bo‘lingandan so‘ng bir birlikka orttiriladi (kamaytiriladi). Standart inkrement va dekrement amallaridan butun, belgili va haqiqiy tiplarda foydalanish mumkin. new operatsiyasi new operatsiyasi yangi obyekt yaratish uchun xizmat qiladi. Sintaksisi: new tip ( [ argumentlar ] ) Misol: object z = new object(); int i = new int(); // bu xolat int i = 0; ga teng kuchli. new operatsiyasi bajaralish jarayonida birinchi navbatda kerakli hajmdagi joy xotiradan ajratiladi, so‘ngra konstruktor metodi orqali kerakli ob’ekt initsializatsiya qilinadi. Qiymatli tiplar new yordamida e’lon qilinganda o‘zgaruvchiga boshlang‘ich qiymat sifatida 0 o‘zlashtiriladi. Unar ayirish amali Unar ayirish amali (-) sonli tipdagi operandning ishorasini uning aksiga aylantirish uchun xizmat qiladi. Mantiqiy ayirish (!) amali - mantiqiy bool tipli kattaliklar uchun mo‘ljallangan. Mantiqiy ayirish amali operand qiymatini uning aksiga o‘zgartirish uchun xizmat qiladi. Ya’ni mantiqiy ayirish amali qo‘llanganda operandning qiymati true bo‘lsa, uning qiymati false ga almshadi, agar operandning qiymati false bo‘lsa, uning qiymati true ga almashadi. Razryadli ayirish ( ~ ) amali – ko‘pincha bitli ayirish amali deb ham yuritiladi. Razryadli ayirish amali int, uint, long yoki ulong tipli operandning ikkilik kodidagi har bir razryadini inversiya qilish uchun qo‘llaniladi. Ya’ni ushbu amalni qo‘lllash natijasida operandning ikkilik kodidagi 1 ga teng bo‘lgan razryadlari 0 ga, 0 ga teng bo‘lgan razryadlari esa 1 ga almashadi. Masalan: int v = 153; // 153 ning ikkilik kodidagi qiymati 10011001 ga teng int n = ~v; // natija: n ning qiymati 102 ga, uning ikkilik koddagi qiymati esa 01100110 ga teng bo‘ladi. Unar amallarda ishtirok etuvchi operand bitta bo‘ladi. * Unar qo‘shish amali qo‘llanganda operandning arifmetik qiymati o‘zgarmaydi, lekin agar uning tipi uchun arifmetik operatsiya aniqlanmagan bo‘lsa uning tipi o‘zgarishi mumkin. Tiplarni oshkor o‘zgartirish amali Tiplarni oshkor o‘zgartirish amali operand qiymatining tipini boshqa tipga o‘zgartirish uchun qo‘llaniladi. Ushbu amalni qo‘llab, kattaroq tipli qiymatlarni kichikroq tipga o‘zgartirilsa, qiymatlarda yo‘qotish kuzatiladi. Sintaksisi: ( tip ) ifoda; Bu yerda tip - ifoda qiymatini qaysi tipga o‘zgartirish lozimligini bildiruvchi tip, ifoda esa - o‘zgaruvchi yoki o‘zgarmas nomi va sh.k. Masalan: long b = 300; int a = (int) b; // Ma’lumot yo‘qolishi yuz bermaydi int d = (byte) a; // Ma’lumot yo‘qoladi Ko‘paytirish, bo‘lish va qoldiqli bo‘lish Ko‘paytirish amali(*) ikki operandni ko‘paytirish orqali hosil bo‘lgan natijani qaytaradi. Standart ko‘paytirish amali int, uint, long, ulong, float, double va decimal tiplari uchun aniqlangan. Boshqa tipli kattaliklar uchun ham ko‘paytirish amalini qo‘llash mumkin, faqat ushbu tip uchun avtomatik o‘zgartirish amalga oshishi lozim bo‘lishi kerak. Natijaning tipi - agar katta tipli operand qiymati int tipidan kichik bo‘lmasa, shu operand tipida, aks xolda eng kamida int tipida bo‘ladi. Bo‘lish amali ( / ) – birinchi operandni ikkinchisiga bo‘lish uchun qo‘llaniladi. Standart bo‘lish amali int, uint, long, ulong, float, double va decimal tiplari uchun aniqlangan. Boshqa tipli kattaliklar uchun ham bo‘lish amalini qo‘llash mumkin, faqat ushbu tip uchun avtomatik o‘zgartirish amalga oshishi lozim bo‘lishi kerak. Natijaning tipi eng kamida int tipida bo‘ladi. Bo‘lish amali bajarilishida agar operandlar har ikkisi ham butun tipli bo‘lsa, natija avtomatik yaxlitlanadi. Agar bo‘luvchi 0 bo‘lsa, System.DivideByZeroException xatoligi generatsiya qilinadi. Agar operandlarning biri haqiqiy tipli bo‘lsa, natija haqiqiy son chiqadi va yaxlitlanmaydi. Qodiqli bo‘lish amali( % ) turli tiplar uchun turli formula bilan hisoblanadi. Agar operadlarning har ikkisi butun tipli bo‘lsa, natija x - (x / y) * y formula orqali hisoblanadi. Agar bo‘luvchi 0 ga teng bo‘lsa xatolik avtomatik tarzda generatsiya qilinadi. Agar operandlarning xech bo‘lmasa bittasi haqiqiy tipli bo‘lsa, natija x – n * y formula bilan hisoblanadi. Bu yerda n – soni - x ni y ga bo‘lishdan hosil bo‘lgan natijadan kichik yoki unga teng bo‘lgan eng katta butun son. Qo‘shish va ayirish Qo‘shish amali ( + )- ikki operandni qo‘shishdan hosil bo‘lgan natijani qaytaradi. Ayirish amali ( - ) ikki operandning ayirmasini ifodalaydi. Standart qo‘shish va ayirish amali int, uint, long, ulong, float, double va decimal tiplari uchun aniqlangan. Boshqa tipli kattaliklar uchun ham qo‘shish va ayirish amallarini qo‘llash mumkin, faqat ushbu tip uchun avtomatik o‘zgartirish amalga oshishi lozim bo‘lishi kerak. Natijaning tipi eng kamida int tipida bo‘ladi. Surish amallari Surish amallari ( << va >> ) – butun tipli operandlar uchun qo‘llaniladi. Surish amallari bajarilishi natijasida birinchi operandning ikkilik kodidagi razryadlarni ikkinchi operand qiymati barobarida o‘ngga yoki chapga suriladi. Chapga surish amalida ( << ) ko‘rsatilgan miqdordagi razryadga surishdan qolgan joylar 0 lar bilan to‘ldiriladi. Chapga surish amali sonni 2 ga ko‘paytirish amali bilan teng kuchli. O‘ngga surishda (>>) esa ko‘rsatilgan miqdordagi razryadga surish orqali ortiqcha razryadlar tashlab yuboriladi. O‘ngga surish amali sonni 2 ga bo‘lishga teng kuchli. Masalan: 4<<1 amali bajarilishi natijasida 8 soni xosil bo‘ladi. Chunki 4 sonining ikkilik koddagi qiymati 100 ga teng. Razryadlarni 1 xona chapga surish orqali 100 soni 1000 ga aylanadi. Bu esa o‘nlik sanoq sistemasida 8 ga teng. 16>>1 bajarilishi natijasida 8 soni hosil bo‘ladi. Chunki 16 sonining ikkilik sanoqsistemasidagi kodi 10000 ga teng. Razryadni 1 birlik o‘ngga surish natijasida eng oxirida 1 ta 0 soni tashlab yuboriladi va 1000 soni qoladi. Ushbu son esa o‘nlik sanoq sistemasida 8 ga teng. Manfiy sonlar uchun surish amallar musbat sonlarga nisbatan farqli natija beradi. Chunki sonning ishorasi alohida razryadni bildiradi. Standart surish amallari int, uint, long va ulong tiplari uchun qo‘llaniladi. Solishtirish amallari va tenglikni tekshirish amallari Solishtirish amallari( <, <=, >, >=, ==, != ) bajarilishi natijasida birinchi operand ikkinchisiga taqqoslanadi. Natija mantiqiy tipda olinadi. Solishtirish amallari va natijalar 4.2- jadvalda keltirilgan. 4.2-jadval. Solishtirish amallaridan olinuvchi natijalar Amal Natija x == y true, agar x operand y ga teng bo‘lsa, aks xolda false x != y true, agar x operand y operandga teng bo‘lmasa, aks xolda false x<y true, agar x operand y operanddan kichik bo‘lsa, aks xolda false x>y true, agar x operand y operanddan katta bo‘lsa, aks xolda false x <= y true, agar x operand y operanddan kichik yoki teng bo‘lsa, aks xolda false x >= y true, agar x operand y operanddan katta yoki teng bo‘lsa, aks xolda false Razryadli mantiqiy amallar Razryadli mantiqiy amallar ( &, |, ^ ) butun tipli operandlar uchun qo‘llanilib, operandlarning ikkilik sanoq sistemasidagi kodlari ustida bajariladi. Amal bajarilishi jarayonida operandlarning mos razryadlari ustida amallar bajariladi, ya’ni birinchi operandning birinchi biti ikkinchi operandning birinchi biti bilan, birinchi operandning ikkinchi biti ikkinchi operandning ikkinchi biti bilan va h. Razryadli konyunksiya ( & ) amalida har ikki operandning mos bitlarini ko‘paytiriladi. Amal operandlarning ikkilik sanoq sistemasidagi kodlari ustida bajariladi. Masalan: 4&5 amalining bajarilish jarayoni quyidagicha bo‘ladi: 4 sonining ikkilik kodi – 1000 5 sonining ikkilik kodi - 1001 (1*1=1, 0*1=0, 0*1=0 va 0*1=0)= 1000 ga teng. Razryadli dizyunksiya( | ) amalida har ikki operandning mos bitlarini qo‘shib chiqiladi. Amal operandlarning ikkilik sanoq sistemasidagi kodlari ustida bajariladi. Masalan: 4|5 amalining bajarilish jarayoni quyidagicha bo‘ladi: 4 sonining ikkilik kodi – 1000 5 sonining ikkilik kodi - 1001 (1+1=10, 0+1=1, 0+1=1 va 0+1=1)= 10111 ga teng. Razryadli-istisnoli YOKI amali( )da har ikki operandning qo‘shiladi. Qo‘shish jarayonida har ikki operand ikkilik kodlarining mos o‘rinda turganlar birbiridan farqli bo‘lgandagina ularning yig‘indisi 1 bo‘ladi, aks holda 0 bo‘ladi. Masalan: 4^5 amalining bajarilish jarayoni quyidagicha bo‘ladi: 4 sonining ikkilik kodi – 1000 5 sonining ikkilik kodi - 1001 (1+1=0, 0+1=1, 0+1=1 va 0+1=1)= 0111 ga teng. Mantiqiy amallar Mantiqiy VA(&&) va YOKI ( || ) amallari mantiqiy tipdagi operandlar uchun qo‘llaniladi. Amal natijasi ham mantiqiy tipda, true yoki false bo‘ladi. Mantiqiy VA(&&) amalining natijasi qachonki har ikki operandning qiymati true bo‘lgandagina true bo‘ladi, aks holda false bo‘ladi. Mantiqiy YOKI ( || ) amalining natijasi har ikki operanddan hech bo‘lmasa bittasining qiymati true bo‘lganda true bo‘ladi, aks holda false bo‘ladi. Shartli operator Shartli operatorda ( ? :) 3 ta operand ishtirok etadi. Shu sabali ushbu operatorni ternar operator ham deb ataladi. Sintaksisi: operand_1 ? operand_2 : operand_3 operand_1 – natijasi mantiqiy tipga ega bo‘lgan ifoda bo‘ladi. Agar ushbu ifodaning natijasi true ga teng bo‘lsa, natija sifatida operand_2 qiymati olinadi, aks xolda operand_3 qiymati natija bo‘ladi. Shartli operatorning tipi operand_2 va operand_3 larning tiplariga bog‘liq bo‘ladi. O‘zlashtirish amallari O‘zlashtirish amallari ( =, +=, -=, *= va sh.k.) bajarilishi natijasida o‘zgaruvchiga yangi qiymat uzatiladi. Ushbu amallardan dasturda tugallangan operator sifatida foydalanish mumkin. O‘zlashtirish amallarining sintaksisi: <o‘zgaruvchi> <amal belgisi> <ifoda> Oddiy o‘zlashtirish amali(=)ni o‘zlashtirish operatori deb ham yuritiladi. O‘zlashtirish operatorining bajarilish mexanizmi quyidagicha: avval ifoda hisoblanadi va natija o‘zgaruvchi nomi orqali ko‘rsatilgan adresdagi hotira qismiga joylanadi. Hotiraning ushbu qismida turgan avvalgi ma’lumot tozalanadi. Misollar: a = b + c / 2; x = 1; x = x + 0.5; O‘zlashtirish operatorining o‘ng tomonidagi ifodaning tipi chap tomondagi operand tipiga avtomatik(oshkor bo‘lmagan) ravishda o‘zgarish xususiyatiga ega bo‘lishi lozim. Ya’ni ifoda natijasining tipi o‘zgaruvchi tipi bilan mos yoki uning tarkibiga kiruvchi bo‘lishi kerak. Murakkab o‘zlashtirish amallari( +=, *=, /= va sh.k.) bajarilishi jarayonida amal belgisining o‘ng tomonidagi ifodani hisoblash jarayonida chap tomondagi o‘zgaruvchining joriy qiymatidan foydalaniladi. Masalan a += b da, qo‘shib o‘zlashtirish amalini bajarilish jarayonida o‘zlashtirish amalining o‘ng tarafidagi ifoda(b)ga chap tarafdagi operand(a)ning qiymati qo‘shiladi va natija chap tarafdagi operand(a)ga o‘zlashtiriladi. Ya’ni: a += b ifoda a = a + b ga teng kuchli. 4.4. Konsolli ilovalar, ma’lumotlarni kiritish va chiqarish. Har qanday ma’lumotlar bilan ishlashga mo‘ljallangan dastur ma’lumotlarni kiritish va chiqarishda aksariyat holatda tashqi qurilmalar bilan bevosita bog‘liq bo‘ladi. Kompyuterning standart kiritish va chiqarish qurilmalari klaviatura va ekran bilan bevosita ishlash uchun mo‘ljallangan muhit konsol deb yuritiladi. C# da ma’lumotlarni kiritish va chiqarish uchun operatorlari yo‘q. Ularning o‘rnida konsolli rejimda ishlash uchun standart obyektlar qo‘llaniladi. Konsol bilan ishlash uchun C# ning System nomlari makoni(kutubxonasi)ning Console sinfidan foydalaniladi. Quyidagi dasturni ko‘raylik: using System; namespace ConsoleApplication1 { class Class1 { static void Main() { int i = 3; double y = 4.12; decimal d = 600m; string s = "Vasya"; Console.WriteLine( "i = " + i ); // 1 Console.WriteLine( "s = " + s ); // 2 Console.WriteLine( "y = {0} \nd = {1}", y, d );//3 } } } Listing 5.1. Konsolli rejimda ma’lumot chiqarish Dastur natijasi: i=3 s = Vasya y = 4,12 d = 600 Yuqorida keltirilgan dasturda ma’lumotlarni ekranga chiqarish uchun Console sinfining WriteLine uslubidan foydalanilgan. WriteLine uslubi turli tipdagi literallar, o‘zgarmaslar va o‘zgaruvchilarni ekranga chiqarish uchun xizmat qiladi. Xuddi shu uslubga o‘xshash Console sinfida Write uslubi ham mavjud. Farqi: Write uslubida ekranga ma’lumot chiqarilgandan so‘ng, yangi kiritiluvchi yoki chiqariluvchi ma’lumot ana shu ekranga chiqqan ma’lumot davomidan ekranga chiqadi, WriteLine uslubida esa ma’lumotni ekranga chiqarilgandan so‘ng, yangi kiritiluvchi yoki chiqariluvchi ma’lumot yangi satrdan davom etadi. C# da bir xil nomli, lekin turli xil parametrlar bilan ishlovchi uslublar qayta yuklanuvchi deb ataladi. Kompilyator avtomatik tarzda qo‘llanilgan parametrlarga qarab kerakli uslubni o‘zi avtomatik tarzda aniqlab oladi. Yuqorida keltirilgan misolda //1 va //2 izohlari bilan ko‘rsatilgan qatorlarda WriteLine uslubi bitta parametrli uslubdir. Bunday uslubda ekranga chiqariluvchi ma’lumotlar + belgisi bilan bir-biriga ulab olinadi. //3 izohli qatorda esa WriteLine uslubining formatli varianti qo‘llanilgan. Console.WriteLine( "y = {0} \nd = {1}", y, d ) Bunday uslub qo‘llanilganda figurali qavslar ichida berilgan raqamlar, shu joyda nechanchi o‘rinda turgan parametr qiymati chiqishi kerakligini bildiradi. Parametrlar ro‘yxati qo‘shtirnoqdan keyin boshlanadi. Ularni, bilan bir-biridan ajratib qo‘yiladi. Ushbu misolda {0}- parametri o‘rniga y ning qiymati, {1} ning o‘rniga esa d ning qiymati ekranga chiqadi. \n – boshqarish belgisi bo‘lganligi sababli ekranga chiqmaydi, u mana shu yerdan keyingi ma’lumot yangi qatordan chiqarilishi kerakligini bildiradi. Konsolli ilovalarda ma’lumotni kiritish uchun Console sinfining Read, Readline, ReadKey uslublaridan foydalaniladi. Ma’lumotlarni ushbu uslublar bilan kiritilganda kiritiluvchi ma’lumotlar satrli tipda qabul qilinadi. Keyinchalik kiritiluvchi ma’lumotni Convert yoki Parse metodlari bilan kerakli tipga o‘zgartirib olinadi. Misol: using System; namespace ConsoleApplication1 { class Class1 { static void Main() { Console.WriteLine( "Matn kiriting:" ); string s = Console.ReadLine(); // 1 Console.WriteLine( "s = " + s ); Console.WriteLine( "Belgi kiriting:" ); char c = (char)Console.Read(); Console.ReadLine(); // 2 // 3 Console.WriteLine( "c = " + c ); string buf; // Raqamlarni kiritish uchun Console.WriteLine( "Butun son kiriting:" ); buf = Console.ReadLine(); int i = Convert.ToInt32( buf ); // 4 Console.WriteLine( i ); Console.WriteLine( "Haqiqiy son kiriting:" ); buf = Console.ReadLine(); double x = Convert.ToDouble( buf ); Console.WriteLine( x ); // 5 Console.WriteLine( " Haqiqiy son kiriting:" ); buf = Console.ReadLine(); double y = double.Parse( buf ); // 6 Console.WriteLine( y ); Console.WriteLine( " Haqiqiy son kiriting:" ); buf = Console.ReadLine(); decimal z = decimal.Parse( buf ); // 7 Console.WriteLine( z ); } } } //1 – izohli qator foydalanuvchidan matn kiritishni so‘raydi. Matnni uzunligi chegaralanmagan va Enter tugmasi bosilgunga qadar kiritishda davom etish mumkin. Enter tugmasi bosilgandan so‘ng kiritilgan matn s = dan keyin ekranga chiqariladi. //2 – operator bajarilganda foydalanuvchidan belgi kiritish talab qilinadi. Agar foydalanuvchi bir nechta belgi kiritib keyin Enter tugmasini bosganda, ushbu qatordan birinchi belgi ajratib olinadi. char tipiga avtomatik o‘zgartirish yo‘qligi sababli o‘zgartirish (char) yordamida amalga oshiriladi. //3-operator foydalanuvchidan shunchaki Enter tugmasini bosishni talab qiladi. Foydalanuvchi Enter ni bosgandan so‘ng c ning qiymati ekranga chiqariladi. //4- va //5- izohli qatorlarda foydalanuvchidan son kiritish talab qilinadi. Kiritilgan sonlar avval matnli o‘zgaruvchi buf ga o‘zlashtiriladi. So‘ngra Convert uslubi yordamida kerakli tipga oshkor o‘zgartiriladi. //6- va //7- izohli qatorlarda ham foydalanuvchidan son kiritish talab qilinadi. Kiritilgan sonlar avval matnli o‘zgaruvchi buf ga o‘zlashtiriladi. So‘ngra Parse uslubi yordamida kerakli tipga oshkor o‘zgartiriladi. Eslatma: Haqiqiy sonlarni kiritishda sonning kasr qismi operatsion tizimning regional sozlamalariga mos ravishda nuqta yoki vergul bilan ajratiladi. Kiritiluvchi nuqta yoki vergul regional sozlama bilan mos kelmasa xatolik yuzaga kelishi mumkin. O’zlashtirish uchun savollar. 1. Ifoda deb nimaga aytiladi? 2. Amal belgisiga misol keltiring va uni izohlang 3. Shartli operatordan foydalanish sintaksisi qanday? 4. Murakkab o`zlashtirish amallarini sanang 5. Surish amallarini tavsiflang 5-Ma’ruza: Turni boshqa turga keltirish. Reja: 1. Turlar 2. Toraytiruvchi va kengaytiruvchi transformatsiyalar 3. Aniq va yashirin konvertatsiyalar Tayanch so’z va iboralar: Tur, kompilator, transformatsiya, toraytiruvchi transformatsiya, kengaytiruvchi transformatsiya, konvertatsiya, aniq konvertatsiya, yashirin konvertatsiya 5.1. Turlar. Ma'lumotlar turlarini ko'rib chiqishda ma'lum bir turdagi qanday qiymatlarga ega bo'lishi va qancha bayt xotirani egallashi ko'rsatilgan. Oxirgi mavzuda arifmetik amallar ko'rib chiqildi. Endi har xil turdagi ma'lumotlarga qo'shish amalini qo'llaymiz: 1 byte a = 4; 2 int b = a + 70; Operatsiya natijasi, kutilganidek, 74 raqamidir. Ammo endi bayt tipidagi ikkita obyektga qo'shishni qo'llashga harakat qilaylik : 1 byte a = 4; 2 byte b = a + 70; // xató Bu yerda faqat qo'shish natijasini oladigan o'zgaruvchining turi o'zgargan - int dan baytga. Biroq, dasturni kompilyatsiya qilinganda, kompilator xatolik haqida xabar beradi. Va agar Visual Studio'da ishlayonayotgan bo'lsa, muhit ikkinchi qatorni qizil chiziq bilan chizib, unda xatolik borligini ko'rsatadi. Ishlayotganda, ma'lum bir turdagi saqlashi mumkin bo'lgan qiymatlar oralig'ini hisobga olish kerak. Ammo bu holda, olinishi kutilayotgan 74 raqami bayt tipidagi qiymatlar oralig'ida, shunga qaramay, xatolik mavjud. Chunki, qo‘shish (va ayirish) operatsiyasi, agar operatsiya int dan kichik yoki unga teng bo‘lgan butun sonli ma’lumotlar turlarini (ya’ni bayt, short, int turlarini) o‘z ichiga olsa, int tipidagi qiymatni qaytaradi. Shuning uchun operatsiya natijasi a + 70 xotirada uzunligi 4 bayt bo'lgan obyekt bo'ladi. Keyin bu obyektni bayt tipiga ega bo'lgan va xotirada 1 baytni egallagan b o'zgaruvchisiga belgilashga harakat qilamiz. Va bu vaziyatdan chiqish uchun siz turdagi konvertatsiya operatsiyasini qo'llashingiz kerak. Turni o'zgartirish operatsiyasi qavslar ichida qiymat o'zgartirilishi kerak bo'lgan turni ko'rsatishni o'z ichiga oladi: Shunday qilib, turni o'zgartirish operatsiyasini qo'llash orqali oldingi misolni o'zgartiramiz: 1 byte a = 4; 2 byte b = (byte)(a + 70); 5.2 Toraytiruvchi va kengaytiruvchi transformatsiyalar Transformatsiyalar torayuvchi (torayuvchi) va kengaytiruvchi (kengayuvchi) bo'lishi mumkin. Kengaytirilgan konversiyalar xotiradagi ob'ekt hajmini kengaytiradi. Misol uchun: bitta byte a = 4; // 0000100 2 ushort b = a; // 000000000000100 Bunda ushort tipidagi o'zgaruvchiga bayt tipidagi qiymat beriladi. Bayt turi 1 baytni (8 bit) egallaydi va a o'zgaruvchining ikkilik qiymati quyidagicha ifodalanishi mumkin: 1 00000100 Qisqa qiymat 2 bayt (16 bit). Va b o'zgaruvchini tayinlashda a o'zgaruvchining qiymati 2 baytgacha kengaytiriladi 1 0000000000000100 Ya'ni, 8 bitni egallagan qiymat 16 bitgacha kengaytiriladi . Toraytiruvchi konvertatsiyalar esa, qiymatni kamroq bitlik turiga toraytiradi. Maqolaning ikkinchi ro'yxatida biz faqat toraytirilgan o'zgarishlar bilan shug'ullandik: 1 ushort a = 4; 2 byte b = (byte) a; Bu erda 8 bitni egallagan b o'zgaruvchisiga 16 bitni egallagan ushort qiymati beriladi. Ya'ni, 0000000000000100 bizdan olamiz 00000100. Shunday qilib, qiymat 16 bitdan (2 bayt) 8 bitgacha (1 bayt) torayadi. 5.3 Aniq va yashirin konvertatsiyalar Yashirin konvertatsiyalar Konversiyalarni kengaytirganda, kompilyator biz uchun barcha ma'lumotlarni o'zgartirishni amalga oshirdi, ya'ni konvertatsiyalar yashirin konvertatsiyalar edi . Bunday o'zgarishlar hech qanday qiyinchilik tug'dirmaydi. Shunga qaramay, bunday o'zgarishlarning umumiy mexanikasi haqida bir necha so'z aytish kerak. Agar konversiya kichikroq bit chuqurligining belgisiz turidan kattaroq bit kengligining belgisiz turiga o'tkazilsa, u holda qiymatlari 0 bo'lgan qo'shimcha bitlar qo'shiladi. Bu nol to'ldirish yoki nol kengaytma deyiladi. 1 byte a = 4; // 0000100 2 ushort b = a; // 000000000000100 Agar belgilangan turga o'tkazish amalga oshirilsa, agar raqam musbat bo'lsa, bit tasviri nol bilan to'ldiriladi, agar raqam manfiy bo'lsa. Raqamning oxirgi bitida ishora biti mavjud - musbat raqamlar uchun 0 va manfiy raqamlar uchun 1. Qo'shilgan bitlarga kengaytirilganda, belgi biti kompilyatsiya qilinadi. Musbat raqamni aylantirishni o'ylab ko'ring: 1 sbyte a = 4; // 0000100 2 short b = a; // 000000000000100 Manfiy raqamni aylantirish: 1 sbyte a = -4; // 1111100 2 short b = a; // 111111111111100 Aniq konvertatsiyalar Aniq konvertatsiyalar ( aniq konvertatsiya ) bilan biz o'zimiz konvertatsiya operatsiyasini (operatsiyani ()) qo'llashimiz kerak. Turni o'zgartirish operatsiyasining mohiyati shundan iboratki, qiymatdan oldin qavs ichida berilgan qiymat qaysi turdagi bo'lishi kerakligi ko'rsatilgan: 1 int a = 4; 2 int b = 6; 3 byte c = (byte)(a+b); Kompilyator kichikroq bit kengligi bo'lgan turdan kattaroq bit kengligiga ega bo'lgan turga kengaytiruvchi konvertatsiyalarni amalga oshiradi. Bu quyidagi transformatsiyalar zanjiri bo'lishi mumkin: bayt -> short -> int -> long -> decimal int -> double short -> float -> double char -> int Barcha xavfsiz avtomatik konvertatsiyalarni quyidagi jadvalda tasvirlash mumkin: 5.1-jadval Turi Qaysi turlarga xavfsiz tarzda aylantirilishi mumkin bayt short, ushort, int, uint, long, ulong, float, double, kasr sbyte short, int, long, float, double, decimal short int, long, float, double, decimal ushort int, uint, long, ulong, float, double, decimal int long, float, double, decimal uint long, ulong, float, double, decimal long float, double, decimal ulong float, double, decimal float Double char ushort, int, uint, long, ulong, float, double, decimal Aks holda, aniq turdagi konversiyalardan foydalanish kerak. Shuni ham ta'kidlash kerakki, ikkilik va o'nlik kasr ma'lumotlarini saqlashi mumkin va o'nlik ikki barobardan kattaroq bit chuqurligiga ega bo'lishiga qaramay, siz baribir ikkilamchi qiymatni o'nlik kasr turiga aniq o'tkazishingiz kerak: 1 double a = 4.0; 2 decimal b = (decimal)a; Ma'lumotlar yo'qolishi va tekshirilgan kalit so'z Boshqa vaziyatni ko'rib chiqing, masalan, quyidagi holatda bo'ladi: 1 int a = 33; 2 int b = 600; 3 byte c = (byte)(a+b); 4 Console.WriteLine(c); // 121 Natijada 121 bo'ladi, shuning uchun 633 bayt turi uchun diapazondan tashqarida va yuqori bitlar kesiladi. Natijada 121 raqami bo'ladi. Shuning uchun konvertatsiya qilishda buni hisobga olish kerak. Va bu holda, biz jami 255 dan ko'p bo'lmagan raqamni beradigan a va b raqamlarini olishimiz mumkin yoki biz bayt o'rniga boshqa ma'lumot turini tanlashimiz mumkin, masalan, int. Biroq, vaziyatlar boshqacha bo'lishi mumkin. Biz a va b qiymatlari qanday bo'lishini aniq bilmasligimiz mumkin. Va bunday vaziyatlardan qochish uchun C# da kalit so'z mavjud checked: 1 try 2 { 3 int a = 33; 4 int b = 600; 5 byte c = checked((byte)(a + b)); 6 Console.WriteLine(c); 7 } 8 catch (OverflowException ex) 9 { 10 11 Console.WriteLine(ex.Message); } Kalit so'zdan foydalanganda, checkeddastur to'lib-toshgan istisnoni chiqaradi. Shuning uchun, bu holda, try...catch konstruktsiyasi uni qayta ishlash uchun ishlatiladi. Biz ushbu konstruksiya va istisno holatlarini keyinroq batafsil ko‘rib chiqamiz, ammo hozircha biz bilishimiz kerakki, biz try blokida xatolik yuzaga kelishi mumkin bo‘lgan harakatlarni o‘z ichiga olamiz va xatoni catch blokida hal qilish mumkin. 5.1.-rasm Tiplarni oshkor bo‘lmagan arifmetik o‘zgartirish ketma-ketligi. O’zlashtirish uchun savollar. 1. Turlarning ahamiyati 2. Transformatsiyalashning qanday usullari mavjud? 3. Konvertatsiya qilish usullari 4. Aniq konvertatsiyalar qanday amalga oshiriladi? 5. Yashirin konvertatsiyalar qanday amalga oshiriladi? 6-Ma`ruza: Shart operatorlari. Reja: 1. if-else konstruksiyasi(if operatori). 2. switch-case konstruksiyasi 3. Qisqa shartli(ternar) operator. Tayanch so’z va iboralar: shart, if operatori, if-else konstruksiyasi, switchcase konstruksiyasi, ternar operator 6.1. if-else konstruksiyasi(if operatori). Tarmoqlanuvchi jarayonlar hisoblash jarayonini biror shartga ko‘ra ikki tomonga tarmoqlanishini ta’minlaydi. Tarmoqlanuvchi jarayonning strukturali sxemasi bizlarga blok-sxemalardan tanish (6.1-rasm). true 1-operator(lar) Tekshiriluv chi shart false 2-operator(lar) 6.1-rasm. Tarmoqlanuvchi jarayonning strukturali sxemasi Tarmoqlanuvchi jarayonlarni hisoblash operatorlaridan biri bu if-operatoridir. Sintaksisi: If(shart) {1-blok. agar shart bajarilsa bajariluvchi operator(lar);} [else] {2-blok. agar shart bajarilmasa bajariluvchi operator(lar);} Bunda birinchi navbatda shart o‘rnida qo‘llaniluvchi mantiqiy ifoda tekshiriladi. Agar ushbu shart bajarilsa, 1 blokdagi operator(lar) bajariladi, aks holda 2 blokdagi operatorlar bajariladi. If operatorining o‘zi yetarli bo‘lsa, else – qismi yozilmasligi ham mumkin. Agar shart bajarilganda yoki bajarilmaganda bajariluvchi opertor bitta bo‘lsa, blok qavslari{}ni ishlatmasa ham bo‘ladi. Masalan: ... int i=16;// if (i>10) // Agar i 10 dan katta bo‘lsa --i; //i=i-1 else //Aks xolda i++ // i=i+1 ... Agar shart tekshirilayotgan o‘zgaruvchi(yoki o‘zgarmas) sonli tip bo‘lsa, va uni 0 dan farqliligi tekshirilsa, u xolda quyidagicha yozish mumkin. ... if (i) // Agar i<>0 bo‘lsa i++; //i=i+1 else //Aks xolda i-- // i=i-1 ... Agar tekshiriluvchi shartning inkori bajarilish lozim bo‘lsa, quyidagicha yoziladi: ... if !(i>10) // Agar i 10 dan katta bo‘lmasa i--; //i=i-1 else //Aks xolda i++ // i=i+1 ... Agar tekshiriluvchi shartlar bir nechta bo‘lsa, ularni mantiqiy shartli amallar bilan bir-biriga bog‘lash lozim. Masalan: ... if(a<b && (a>d || a==0)) b++; else{ b*=a; a=0; } ... Nishonga otilgan o‘qlar bo‘yicha to‘plangan ochkolarni ularning kordinatasiga nisbatan hisoblash dasturini ko‘rib chiqaylik(6.1.2-rasm). 6.2-rasm. Nishon //X – Nishonga tekkan o‘qning x kordinatasi //Y - Nishonga tekkan o‘qning y kordinatasi using System; namespace ConsoleApplication1 { class Class1 { static void Main() { Console.WriteLine("X – Nishonga tekkan o‘qning x kordinatasi"); Console.WriteLine("Y – Nishonga tekkan o‘qning y kordinatasi"); Console.WriteLine( " x ni kiriting:" ); double x = Convert.ToDouble(Console.ReadLine() ); Console.WriteLine( " y ni kiriting:" ); double y = double.Parse( Console.ReadLine() ); int kol = 0; if ( x * x + y * y < 1 ) kol = 2; else if ( x * x + y * y < 4 ) kol = 1; Console.WriteLine( "Rezultat = {0} ochko", kol ); } } } Jadval 6.1. Nishonga otilgan o‘qlar bo‘yicha ochkoni hisoblash dasturi If..else konstruksiyasi ichida yana bir nechta If..else konstruksiyasin qo‘llash mumkin. Lekin bu dasturni murakkablashib ketishiga olib kelishi mumkin. Ichma-ich joylashgan If..else konstruksiyasiga misol tariqasida 6.1.2 listingda kiritilgan 3 ta sondan eng katta va eng kichigini topish dasturi keltirilgan. using System; namespace uch_sondan_topish { class Program { static void Main(string[] args) { double a, b, c, max=0, min=0; //string smax, smin; Console.Write("A="); a = double.Parse(Console.ReadLine()); Console.Write("B="); b = double.Parse(Console.ReadLine()); Console.Write("C="); c = double.Parse(Console.ReadLine()); if ((a == b) && (b == c)) Console.WriteLine("a, b, c sonlari o'zaro teng!"); else { if (a > b) { max = a; min = b;} else if (a < b) {max = b; min = a;} //****2 else {max = b; min = b;} //*********************** if (max < c)max = c; else if (min > c)min = c; else if (max == c)max = c; else if (min == c)min = c; } Console.WriteLine("MAX=" + max + ", MIN=" + min + ",\n "); Console.ReadKey(); } } } Jadval 6.2. 3 ta sondan eng katta va eng kichigini topish dasturi 6.2. Qisqa shartli operator Ushbu operator bilan biz avvalgi ma’ruzalarimizda tanishib o‘tgan edik. Ushbu operatorni ternar operator ham deb ataladi. Odatda ternar operatoridan shartga mos ravishda bajariluvchi operatorlar soni bittadan ko‘p bo‘lmaganda foydalanish qulaydir. Sintaksisi: <shart ? [rost bo‘lsa, operator]:[yolg‘on bo‘lsa, operator]> Masalan: int i=10; Console.WriteLine(i==10 ? “i = 10”:“i <> 10”); Console.WriteLine(i<20 ? “i < 20”:“i >= 20”); If..else konstruksiyasi va ternar operatorlaridan dasturlarda foydalanishga misollar. 1-Misol. Kiritilgan sonlarni boshqa bir songa qoldiqlarsiz bo‘linishini tekshirish dasturini tuzishda if..else va ternar operatorlaridan foydalanish. using System; namespace qoldiqsiz_bolinish_consol { class Program { static void Main(string[] args) { Console.Write("Bol'inuvchi sonni kiriting:"); double b = int.Parse(Console.ReadLine()); //2 ga bo‘linishini tekshirish if (b > 2) { Console.WriteLine(b % 2 == 0 ? b + " soni 2 ga qoldiqsiz bo'linadi!\n " + b + "/2=" + b / 2 : b + " soni 2 ga qoldiqsiz bo'linmaydi!\n " + b + " ni 2 ga bolishda butun qismi " + (b - (b % 2)) / 2 + " qoldiq qismi = " + b % 2); } else { Console.WriteLine(b+" son 2 dan kichik, shu sababli u 2 ga qoldiqsiz bo'linmaydi!"); } Console.WriteLine(); //3 ga bo‘linishini tekshirish if (b > 3) { Console.WriteLine(b % 3 == 0 ? b + " soni 3 ga qoldiqsiz bo'linadi!\n " + b + "/3=" + b / 3 : b + " soni 3 ga qoldiqsiz bo'linmaydi!\n " + b + " ni 3 ga bolishda butun qismi " + (b - (b % 3)) / 3 + " qoldiq qismi = " + b % 3); } else { Console.WriteLine(b + " son 3 dan kichik, shu sababli u 3 ga qoldiqsiz bo'linmaydi!"); } Console.WriteLine(); //4 ga bo‘linishini tekshirish if (b > 4) { Console.WriteLine(b % 4 == 0 ? b + " soni 4 ga qoldiqsiz bo'linadi!\n " + b + "/4=" + b / 4 : b + " soni 4 ga qoldiqsiz bo'linmaydi!\n " + b + " ni 4 ga bolishda butun qismi " + (b - (b % 4)) / 4 + " qoldiq qismi = " + b % 4); } else { Console.WriteLine(b + " son 4 dan kichik, shu sababli u 4 ga qoldiqsiz bo'linmaydi!"); } Console.WriteLine(); //5 ga bo‘linishini tekshirish if (b > 5) { Console.WriteLine(b % 5 == 0 ? b + " soni 5 ga qoldiqsiz bo'linadi!\n " + b + "/5=" + b / 5 : b + " soni 5 ga qoldiqsiz bo'linmaydi!\n " + b + " ni 5 ga bolishda butun qismi " + (b - (b % 5)) / 5 + " qoldiq qismi = " + b % 5); } else { Console.WriteLine(b + " son 5 dan kichik, shu sababli u 5 ga qoldiqsiz bo'linmaydi!"); } Console.WriteLine(); Console.ReadKey(); } } } Jadval 6.2.-Ternar: Kiritilgan sonni 2 dan 5 gacha bo‘lgan sonlarga qoldiqsiz bo‘linish yoki bo‘linmasligini ko‘rsatuvchi dasturini. 2-Misol. Kiritilgan ikki sonni solishtirish uchun if..else va ternar operatorlaridan foydalanib dastur tuzing. using System; namespace kattasini_topish_consol { class Program { static void Main(string[] args) { l1: Console.Write("Birinchi sonni kiriting: "); int a = int.Parse(Console.ReadLine()); Console.Write("Ikkinchi sonni kiriting: "); int b=int.Parse(Console.ReadLine());. //Qisqa shart operatori bilan a va b larni teng emasligini tekshiramiz Console.WriteLine(a!=b ? a+" soni "+b+" soniga teng emas": a+" soni "+b+" soniga teng"); //Agar a son b songa tengligi yolg‘on bo‘lsa, if (!(a==b)) { if(a>b) Console.WriteLine(a+" > "+b); else Console.WriteLine(a+" < "+b); } //Bitta bo‘sh qator tashlash Console.WriteLine(); //Kerakli tugmalar bosish haqida xabar chiqarish Console.Write("\n Takrorlash uchun R ni bosing\n Dasturdan chiqish uchun X ni bosing;"); char x; l0: //x ga bosilgan tugma qiymatini o‘zlashtirish x=Console.ReadKey().KeyChar; if ((x == 'x') || (x == 'X')) goto l2; // x tugma bosilsa l2 metkaga o‘tish else if ((x == 'r') || (x == 'R')) { Console.Clear(); goto l1; //r tugma bosilsa l1 metkaga o‘tish } goto l0; //Boshqa tugmalar bosilsa l0 metkaga o‘tilsin. l2:; // dastur oxiri, tugashi } } } Jadval 6.3. Kiritilgan ikki sonni solishtirish dasturi. 6.3.switch-case konstruksiyasi switch-case konstruksiyasini variant tanlash operatori deb ham atash mumkin. Agar argumentni solishtiriluvchi qiymatlari bir nechta bo‘lsa, ushbu operatordan foydalanish juda qulaydir. Sintaksisi: ... switch(argument) { case <a1> : [operator(lar)..]; break; case <a2> : [operator(lar)..]; break; ... [default: [operator(lar)..]; break;] } Bu yerda: <> - ichidagi element majburiy ekanligini bildiradi; [] - ichidagi element majburiy emasligini bildiradi; argument – qiymati tekshiriluvchi o‘zgaruvchi yoki o‘zgarmas yoki ifoda; [operator(lar)..]- shartga mos ravishda bajariluvchi operator(lar); a1, a2..- tekshiriluvchi shart, ya’ni argument a1(mos ravishda a2 ga, a3 ga va h.) ga teng bo‘lsa; default – case lar yordamida tekshirilgan birorta shart bajarilmasa, bajarilishi lozim bo‘lgan kodni bildiradi. break – dastur, konstruksiya ichidagi keyingi qatorlarni bajarishga o‘tib ketib qolmasligini ta’minlash uchun konstruksiyadan chiqib ketish maqsadida ishlatiladi. Ushbu operator o‘rnida goto operatoridan ham foydalanish mumkin. Ishlash rejimi quyidagicha: switch xizmatchi so‘zidan keyin yozilgan qavs ichidagi ifodani tekshiriladi. Ushbu ifoda qiymati navbatma-navbat case metkasi bilan berilgan qiymatlar(a1, a2 va h.)ga solishtiriladi. Agar ular teng bo‘lsa,shu case bloki ichida yozilgan operator(lar) bajariladi. Misol: Console.WriteLine("Y yoki N tugmalaridan birini bosing"); char selection; selection = Console.ReadKey().KeyChar; switch (selection) { case "Y": Console.WriteLine("Siz Y tugmasini bosdingiz!"); break; case "N": Console.WriteLine("Siz N tugmasini bosdingiz!"); break; default: Console.WriteLine("Siz boshqa tugmani bosdingiz!"); break; } Jadval 6.4. Bosilgan tugmani aniqlash Quyidagi listingda switch-case konstruksiyasidan foydalanib oddiy kalkulyator dasturiga misol keltirilgan. using System; namespace ConsoleApplication1 { class Class1 { static void Main() { string buf; double a, b, res; Console.WriteLine( "Birinchi operandni kiriting:" ); a = double.Parse( Console.ReadLine() ); Console.WriteLine( "Amal belgisini kiriting" ); char op = (char)Console.Read(); Console.ReadLine(); Console.WriteLine( "Ikkinchi operandni kiriting:" ); b = double.Parse( Console.ReadLine() ); bool ok = true; switch (op) { case '+' : res = a + b; break; case '-' : res = a - b; break; case '*' : res = a * b; break; case '/' : res = a / b; break; default : res = double.NaN; ok = false; break; } if (ok) Console.WriteLine( "Natija: " + res ); else Console.WriteLine( "Noto‘g‘ri amal" ); } } } Jadval 6.5. Kalkulyator dasturi O’zlashtirish uchun savollar. 1. To`liq tarmoqlanish deganda nimani tushunasiz? 2. To`liq hamda to`liqsiz tarmoqlanish operatorlari qanday farqlanadi? 3. Ternar operatorining if-else dan farqi nimada? 4. Switch case konstruksiyasi qanday qo`llaniladi? 5. Switch case konstruksiyasida default hamda breakning qo`llanilishi 7-Ma`ruza: Takrorlash operatorlari. 1. Takrorlash operatorlari 2. Parametrli takrorlash operatori – for() konstruksiyasi 3. forech operatori 4. while va do..while operatorlari 5. Boshqaruvni uzatish operatorlari: goto, break, continue va return Tayanch so’z va iboralar: for() konstruksiyasi, foreach operatori, while operatori, do while operatori, goto, break, continue, return 7.1. Takrorlash operatorlar Takrorlash operatorlari bir necha marta takrorlanuvchi jarayonlarni hisoblash uchun qo‘llaniladi. Takrorlanuvchi jarayonlarni strukturali sxemasining blok sxema ko‘rinishi 7.1-rasmda keltirilgan. Boshlang`ich ma`lumtlar Boshlang`ich ma`lumtlar operatorlar Shartli ifoda Sikl parametrini o`zgartirish operatorlar Shartli ifoda Sikl parametrini o`zgartirish 7.1-rasm. Takrorlanuvchi jarayonning strukturali sxemasi Boshlang‘ich ma’lumotlar - takrorlanuvchi jarayonni tashkil etish uchun zarur bo‘lgan ma’lumotlardir; Shartli ifoda - takrorlanish davom etishini va tugallanishini belgilab beruvchi, takrorlanish parametrini tekshiruvchi mantiqiy ifoda. Ushbu shart sikl boshida ham bo‘lishi mumkin, oxirida ham bo‘lishi mumkin; Operatorlar – takroran bajariluvchi operator yoki operatorlar to‘plami, sikl tanasi; Takrorlanish parametrini o‘zgarishi-bu odatda takrorlanish qadami bo‘lib, u har bir iteratsiyada o‘zgaradi va shartli ifodada tekshiriladi. Agar takrorlanish parametri butun son bo‘lsa, uni hisoblagich(schyotchik) deb ham ataladi. Takrorlanuvchi jarayonning bir marta takrorlanishi iteratsiya deb ataladi. Takrorlanish jarayonini tezkorlik bilan joriy iteratsiyada to‘htatish mumkin. Buning uchun boshqaruvni uzatish opertaorlari break, continue, return va goto lardan foydalaniladi. Lekin sikl tashqarisidan turib uning ichiga boshqaruvni uzatish taqiqlanadi. 7.2. Parametrli takrorlash operatori – for() konstruksiyasi Sintaksisi: for([initsializatsiya-schyotchik]<;> [shartli ifoda]<;> [o‘zgarish qadami]) { operator(lar)... } Bu yerda: initsializatsiya-schyotchik – takrorlanish parametrining boshlang‘ich qiymatini o‘rnatish, ya’ni initsializatsiya qilish uchun yoziladi. Ushbu qismda bir vaqtning o‘zida bir yoki bir nechta o‘zgaruvchini boshlang‘ich qiymatini initsializatsiya qilib ketish mumkin. Agar boshlang‘ich qiymati initsializatsiya qilinuvchi o‘zgaruvchilar bir nechta bo‘lsa ular vergul bilan ajratib yoziladi. Masalan: for ( int i = 0, j = 20; ... Shartli ifoda takrorlanishni davom etishini yoki tugallanishini tekshiruvchi maniqiy ifoda. Ushbu ifodaning qiymati true bo‘lsa, takrorlanish jarayoni davom etadi va aksincha false bo‘lsa tugallanadi. O‘zgarishsh qadami – takrorlanish parametrining har bir iteratsiyada o‘zgarib borishini taminlovchi ifoda. Ushbu ifoda bir nechta bo‘lsa ular vergul bilan ajratib yoziladi. Masalan: for ( int i = 0, j = 20; i < 5 && j > 10; i++, j-- ) ... for konstruksiyasining yuqorida sanab o‘tilgan 3 ta parametrlarni ixtiyoriy birortasidan yoki umuman foydalanmaslik mumkin. Lekin uning o‘rnini bildiruvchi nuqtali vergul(;)larni o‘z o‘rnida qo‘yib ketilishi lozim. Masalan: int i = 0; for (; ;) { Console.WriteLine("{0}ning kvadrati={1}", ++i, i * i); System.Threading.Thread.Sleep(500); } Yuqoridagi misolda initsializatsiya qilinuvchi va takrorlanishni to‘xtatuvchi shart ko‘rsatilmagan. Shu sababli sikl xatolik yuzaga kelmaguncha davom etaveradi. 0-9 gacha bo‘lgan sonlarning kvadratlarini chop qilish uchun for konstruksiyasi quyidagicha yoziladi: for(int i=0; i<9; i++ ) { Console.WriteLine(“{0} sonining kvadrati {1} ga teng”,i,i*i); } Quyidgi misol esa, yuqorida keltirilgan misolga ekvivalentdir. int i = 0; for (; i<9;) { Console.WriteLine("("{0}ning kvadrati={1}", ++i, i * i); } Bizga quyidagi funksiya berilgan bo‘lsin. 𝑥, 𝑎𝑔𝑎𝑟 𝑥 < 0 𝑦 = (𝑡𝑥, 𝑎𝑔𝑎𝑟 0 ≤ 𝑥 < 10). 2𝑡, 𝑎𝑔𝑎𝑟 𝑥 ≥ 10 𝐵𝑢 𝑦𝑒𝑟𝑑𝑎 𝑥𝜖(−2. .12); 𝑡 = 2 O‘zgarish qadami 2 bo‘lganda, [-2..12] gacha oraliqda uning funksiyaga mos ravishda X argumentning qiymatlarini chop qiluvchi dastur 7.1-listingda keltirilgan. X argumentning boshlang‘ich qiymatini Xn, oxirgi qiymatini Xk, o‘zgarish qadamini dx bilan belgilab olamiz. using System; namespace ConsoleApplication1 { class Class1 { static void Main() { double Xn = -2, Xk = 12, dX = 2, t = 2, y; Console.WriteLine( "| x | y |"); // qiymatlarni chop qilish uchun jadval sarlavxasi for ( double x = Xn; x <= Xk; x += dX ) { y = t; if ( x >= 0 && x < 10 ) y = t * x; if ( x >= 10 ) y = 2 * t; Console.WriteLine( "| {0,6} | {1,6} |", x, y ); } } } } Listing 7.1. for konstruksiyasidan foydalangan holda funksiya qiymatini hisoblash dasturi. 7.3. foreach operatori Ushbu operator massiv va unga o‘xshash kontaynerlardan ma’lumotlarni o‘qish uchun ishlatiladi. Sintaksisi: foreach(<kontayner tipi> <o‘zgaruvchi> in <kontayner>) bu yerda: <kontayner_tipi> - ichidan elementining qiymati o‘qib olinayotgan massiv yoki konteynerli o‘zgaruvchining tipi. <o‘zgaruvchi> - massiv yoki konteynerli o‘zgaruvchi elementining qiymatini o‘zlashtirib oluvchi o‘zgaruvchi. <kontayner> -elementlarining qiymati o‘qib olinuvchi massiv yoki konteynerli o‘zgaruvchi. Misol: int[] array = new int[] { 1, 2, 3, 4, 5 };//massiv foreach (int i in array) { Console.WriteLine(i); } Yuqoridagi misolda kontayner sifatida int tipidagi array nomli massiv dan foydalanilyapti, shu sababli int tipidagi i nomli o‘zgaruvchini initsializatsiya qilib olinyapti. Ushbu sikl avtomatik tarzda kontaynerning barcha elementlarini navbatma navbat o‘qiydi. 7.4. while va do..while konstruksiyalari. while operatori - shartni avval tekshirib olib so‘ngra, sikl tanasini bajarishga o‘tadi. Sintaksisi: while (shartli ifoda) { … operator(lar)… } Bu yerda: shartli ifoda – takrorlashni tugallanishini yoki davom etishini belgilovchi mantiqiy ifoda, u har bir iteratsiyadan oldin tekshiriladi. Ushbu ifodaning qiymati true bo‘lsa, takrorlanish jarayoni davom etadi va aksincha false bo‘lsa takrorlash tugallanadi. ; operator(lar)- sikl tanasi. Misol: int i = 6; while (i > 0) { Console.WriteLine(i); i--; } 7.1-rasmda keltirilgan funksiyani while takrorlash konstruksiyasi orqali hisoblash dasturi 7.2-listingda keltirilgan. using System; namespace ConsoleApplication1 { class Class1 { static void Main() { double Xn = -2, Xk = 12, dX = 2, t = 2, y; Console.WriteLine( "| x | y |" ); double x = Xn; while ( x <= Xk ) { y = t; if ( x >= 0 && x < 10 ) y = t * x; if ( x >= 10 ) y = 2 * t; Console.WriteLine( "| {0,6} | {1,6} |", x, y ); x += dX; } } } } Listing 7.2. while konstruksiyasidan foydalangan holda funksiya qiymatini hisoblash dasturi. do..while operatori Ushbu takrorlash jarayoni eng kamida bir marta takrorlanadi. Chunki takrorlashni sharti sikl tanasidan so‘ng tekshiriladi. Sintaksisi: do { … operator(lar)… } while (shartli ifoda); Bu yerda: operator(lar)- sikl tanasi. shartli ifoda – takrorlashni tugallanishini yoki davom etishini belgilovchi mantiqiy ifoda, u har bir iteratsiyadan oldin tekshiriladi. Ushbu ifodaning qiymati true bo‘lsa, takrorlanish jarayoni davom etadi va aksincha false bo‘lsa takrorlash tugallanadi. ; Misol: int i = 6; do { Console.WriteLine(i); i--; } while (i > 0); Ushbu operatordan takrorlanish jarayoni hech bo‘lmaganda bir marta bajarilishi shart bo‘lgan masalalarni hal qilishda qo‘llaniladi. 7.3-listingda y tugmasi bosilmagunga qadar ekranga “Shokolad sotib olsizmi ?” yozuvini chiqaruvchi dastur matni keltirilgan. using System; namespace ConsoleApplication1 { class Class1 { static void Main() { char answer; do { Console.WriteLine( " Shokolad sotib olsizmi ?" ); answer = (char) Console.Read(); Console.ReadLine(); } while ( answer != 'y' ); } } } Listing 7.3. Bosilgan tugmani tekshirish 7.5. Boshqaruvni uzatish operatorlari Boshqaruvni uzatish operatorlari dasturning bajarilish ketma-ketligini o‘zgartirish uchun qo‘llaniladi. C# da beshta boshqaruvni uzatish operatori mavjud: • Shartsiz o‘tish operatori - goto ; • Takrorlash jarayonidan chiqish operatori - break ; • Yozilgan joydan joriy iteratsiyani to‘htatib, keyingi iteratsiyaga o‘tish operatori - continue ; • Funksiyadan chiqish operatori return ; • Istisnoli xolatni generatsiya qiluvchi operator - throw. Ushbu operatorlar ular yozilgan blok ichidan shu blok tashqarisiga boshqaruvni uzatish uchun qo‘llaniladi. goto operatori Shartsiz o‘tish operatori – goto dan quyidagi uchta formasi mavjud: goto metka; Bu formadagi goto operatori boshqaruvni metka bilan belgilab qo‘yilgan biror qatorga o‘tkazish uchun qo‘llaniladi. Faqat ushbu metka goto operatorining «ta’sir doirasi»dan tashqarida bo‘lmasligi lozim. goto case o‘zgarmas ifoda; va goto default; formalari tarmoilanish(variant tanlash) operatori switch konstruksiyasi ichida qo‘llanilib, boshqaruvni ko‘rsatilgan case qatoriga yoki defaul qatoriga o‘tkazish uchun xizmat qiladi. break operatori Ba’zi xollarda sikl oxiriga yetishini kutmasdan sikl tanasi(bloki)dan chiqib ketish lozim bo‘ladi. Bunday xollarda break operatoridan foydalaniladi. Misol uchun quyida keltirilgan Teylor qatorini = 10-6 gacha aniqlikda hisoblovchi dasturni ko‘raylik: using System; namespace ConsoleApplication1 { class Class1 { static void Main() { double e = 10^-6;// aniqlik chegarasi const int MaxIter = 500;// iteratsiyalarning maksimal soni Console.WriteLine( "x argument qiymatini kiriting:" ); double x = Convert.ToDouble( Console.ReadLine() ); bool done = true; // aniqlik chegarsini bildiruvchi belgi double ch = x, y = ch; for ( int n = 0; Math.Abs(ch) > e; n++ ) { ch *= -x * x / (2 * n + 2 ) / ( 2 * n + 3); // qatorning navbatdagi a’zosi y += ch; // summani yig‘ib borish if ( n > MaxIter ) { done = false; break; } } if ( done ) Console.WriteLine( "Qator yig‘indisi - " + y ); else Console.WriteLine("Kerakli aniqlikka belgilangan iteratsiyalar soni –{0}bilan erishib bo‘lmaydi!", MaxIter ); } } } Listing 7.4. Cheksiz qator yig‘indisini topish dasturi Polucheniye summi beskonechnogo ryada — primer vichisleniy, kotorie prinsipialno nevozmojno vipolnit tochno. continue operatori Ba’zi xollarda sikl tanasining ma’lum qismida uning qolgan qismidagi amallarni bajarmasdan keyingi takrorlanish qadamiga o‘tish lozim bo‘ladi. Bunday xollarda continue operatoridan foydalaniladi. Masalan, 1 dan 100 gacha bo‘lgan sonlar ichidan faqat 3 ga karrali bo‘lgan sonlar chop qilmasdan o‘tib ketuvchi dasturni continue operatoridan foydalangan xoldagi matni 7.5.-listingda keltirilgan. using System; namespace ConsoleApplication1 { class Class1 { static void Main() { int s; for(i=1;1<=100;i++) { if (i % 3==0) continue; Console.WriteLine( "i = " + i +"\n"); } Console.ReadKey(); } } } 7.5.-listing. continue operatoridan foydalanish return operatori return operatori biror bir operatsiyani bajarishga mo‘ljallangan funksiyani bajarilishini to‘xtatib, boshqaruvni ushbu funksiya chaqirilgan joyga qaytarish uchun xizmat qiladi. Ushbu opertorning sintaksisi quyidagicha: return [ ifoda ]; bu yerda ifoda funksiyaning qiymati sifatida qaytariluvchi va tipi ushbu funksiya tipiga mos bo‘lgan ifodadir. Agar funksiya void xizmatchi so‘zi bilan yozilgan bo‘lsa, bunday xolda ifoda yozilmaydi. Ushbu operatordan foydalanishga misollarni qism dasturlar to‘g‘risidagi navbatdagi ma’ruzalarda ko‘rib o‘tamiz. O’zlashtirish uchun savollar 1. Takrorlash operatorlarini sanang 2. Parametrli takrorlash operatorini izohlang 3. While operatorini izohlang 4. While hamda do while operatorlarining farqi nimada? 5. Return() ning vazifasi nima? 8-Ma`ruza: Massivlar. Reja: 1. Massivlar. 2. Bir o‘lchovli massivlar. 3. Ko‘p o‘lchovli massivlar. 4. Pog‘anali(stupenchatiy) massivlar. 5. System.Array bazaviy sinfi. 6. foreach operatori 7. Tasodifiy sonlar generatori Tayanch so’z va iboralar: Jadval, massiv, pog`onali massiv, System.Array bazaviy sinfi, foreach operatori, tasodifiy son, generator 8.1. Massivlar Massiv bir xil tipli elementlardan tashkil topgan cheklangan to‘plamdir. Massivning har bir elementi alohida o‘zgaruvchi yoki o‘zgarmas bo‘lishi mumkin. Massivda barcha elementlarning nomlari massiv nomi bilan bir xil bo‘ladi, faqatgina tartib nomeri bilan farq qiladi. Ushbu tartib nomerlari element indeksi deb yuritiladi. Massivlardan foydalanishdan avval ularni e’lon qilib olinadi. Masalan, 10 butun tipli elementga ega massiv quyidagicha e’lon qilinadi: int[] w = new int[10]; Bu yerda: int- e’lon qilinayotgan massiv tipi; [] – e’lon qilinayotgan kattalik massiv ekanligini va uning o‘lchamini bildiruvchi belgi; w – massiv nomi; new – xizmatchi so‘z bo‘lib, xotiradan yangi yaratilayotgan massiv uchun joy ajratilishini ta’minlaydi. int[10] – xotiradan ajratiluvchi joy. Ushbu misolda new int[10] xotiradan 10 ta butun tipli element uchun joy ajaratib, ularni nollar bilan to‘ldiradi. string[] z = new string[100]; Ushbu misolda string tipidagi 100 ta elementdan iborat z nomli massiv e’lon qilinyapti. Massivning har bir elementi u matnli tipda bo‘lganligi sababli null lar bilan to‘ldiriladi. Massiv elementlari soni massivning o‘lchamini belgilaydi. Massiv o‘lchamini uni e’lon qilingandan so‘ng o‘zgartirib bo‘lmaydi. Massiv o‘lchamini manfiy son bilan va haqiqiy son bilan berib bo‘lmaydi. Massiv elementarining indeksi(raqamlanishi) har doim 0 dan boshlanadi, shu sababli massiv elementining eng katta indeksi har doim uning elementlari sonida 1 ta kam bo‘ladi. Massiv elementiga murojaat qilinganda massiv nomdan keyingi to‘rtburchak qavs ichida element indeksi(nomeri) yoziladi. Masalan: int[] nums = new int[4]; nums[0] = 1; nums[1] = 2; nums[2] = 3; nums[3] = 5; Console.WriteLine(nums[3]); Agar massivning mavjud bo‘lmagan elementiga murojaat qilinsa yoki massiv o‘lchami chegarasidan chiqib ketilsa IndexOutOfRangeException tipidagi xatolik yuzaga keladi. Bir xil tipga ega bo‘lgan massivlardan biri-birini e’lon qilishda foydalanish mumkin. Bu xolda massiv bilan e’lon qilingan yangi massiv elementlari tipi ishoratli tip sifatida qabul qilinadi. Bunday xolda har ikki massiv teng emas balki, bitta umumiy massiv bo‘ladi. Masalan: int[] a = new int[10]; int[] b = a; // b va a bitta massivdir C# da massivlarning 3 xil turi bilan ishlanadi: bir o‘lchovli massivlar, ko‘p o‘lchovli to‘rtbo‘rchak massivlar va pog‘onasimon massivlar. 8.2. Bir o‘lchovli massivlar Bir o‘lchovli massivlardan dasturlashda qolganlariga nisbatan ko‘proq qo‘llaniladi. Bir o‘lchovli massivlarni turli xil e’lon qilish mumkin: tip[] massiv_nomi; tip[] massiv_nomi = new tip [ o‘lchami ]; tip[] massiv_nomi = { elementlar qiymati-initsializatorlar }; tip[] massiv_nomi = new tip [] { initsializatorlar }; tip[] massiv_nomi = new tip [ o‘lchami ] { initsializatorlar }; Misollar: // 1 elementlar berilmagan, initsializatsiya qilinmagan. Massivdan elementlar initsializatsiya qilinmaguncha foydalanib bo‘lmaydi. int[] a; // 2 Elementlar qiymati 0 ga teng int[] b = new int[4]; // 3 new avtomatik bajariladi va elementlar sonidan kelib chiqib o‘lcham belgilanadi int[] c = { 61, 2, 5, -9 }; // 4 elementlar sonidan kelib chiqib o‘lcham avtomatik ravishda aniqlanadi int[] d = new int[] { 61, 2, 5, -9 }; // 5 massiv foydalanuvchi tomonidan to‘liq yozilgan int[] e = new int[4] { 61, 2, 5, -9 }; 8.2.1 listingda 6 ta butun tipli elementlardan tashkil topgan massivning manfiy qiymatli elementlari yig‘indisi, soni va massivning eng katta elementini topish dasturi keltirilgan. using System; namespace ConsoleApplication1 { class Class1 { static void Main() { const int n = 6; int[] a = new int[n] { 3, 12, 5, -9, 8, -4 }; Console.WriteLine( "Joriy massiv:" ); for ( int i = 0; i < n; ++i ) Console.Write( "\t" + a[i] ); Console.WriteLine(); long sum = 0; // manfiy elementlar yig‘indisi int num = 0; // manfiy elementlar soni for ( int i = 0; i < n; ++i ) if ( a[i] < 0 ) { sum += a[i]; ++num; } Console.WriteLine( "Manfiy elementlar yig‘indisi = " + sum ); Console.WriteLine( " Manfiy elementlar soni = " + num ); int max = a[0]; // Eng katta element for ( int i = 1; i < n; ++i ) if ( a[i] > max ) max = a[i]; Console.WriteLine( " Eng katta element = " + max ); } } } Listing 8.1. Bir o‘lchovli massivlar bilan ishlash 8.3. Ko‘p o‘lchovli to‘rtbo‘rchak massivlar Ko‘p o‘lchovli massivlarni uning har bir elementi yana shu tipli massivdan tashkil topadi. Dasturlashda ko‘proq ikki o‘lchovli massivlardan foydalaniladi. Ko‘p o‘lchovli massivlarni e’lon qilish variantlari quyidagicha: tip[,] massiv_nomi; tip[,] massiv_nomi = new tip [ o‘lcham1, o‘lcham2 ]; tip[,] massiv_nomi = { initsializatorlar }; tip[,] massiv_nomi = new tip [,] { initsializatorlar }; tip[,] massiv_nomi = new tip [o‘lcham1, o‘lcham2] { initsializatorlar }; Misollar: elementlar berilmagan, initsializatsiya qilinmagan. Massivdan elementlar initsializatsiya qilinmaguncha foydalanib bo‘lmaydi. int[,] a; // 2 Elementlar qiymati 0 ga teng int[,] b = new int[2, 3]; // 3 new avtomatik bajariladi va elementlar sonidan kelib chiqib o‘lcham belgilanadi int[,] c = {{1, 2, 3}, {4, 5, 6}}; // 4 elementlar sonidan kelib chiqib o‘lcham avtomatik ravishda aniqlanadi int[,] c = new int[,] {{1, 2, 3}, {4, 5, 6}}; // 5 massiv foydalanuvchi tomonidan to‘liq yozilgan int[,] d = new int[2,3] {{1, 2, 3}, {4, 5, 6}}; Ikki o‘lchovli massivlarga murojaat qilishda, uning qator va ustunning kesishgan joyi nomerlarini ko‘rsatiladi. Masalan: a[1, 4] b[i, j] b[j, i] 8.2. listingda 3x4 o‘lchamli matritsa elementlarining o‘rta arifmetik qiymatini va har bir qatoridagi musbat elementlari sonini aniqlash dasturi keltirilgan Massivning o‘rta arifmetik qiymatini topish uchun, barcha elementlar yig‘indisini ularning soniga bo‘lamiz. Qatordagi musbat elementlar sonini qator bo‘yicha ko‘rib chiqish orqali topamiz. using System; namespace ConsoleApplication1 { class Class1 { static void Main() { const int m = 3, n = 4; int[,] a = new int[m, n] { { 2,-2, 8, 9 }, {-4,-5, 6,-2 }, { 7, 0, 1, 1 } }; Console.WriteLine( "Joriy massiv:" ); for ( int i = 0; i < m; ++i ) { for ( int j = 0; j < n; ++j ) Console.Write( "\t" + a[i, j] ); Console.WriteLine(); } double sum = 0; int nPosEl; for ( int i = 0; i < m; ++i ) { nPosEl = 0; for ( int j = 0; j < n; ++j ) { sum += a[i, j]; if ( a[i, j] > 0 ) ++nPosEl; } Console.WriteLine( " {0} {1} qatordagi musbat elementlar soni: ", i, nPosEl ); } Console.WriteLine( "Massivning o‘rta arifmetik qiymati: " + sum / m / n ); } } } Listing 8.2. Ikki o‘lchovli massiv bilan ishlash 8.4. Pog‘onasimon massivlar Pog‘onasimon massivlarda har bir qatordagi elementlar soni bir-biridan farq qilishi mumkin. Pog‘anasimon massivlar xotirada to‘rtburchak ko‘rinishdagi massivlardan farqli ravishda saqlanadi, ya’ni massivning yana har bir massiv elementi uchun alohida joy ajratiladi. Bundan tashqari xotiradan har bir ichki massiv elementlariga ishoratni saqlovchi alohida joy ajratiladi. Pog‘anasimon massivlarning har bir elementi uchun uni e’lon qilishda ham alohida o‘lcham beriladi.Masalan: int[][] nums = new int[3][]; nums[0] = new int[2]; nums[1] = new int[3]; nums[2] = new int[5]; 8.5.System.Array bazaviy sinfi C# da barcha massivlar uchun System nomlar makonining Array sinfi mavjud bo‘lib, unda massivlar bilan ishlash uchun bir qancha qulay bo‘lgan uslublar mavjud. Quyidagi jadvalda Array sinfining asosiy xususiyat va uslublari keltirilgan 8.1.- jadval. Array sinfining ba’zi metodlari va uslublari Element Ko‘rinishi Tavsifi Length Xususiyat Massivning elementlar soni Clear Statik Massiv uslub boshlang‘ich holatga qaytarish Statik Bir massivning ko‘rsatilgan diapazonidagi uslub elementlaridan boshqa massivga nusxa olish uslub Ko‘rsatilgan massiv elementi qiymatini olish Copy GetValue elementlarini e’lon qilingandagi Reverse Sort Rank Statik Bir o‘lchamli massiv elementlarini uslub teskari(reversiv) joylshtiradi Statik Bir o‘lchamli massiv elementlarini kamayish uslub tartibida joylashtiradi Statik Massiv o‘lchamini ko‘rsatadi uslub GetLength(n) uslub massivning n chi tartibi bo‘yicha uzunligini ko‘rsatadi. Masalan: GetLength(0) – 1 chi tartib bo‘yicha o‘lchami uzunligi, GetLength(1) – 2 o‘lchovli massivlarda 2 chi o‘lchami uzunligi va h. GetUpperBound(n) Statik uslub massivning n chi tartibi bo‘yicha yuqori chegarasi(eng katta indeksi nomeri)ni ko‘rsatadi. IndexOf(m,e) Statik Bir o‘lchovli m massivdan e elementni uslub birinchi bo‘lib, qaysi joyda uchrashini bildiradi. LastIndexOf(m,e) Statik Bir o‘lchovli m massivdan e elementni oxirgi uslub bo‘lib, qaysi joyda uchrashini bildiradi. 8.1. listingda Array sinfi elementlaridan dasturlashda foydalanishga misol keltirilgan. using System; namespace massiv { class Program { static void Main(string[] args) { int[,] a=new int[2,3]; a[0,0] = 55; a[0, 1] = 58; a[0, 2] = -5; a[1, 0] = 15; a[1, 1] = 45; a[1, 2] = 100; double[] d = {4,-3.01,-1,0,5,5,5,75}; int i,j; Console.WriteLine("Massiv uzunligi = " + a.Length); Console.WriteLine("Massiv o'lchami = " + a.Rank); Console.WriteLine("Massivning vertikal uzunligi = " + a.GetLength(0)); Console.WriteLine("Massivning gorzontal uzunligi = " + a.GetLength(1)); Console.WriteLine("Massivning vertikal indexi yuqori chegarasi = " + a.GetUpperBound(0)); Console.WriteLine("Massivning gorizontal indexi yuqori chegarasi = " + a.GetUpperBound(1) + "\n"); //Takrorlash konstuksiyasi Console.WriteLine("a massivning joriy holati:"); for (i = 0; i < a.GetLength(0); i++) { for (j=0; j<a.GetLength(1);j++) Console.Write("a[{0},{1}]="+a[i,j]+"\t",i,j); Console.Write("\n"); } Console.Write("\nd massivning joriy holati:\n d{\t"); for (i = 0; i < d.GetLength(0); i++) { Console.Write(d[i]+"\t"); } Console.Write("}\n"); Array.Reverse(d); Console.Write("\nd massivning reversiv holati:\n d{\t"); for (i = 0; i < d.GetLength(0); i++) { Console.Write(d[i] + "\t"); } Console.Write("}\n"); Array.Sort(d); Console.Write("\nd massivning tartblangan holati:\n d{\t"); for (i = 0; i < d.GetLength(0); i++) { Console.Write(d[i] + "\t"); } Console.Write("}\n"); Console.WriteLine("\nd massivda 5 soni 1 chi bo'lib {0} chi indexda turibdi",Array.IndexOf(d,5)); Console.WriteLine("\nd massivda 5 soni oxirgi bo'lib {0} chi indexda turibdi", Array.LastIndexOf(d, 5)); Console.ReadKey(); } } } Listing 8.1. Array sinfi elementlaridan dasturlashda foydalanish 8.1. lictingdagi dastur natijasi 8.6. foreach operatori foreach operatori maxsus tashkil qilingan gurux ma’lumotlarini o‘qish uchun qo‘llaniladi. Massivlar xuddi shunday guruxlar sirasiga kiradi. Ushbu operatordan foydalanishni qulayligi shundaki, massivning elementlari sonini bilish talab etilmaydi va elementlar navbatma-navbat tartib nomeri(indeksi) bo‘yicha o‘qilaveradi. Sintaksisi: foreach(<tip> <o‘zgaruvchi> in <kontayner>) sikl tanasi foreach operatoridan foydalanilganda, kontaynerning elementlari navbatmanavbat ko‘rsatilgan o‘zgaruvchiga o‘zlashtirib boriladi. Har bir siklda o‘zgaruvchi kontaynerning navbatdagi elementi qiymati o‘zlashtiriladi. Kontayner sifatida ko‘proq massivlar qo‘llaniladi. O‘zgaruvchining tipi kontayner elementi tipiga mos bo‘lishi talab etiladi. 8.6.1. listingda massivning manfiy elementlari yig‘indisi va ularning sonini hamda eng katta elementini foreach operatoridan foydalanib topish dasturi keltirilgan. using System; namespace ConsoleApplication1 { class Class1 { static void Main() { int[] a = { 3, 12, 5, -9, 8, -4 }; Console.WriteLine( "Massiv:" ); foreach ( int elem in a ) Console.Write( "\t" + elem ); Console.WriteLine(); long sum = 0; // manfiy elementlar summasi int num = 0; // Manfiy elementlar soni foreach ( int elem in a ) if ( elem < 0 ) { sum += elem; ++num; } Console.WriteLine( "sum = " + sum ); Console.WriteLine( "num = " + num ); int max = a[0]; // eng katta element foreach ( int elem in a ) if ( elem > max ) max = elem; Console.WriteLine( "max = " + max ); Console.Readkey(); } } } Listing 8.1. bir o‘lchamli massivlar bilan ishlashda foreach operatoridan foydalanish Foreach opertoridan foydalanib, konteynerdagi elementlar qiymatini faqatgina o‘qish mumkin. 8.2-listingda pog‘anasimon massivlar bilan ishlashda foreach operatoridan foydalanilgan dastur qismi keltirilgan ... int[][] a = new int[3][]; a[0] = new int [5] { 24, 50, 18, 3, 16 }; a[1] = new int [3] { 7, 9, -1 }; a[2] = new int [4] { 6, 15, 3, 1 }; Console.WriteLine( "Joriy massiv:" ); foreach ( int [] mas1 in a ) { foreach ( int x in mas1 ) Console.Write( "\t" + x ); Console.WriteLine(); } // Massivning birinchi qatoridan 18 ga teng elementni topish: Console.WriteLine( Array.IndexOf( a[0], 18 ) ); ... Listing 8.2. Pog‘anasimon massivlar bilan ishlashda foreach operatorini qo‘llash 8.7. Tasodifiy sonlar generatori Ba’zi xollarda massivni to‘ldirish uchun tasodifiy sonlardan foydalanishga to‘g‘ri keladi. C# da tasodifiy sonlarni Random sinfi shablonidan foydalanib hosil qilinadi. Tasodifiy sonlarni generatsiya qilish quyidagicha: Random <o‘zgaruvchi-generator> = new Random(); <tasodifiy sonni o‘zlashtiruvchi o‘zgaruvchi>=<o‘zgaruvchi- generator>.Next([tasodifiy sonning quyi chegarasi][,][tasodifiy sonning yuqori chegarasi]). Masalan: 0..100 oraliqdagi tacodifiy sonni generatsiya qilish uchun: Random r=new Random(); int a=r.Next(100); Console.WriteLine(a); … Agar 500…1000 gacha bo‘lgan tasodifiy sonni generatsiya qilish uchun quyidagicha dasturdan foydalaniladi: Random r=new Random(); int a=r.Next(500,1000); Console.WriteLine(a); Ma’ruzaga doir misollar Listing 8.3. Misol:Bir o‘lchamli Massivning 2 yoki undan ortiq takrorlanuvchi elementlarini sonini aniqlang va ularni boshqa songa almashtiring using System; namespace zadacha_Massiv { class Program { static void Main(string[] args) { Console.Write("Massiv o`lchamini kiriting:"); int n=int.Parse(Console.ReadLine()); int[] massiv = new int[n]; int[] tmparr = new int[n]; int rnn = n+1; Random rnd=new Random(); Console.WriteLine("Massivning joriy elementlari"); for (int i = 0; i < n; i++) { massiv[i]=rnd.Next(rnn); //{0} o‘rniga i, {1} o‘rniga massiv[i] qo‘yilib chop qilinadi. Console.WriteLine("massv[{0}]={1}",i,massiv[i]); } Console.WriteLine(); Array.Copy(massiv,tmparr,n); int tmp = 0; //birinchi tekshiruvdada massiv dagi 0 ga teng bo'lgan elementni tekshirib olish uchun int sch = 0; for (int k = 0; k < n; k++) { if (tmp == tmparr[k]) { sch++; tmparr[k] = 0; if (sch > 1) { l1: int a = rnd.Next(rnn); if (Array.IndexOf(massiv, a) != -1) goto l1; else massiv[k] = a; } } } if (sch == 0) { Console.WriteLine("massiv massivida {0} ga teng elementlar soni: {1} ta", tmp, 1); } else { Console.WriteLine("massiv massivida {0} ga teng elementlar soni: {1} ta", tmp, sch); } for(int i=0;i<n;i++) { tmp = tmparr[i]; sch = 0; if (tmp==0) continue; for (int k = 0; k < n; k++) { if (tmparr[k] == 0) continue; else if (tmp == tmparr[k]) { sch++; tmparr[k] = 0; if (sch > 1) { l2: int a = rnd.Next(rnn); if (Array.IndexOf(massiv, a) != -1) goto l2; else massiv[k] = a; } } } if (sch == 0) { Console.WriteLine("massiv massivida {0} ga teng elementlar soni: {1} ta", tmp, 1); } else { Console.WriteLine("massiv massivida {0} ga teng elementlar soni: {1} ta", tmp, sch); } } int j = -1; foreach (int i in massiv) { j=j+1; Console.Write("massv[{0}]={1}\t", j, i); Console.WriteLine("tmparr[{0}]={1}", j, tmparr[j]); } Console.WriteLine(); Console.ReadKey(); } } } Listing 8.3. Bir o‘lchamli Massivning 2 yoki undan ortiq akrorlanuvchi elementlarini sonini aniqlang va ularni boshqa songa almashtirish. Listing 8.4. Misol: Ikki o'lchovli massivda bir hil bolgan nechta elementlari bolsa sonini toping va ularni massiv tarkibida yoq bolgan sonlar bilan almashtiring using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Zadacha_massiv2 { class Program { /*2 o‘lchamli massivlar uchun IndexOf() funksiyasi ishlamaganligi sababli, ushbu funksiyani o‘zimiz yaratib olamiz.*/ //************************************************************ ******************** public static int IndexOF(Array A, int b) { int s= -1; for (int i = 0; i < A.GetLength(0); i++) { for (int j = 0; j < A.GetLength(1); j++) {/*Massivdan funksiya parametri sifatida foydalanilganda uning elementiga to‘g‘ridan to‘g‘ri murojaat qilib bo‘lmaydi, unga murojaat qilish uchun GetValue va SetValue lardan foydalaniladi */ if (b == Convert.ToInt32(A.GetValue(i, j))) { s=1; break; } } } return s; } //************************************************************ ******************** static void Main(string[] args) { Console.WriteLine("Massiv o'lchamini kiriting:"); Console.Write("m="); int m = int.Parse(Console.ReadLine()); Console.Write("n="); int n = int.Parse(Console.ReadLine()); int[,] AA = new int[m,n]; int[,] T = new int[m,n]; Array.Clear(T,0,T.Length); Random rnd=new Random(); int rnn=m*n+1; Console.WriteLine("Massivning boshlang'ich holati:"); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { AA[i,j]=rnd.Next(rnn); Console.Write("AA[{0},{1}]={2}\t",i,j,AA[i,j]); } Console.Write("\n"); } Array.Copy(AA, T, m * n); int s = 0; int tmp = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (tmp == T[i, j]) s++; if (s > 1) { l1: int a = rnd.Next(rnn); if (IndexOF(AA, a) != -1) goto l1; else AA[i, j] = a; } } } if (s!=0) Console.WriteLine("AA massivda {0} ga teng elementdan {1} ta", tmp, s); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { s = 0; tmp = T[i, j]; if (tmp == 0) continue; for(int k=0; k<m;k++) { for(int t=0;t<n;t++) { if (tmp == T[k, t]) { s++; if (s > 1) { T[k, t] = 0; l2: int a = rnd.Next(rnn); if (IndexOF(AA, a)!=-1) goto l2; else AA[k, t] = a; } } } } Console.WriteLine("AA massivda {0} ga teng elementdan {1} ta", tmp, s); } } Console.WriteLine("\nMassiv ozgartirilgandan keyingi holat"); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { Console.Write("AA[{0},{1}]={2}\t", i, j, AA[i, j]); } Console.Write("\n"); } Console.ReadKey(); } } } Listing 8.4. Ikki o'lchovli massivda bir hil bolgan nechta elementlari bolsa sonini toping va ularni massiv tarkibida yoq bolgan sonlar bilan almashtirish. O’zlashtirish uchun savollar 1. Massiv deb nimaga aytiladi? 2. Massivning qanday turlari bor? 3. Pog`onasimon massiv deganda nimani tushunasiz? 4. Pog`onasimon massivni ikki o`lchamli massiv deyish mumkin? 5. Tasodifiy sonlar generatori deganda nimani tushunasiz? 9-Ma`ruza: Satrlar. Reja: 1. Belgili kattaliklar bilan ishlash 2. Satrli kattalik(matn)lar bilan ishlash. 3. System.String bazaviy sinfi Tayanch so’z va iboralar: Belgili kattalik, satrli kattalik, System.Char sinfi, System.String sinfi, IsDigit metodi, IsLetter metodi 9.1. Belgili kattaliklar bilan ishlash Matnli ma’lumotlarni qayta ishlash zamonaviy dasturlashda eng keng tarqalgan masalalardan biri hisoblanib, C# da bunday masalalarni hal etish uchun keng qamrovli vositalarni taqdim etadi: alohida belgilar, belgili massivlar, o‘zgaruvchi va o‘zgarmas qatorlar hamda regulyar ifodalar. Belgili ma’lumotlarning tiplari C# da char tipi orqali e’lon qilinadi. char tipi Unicode kodirovkasidagi belgilarni saqlash uchun xizmat qiladi. Belgili ma’lumotlarni qayta ishlash uchun System nomlar makonida joylashgan Char sinfi elementlaridan foydalaniladi. Ushbu sinfda bir qator belgili kattaliklar bilan ishlash uchun mo‘ljallangan uslublar mavjud bo‘lib ulardan dasturlashda ko‘p qo‘llaniladiganlari 9.1 – jadvalda keltirilgan. 9.1-jadval. System.Char sinfining ayrim uslublari Uslub GetNumericValue Tavsifi Agar belgi son bo‘lsa uni sonli qiymatini qaytaradi, aksincha bo‘lsa -1 qiymat qaytaradi. IsControl Agar belgi boshqaruv belgisi bo‘lsa true qiymat, aks holda false qiymat qaytaradi. IsDigit Agar belgi 10 lik sanoq sistemasidagi raqam bo‘lsa true qiymat qaytaradi, aks holda false qiymat qaytaradi. IsLetter Agar belgi harf bo‘lsa true qiymat qaytaradi, aks holda false qiymat qaytaradi. IsLower Agar belgi ostki registrdagi(kichik) harf bo‘lsa true qiymat qaytaradi, aks holda false qiymat qaytaradi. IsUpper Agar belgi ustki registrdagi(katta) harf bo‘lsa true qiymat qaytaradi, aks holda false qiymat qaytaradi. IsWhiteSpace Agar belgi probel, yangi satrga o‘tish yoki karetkani qaytaruvchi belgi bo‘lsa true qiymat qaytaradi, aks holda false qiymat qaytaradi. Parse Matnli qatorni agar u 1 ta belgidan iborat bo‘lsa belgiga o‘zgartirish ToLower Belgini ostki registr(kichik harf)ga o‘tkazish ToUpper Belgini ustki registr(katta harf)ga o‘tkazish MaxValue, Ko‘rinmas xolda ifodalanuvchi belgilarni maksimal MinValue va minimal kodlarini qaytaradi 9.1-listingda ushbu uslublardan foydalanishga misol tariqasidagi dastur keltirilgan. using System; namespace ConsoleApplication1 { class Class1 { static void Main() { try { char b = 'B', c = '\x63', d = '\u0032'; // 1 Console.WriteLine( "{0} {1} {2}", b, c, d ); Console.WriteLine( "{0} {1} {2}", char.ToLower(b), char.ToUpper(c), char.GetNumericValue(d) ); char a; do // 2 { Console.Write( "Belgi kiriting: " ); a = char.Parse( Console.ReadLine() ); Console.WriteLine( " {0} belgisi kiritildi, uning kodi – {1}", a, (int)a ); if (char.IsLetter(a)) Console.WriteLine("Harf"); if (char.IsUpper(a)) Console.WriteLine("Katta registrda"); if (char.IsLower(a)) Console.WriteLine("Kichik registrda"); if (char.IsControl(a)) Console.WriteLine("Boshqaruv belgisi"); if (char.IsNumber(a)) Console.WriteLine("Son"); if (char.IsPunctuation(a)) Console.WriteLine("Ajratgich"); } while (a != 'q'); } catch { Console.WriteLine( "Istisnoli xolat qayd etildi!" ); return; } } } } Listing 9.1. System.Char sinfi uslublaridan foydalanish Dasturlashda aksariyat xollarda belgilardan tashkil topgan, ya’ni belgili tipdagi massivlardan ham foydalaniladi. Belgi tipdagi massivlar boshqa massivlar kabi Array bazaviy sinfi asosida yaratiladi. 9.2-listingda belgili tipdagi maasivdan foydlanishga misol keltirilgan. using System; namespace ConsoleApplication1 { class Class1 { static void Main() { char[] a = { 'm', 'a', 's', 's', 'i', 'v' }; char[] b = "Abdulxamid va Akbar".ToCharArray(); // 1 // 2 PrintArray( "a massiv:", a ); //a massivni chop qilish funksiyasiga murojaat int pos = Array.IndexOf( a, 'm' );// a massivdan m belgisini qidirish a[pos] = 'M'; //topilgan elementni katta M belgisiga almashtirish PrintArray( " a massivning o‘zgargan holati:", a ); PrintArray( "b massiv:", b ); //b massivni chop qilish Array.Reverse( b ); //b massivni revers xolatga o‘tkazish PrintArray( "b massivning o‘zgargan holati:", b ); } // massivni chop qilish funksiyasini yaratib olamiz public static void PrintArray( string header, Array a ) { Console.WriteLine( header ); foreach ( object x in a ) Console.Write( x ); Console.WriteLine( "\n" ); } } } Listing 9.2. Belgili tipdagi massivlardan foydalanish Dastur natijasi: a massiv: massiv a massivning o‘zgargan holati: Massiv b massiv: Abdulxamid Akbarni avtomobilda ko‘rdi b massivning o‘zgargan holati: dimaxludbA av rabkA Boshqaruv belgisi hisoblangan ayrim belgilarni chop qilish uchun ulardan oldin teskari bo‘lish(\) belgisidan foydalaniladi. Masalan: "\" belgisi xizmatchi belgi bo‘lib, qatorda ushbu belgini ifodalash uchun 2 marta (ya’ni \\) belgisi qo‘yish kerak. "\t" – boshqaruv belgisi tabulyatsiyani bildiradi. Ushbu belgidan avval turgan va keyingi turgan matn orasiga 1 ta tabulyatsiya qo‘shiladi. "\r"-matnni keyingi satrga o‘tkazish. "\"" – ikkitali qo‘shtirnoqni matnda ifodalash. 9.2. Satrli kattalik(matn)lar bilan ishlash. C# da satrli kattaliklar bilan ishlash uchun string tipidan foydalaniladi. string tipi Unicode kodirovkasidagi belgili qatorlarni saqlash uchun mo‘ljallangan standart tip hisoblanadi. Belgili qatorlar bilan ishlash uchun System nomlar makonining String bazaviy sinfi elementlari foydalaniladi. Satrli o‘zgaruvchilarni bir necha hil usul bilan yaratish mumkin: string s; // boshlang‘ich qiymat berilmagan s o‘zgaruvchini e’lon qilish string t = "qqq"; // boshlang‘ich qiymat berilgan t o‘zgaruvchini e’lon qilish string u = new string(' ', 20); // 20 probeldan iborat satr yaratish char[] a = { '0', '0', '0' }; // belgili tipdagi massivdan iborat satr string v = new string( a ); // belgili tipdagi massivdan satr yaratish C# da satrli kattaliklar ustida amallar bajarish uchun quyidagi amal belgilaridan foydalaniladi: • o‘zlashtirish( = ); • teng ekanligini tekshirish ( == ); • teng emasligini tekshirish ( != ); • tartib raqami(indeksi) bo‘yicha murojaat qilish ( [] ); • qo‘shish (konkatenatsiya) ( + ). Misollar: Matnni o‘zgaruvchiga o‘zlashtirish va uni ekranga chiqarish static void Main(string[] args) { string s = "Hello, World!"; Console.WriteLine(s); } Ikki matnni o‘zaro qo‘shish(konketanatsiya) string s = "Hello," + " World!"; "[]" operatori matnli qatorning qavs ichida ko‘rsatilgan indeksdagi elementiga murojaat qilish uchun qo‘llaniladi va char tipidagi qiymat qaytaradi. string s = "Hello, World!"; char c = s[1]; // bu yerda s ='e' Tenglikka tekshirish string s = "Hello, World!"; string s1 = "hello, world!"; if(s==s1) s2=”teng” else s2=”teng emas” // s2 = teng emas 9.3. System.String bazaviy sinfi System.String sinfi string tipidagi kattaliklar bilan ishlashga mo‘ljallangan bazaviy sinf hisoblanadi. Unda satrlar bilan ishlash uchun bir qator uslub va funksiyalar mavjud. Ularnnig ayrimlari bilan tanishib chiqamiz. Matnni bo‘sh yoki bo‘sh emasligini tekshirish uchun String sinfining IsNullOrEmpty() uslubidan foydalaniladi. Agar qator bo‘sh bo‘lsa yoki null qiymatli yoki bo‘sh bo‘lsa, funksiya qiymati true, aks holda false ga teng bo‘ladi. static void Main(string[] args) { string s1 = null, s2 = "", s3 = "Hello"; String.IsNullOrEmpty(s1); // true String.IsNullOrEmpty(s2); // true String.IsNullOrEmpty(s3); // false } IsNullOrWhiteSpace() uslubi ham xuddi IsNullOrEmpty() uslubi kabi ishlaydi. Farqi: IsNullOrWhiteSpace() funksiyasi matn faqat null qiymatli yoki probel(“ ”), tabulyatsiya ("\t")dan tashkil topgan bo‘lsa, funksiya qiymati true, aks holda false ga teng bo‘ladi. static void Main(string[] args) { string s1 = null, s2 = "\t", s3 = " ", s4 = "Hello"; String.IsNullOrWhiteSpace(s1); // true String.IsNullOrWhiteSpace(s2); // true String.IsNullOrWhiteSpace(s3); // true String.IsNullOrWhiteSpace(s4); // false } Ikki matnni o‘zaro solishtirish uchun String sinfining Compare() uslubidan foydalaniladi. Bunda matnlarning o‘zaro farqi(katta yoki kichikligi) matndagi belgilarning alfavitda joylashgan o‘rniga qarab belgilanadi. Masalan “a” matn “b” matndan kichik, “bb” matn “b” matndan katta va sh.k. Agar solishtirish uchun qo‘yilgan ikki matnni birinchisi ikkinchisidan: - kichik bo‘lsa, funksiya qiymati “-1” ga, - o‘zaro teng bo‘lsa, funksiya qiymati “0” ga, - katta bo‘lsa, funksiya qiymati “1” ga teng bo‘ladi. static void Main(string[] args) { String.Compare("a", "b"); // -1 String.Compare("a", "a"); // 0 String.Compare("b", "a"); // 1 String.Compare("ab", "abc"); // -1 String.Compare("Romania", "Russia"); // -1 String.Compare("Rwanda", "Russia"); // 1 String.Compare("Rwanda", "Romania"); // 1 } Agar solishtirilayotgan matndagi harflarning katta kichikligini hisobga olmaslik lozim bo‘lsa, funksiyada 3 chi argument sifatida “true” – xizmachi so‘zi ishlatiladi. Masalan: String.Compare("ab", "Ab"); // qiymat -1 teng String.Compare("ab", "Ab", true); // qiymat 0 teng Matndagi barcha belgilarni katta registrga o‘tkazish uchun ToUpper(), va aksincha kichik registrga o‘tkazish uchun ToLower() uslublaridan foydalaniladi: static void Main(string[] args){ string s = "Hello, World"; Console.WriteLine(s.ToUpper()); // "HELLO, WORLD" Console.WriteLine(s.ToLower()); // "hello, world" Console.ReadLine(); } Matnda biror qism matn bor yoki yo‘qligini tekshirish uchun Contains() uslubidan foydalaniladi. Agar argument sifatida foydalanilayotgan qism matn asosiy matnda bor bo‘lsa funksiya qiymati true, aks xolda false ga teng bo‘ladi. Misol: static void Main(string[] args){ string s = "Hello, World"; if (s.Contains("Hello")) Console.WriteLine("Mavjud"); Console.ReadLine(); } Ushbu dastur "Hello, World" matnida "Hello" matni bor bo‘lsa, ekranga “Mavjud” degan natijani chiqaradi. Matndan qidirilayotgan qism matnning birinchi bo‘lib uchrovchi pozitsiyasi(indeksi)ni aniqlash uchun IndexOf() uslubidan foydalaniladi. Agar qism matn asosiy matnda mavjud bo‘lsa funksiya qiymati asosiy matndagi qism matn uchragan birinchi indeksga teng bo‘ladi. Agar qism matn asosiy matndan topilmasa funksiya qiymati -1 ga teng bo‘ladi. static void Main(string[] args){ string s = "Hello, World"; Console.WriteLine(s.IndexOf("H")); // 0 Console.WriteLine(s.IndexOf("World")); // 7 Console.WriteLine(s.IndexOf("Zoo")); // -1 Console.ReadLine(); } Matndan qidirilayotgan qism matnda oxiri bo‘lib uchrovchi pozitsiyasi(indeksi)ni aniqlash uchun LastIndexOf() uslubidan foydalaniladi. Agar qism matn asosiy matnda mavjud bo‘lsa funksiya qiymati asosiy matndagi qism matn uchragan oxirgi indeksga teng bo‘ladi. Agar qism matn asosiy matndan topilmasa funksiya qiymati -1 ga teng bo‘ladi. static void Main(string[] args){ string s = "Hello, World"; Console.WriteLine(s.LastIndexOf("o")); // 9 Console.WriteLine(s. LastIndexOf("World")); // 7 Console.WriteLine(s. LastIndexOf("Zoo")); // -1 Console.ReadLine(); } Matnda biror matn bilan boshlanuvchi qator bor yoki yo‘qligini tekshirish uchun StartsWith(), biror matn bilan tugovchi qator bor yoki yo‘qligini tekshirish uchun esa EndsWith(), uslubidan foydalaniladi. Funksiya qiymati qidiriluvchi satr topilsa, true aks xolda false ga teng bo‘ladi. Misol: static void Main(string[] args){ string s = "Hello, World"; Console.WriteLine(s.StartsWith("Hello")); // true Console.WriteLine(s.StartsWith("World")); // false Console.WriteLine(s.EndsWith("World")); // true Console.ReadLine(); } Matnning biror pozitsiyasiga boshqa bir matnni qo‘shish uchun Insert() uslubidan foydalaniladi. static void Main(string[] args){ string s = "Hello World"; Console.WriteLine(s.Insert(5,",")); //5 pozitsiyaga “,” qo‘shiladi, ya’ni "Hello, World"; Console.ReadLine(); } Matnning biror pozitsiyasidan boshlab qolganlarini o‘chirish uchun Remove() uslubidan foydalaniladi. static void Main(string[] args) { string s = "Hello, World"; Console.WriteLine(s.Remove(5)); // ekranga "Hello" chiqadi. Console.ReadLine(); } Agar matnning biror pozitsiyasidan boshlab ma’lum sondagi belgilarni olib tashlash zarur bo‘lsa, ikkinchi argument sifatida kesib tashlanuvchi belgilarni soni ko‘rosatiladi. Masalan: s.Remove(3, 5) – 3 pozitsiyadan boshlab 5 ta simvol o‘chirilgan holdagi qiymatni qaytaradi. Berilgan matndan ko‘rsatilgan pozitsiyadan boshlanib ma’lum satrni qirqib olish uchun Substring() uslubidan foydalaniladi. Agar uslubdan foydalanishda 1 ta argument ishlatilsa, funksiya qiymati argumentda ko‘rsatilgan pozitsiyadan boshlab, matn oxirigacha bo‘lgan belgilarga teng bo‘ladi. Masalan: static void Main(string[] args) { string s = "Hello, World"; Console.WriteLine(s.Substring(7)); // ="World" Console.ReadLine(); } Agar uslubdan foydalanishda 2 ta argument ishlatilsa, funksiya qiymati argumentda ko‘rsatilgan pozitsiyadan boshlab, ikkinchi argument qiymatiga teng miqdordagi qirqib olingan belgilarga teng bo‘ladi. Masalan: static void Main(string[] args){ string s = "Hello, World"; Console.WriteLine(s.Substring(3,7)); // =lo, Wor Console.ReadLine(); } Matndagi, biror qism matnni boshqa matnga o‘zgartirish uchun Replace() uslubiddan foydalaniladi. static void Main(string[] args) { string s = "Hello, World, Hello"; Console.WriteLine(s.Replace("Hello", "World")); //natija "World, World, World" Console.ReadLine(); } Matndagi belgilarni char tipipdagi ToCharArray() uslubidan foydalaniladi. static void Main(string[] args) { string s = "Hello, World"; massivga o‘zlashtirish uchun char[] array = s.ToCharArray(); // Massiv elementlari – 'H', 'e', 'l', 'l'… ga teng bo‘ladi. } Matndagi ko‘rsatilgan belgi ishlatilgan joydan qism matnlarga ajratib uni massivga o‘zlashtirish uchun Split() uslubidan, massivdagi elementlarnbelgi qo‘yilgan holda bitta matnga yig‘ish uchun Join() foydalaniladi. Misol: static void Main(string[] args) { string s = "Arsenal,Milan,Real Madrid,Barcelona"; string[] array = s.Split(','); /* vergul qatnashgan joydan qism qatorlar ajratiladi, bunda massiv elementlari – array[0]= "Arsenal" array[1]= "Milan" array[2]= "Real Madrid" array[3]= "Barcelona" ga teng bo‘ladi.*/ } Yuqorida keltirib o‘tilgan uslublardan foydalanilganda, asosiy matn o‘zgarmaydi, balki asosiy matndan foydalaniladi xolos. Asosiy matni o‘zgartirish uchun StringBuilder sinfining uslublaridan foydalaniladi. Quyidagi listinglarda satrli kattaliklar bilan ishlashga misollar keltirilgan. Listing 9.3. Shunday matn berilgan bo‘lsinki unda kamida 2 ta so‘z va har bir so‘z orasida kamida 2 tadan probel bor bo‘lsin! *1) Berilgan matnning umumiy uzunligini aniqlang; *2) matndagi boshlang‘ich holdagi probellar sonini aniqlang; *3) so‘ngra matndagi har bir so‘z orasidagi probelni bittagacha qisqartiring. *4) matnning har bir so‘zini massivga joylashtiring *5) massivdagi elementlar sonini aniqlang. * barcha natijalarni ekranga chiqaring; using System; using System.Text; namespace stroka1{ class Program { static void Main(string[] args) { string matn; l0: Console.WriteLine("Shunday matn kiritingki unda kamida 2 so'z va \n har bir so'z orasida kamida 2 tada probel bor bo'lsin!"); matn = Console.ReadLine(); if (String.IsNullOrWhiteSpace(matn)) { Console.WriteLine("Kiritiluvchi matn faqat bo'sh joy yoki probellardan tashkil topgan bo'lmasligi kerak!"); goto l0; } Console.WriteLine(); int joriy_probel = 0; string yangi_matn=matn; Console.WriteLine("Matnning uzunligi:{0}", matn.Length); foreach (char i in matn) if (i == ' ') joriy_probel++; while (yangi_matn.IndexOf(" ") != -1) yangi_matn = yangi_matn.Replace(" ", " "); string [] massiv = yangi_matn.Split(' '); Console.WriteLine("Matning joriy holidagi probellar soni:{0}", joriy_probel); Console.WriteLine("Matnning qisqartirilgan holati:"+yangi_matn); Console.WriteLine("Matnning qisqartirilgan holati uzunligi:" + yangi_matn.Length); Console.WriteLine("Matn bo'lib joylashtirilgan massiv elementlari soni:{0}",massiv.Length); for(int i=0;i<massiv.Length;i++) { Console.WriteLine("massiv[{0}]=" + massiv[i], i); } Console.ReadKey(); } } } Listing 9.3. Shunday matn berilgan bo‘lsinki unda kamida 2 ta so‘z va har bir so‘z orasida kamida 2 tadan probel bor bo‘lsin! Listing 9.4. Berilgan matndagi ishtirok etgan barcha belgilarni kichik registrga o‘kazing va har bir belgini necha martadan ishtirok etganligini aniqlovchi dastur tuzing using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace stroka2{ class Program { static void Main(string[] args) { String matn; Console.Write("Matnni kiriting:"); matn = Console.ReadLine().ToLower(); Console.WriteLine("Natijalar:\n"+matn); string tmp_matn=null;// = matn; for (int i = 0; i < matn.Length; i++) { if (string.IsNullOrEmpty(tmp_matn)) tmp_matn = matn.Substring(0, 1); else { if (tmp_matn.IndexOf(matn[i]) == -1) tmp_matn += matn[i]; } } Console.WriteLine("Matnda ishtirok etgan belgilar:"+tmp_matn); int belgi_soni; Console.Write("Matnda:\n"); foreach (char i in tmp_matn) { belgi_soni = 0; foreach (char j in matn) { if (i == j) belgi_soni += 1; } Console.WriteLine("{0} belgi {1} marta ishtirok etgan", i, belgi_soni); } Console.ReadKey(); } } } Listing 9.4. Berilgan matndagi ishtirok etgan barcha belgilarni kichik registrga o‘kazing va har bir belgini necha martadan ishtirok etganligini aniqlovchi dastur Listing 9.5. Ismlardan iborat biror matn oling va unda albatta “Anvar” ismi qatnashgan bo‘lsin. * Matnda Anvar ismi bor yoki yo‘qligini tekshiring. * U qaysi pozitsiyalarda qatnashayotganligini aniqlang. * Matnni boshqa bir o‘zgaruvchiga o‘zlashtiring va undagi Anvar ism(lar)ini o‘chiring, Anvar ism(lar)ini o‘rni eslab qolinsin * O‘chirilgan Anvar ismlarini o‘rniga "Abror" ism(lar)i qo‘shilsin * Abror ism(lar)ini String.Replace() metodidan foydalanib, mos ravishda “Baxrom” ismiga almashtiring. * Matnda Baxrom ismi bor yoki yo‘qligini tekshiring * Matnni so‘z xolatida va belgi xolati massivlarga joylashtiring * Natijalarni ekranga chiqaring using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace stroka3 { class Program { static void Main(string[] args) { string matn = "Anvar do‘sti Abdusalomning dadasi Anvarjon akani ishxonasida Anvar ismli bolani uchratdi."; Console.WriteLine("Berilgan matn\n"+matn+"\n"); if (matn.Contains("Anvar")) { Console.WriteLine("Matnda Anvar ismi bor!"); string tmp_matn = matn; string tmp="Anvar"; int i_s=0;//Ism necha marta ishtirok etganligini aniqlash uchun int pos=0;//Pozitsiyani aniqlash uchun while(tmp.Contains("Anvar")) { i_s++; pos=tmp_matn.IndexOf("Anvar"); tmp=tmp_matn.Remove(pos,"Anvar".Length); tmp_matn = tmp; } Console.WriteLine("Matnning Anvar ismi o‘chirilgan xolati:+\n"+tmp_matn); Console.WriteLine("\nMatnda Anvar ismining egallagan pozsiyalari:"); int[] m_arr = new int[i_s]; tmp_matn = matn; tmp = "Anvar"; i_s=0; while (tmp.Contains("Anvar")) { m_arr[i_s] = tmp_matn.IndexOf("Anvar"); tmp = tmp_matn.Remove(m_arr[i_s], "Anvar".Length); tmp_matn = tmp; Console.Write(m_arr[i_s]+i_s*"Anvar".Length + "\t"); i_s++; } i_s = 0; foreach (int i in m_arr) { tmp = tmp_matn.Insert(i+i_s*"Anvar".Length, "Abror"); tmp_matn = tmp; i_s++; } Console.WriteLine("\nMatndan o‘chirilgan Anvar ismlari o‘rniga Abror ismini Insert metodi bilan qo‘shilgani:\n" + tmp); tmp = tmp_matn.Replace("Abror", "Baxrom"); Console.Write("\nMatndagi Abror ismlarini Replace metodidan foydalanib Baxromga almashtirilgan xolati:\n"+tmp); if (tmp.Contains("Baxrom")) Console.WriteLine("\nMatnda Baxrom ismi qo‘shilgan"); else Console.WriteLine("\nMatnda Baxrom ismi qo‘shilmagan"); Console.WriteLine("\nToUpper metodi:\n"+tmp.ToUpper()); Console.WriteLine("\nToLower metodi:\n" + tmp.ToLower()); string [] matn_array=tmp.Split(' '); char[] belgi_array = tmp.ToArray(); i_s=0; foreach(string i in matn_array) { Console.WriteLine("matn_array[{0}]={1}",i_s,i); i_s++; } i_s = 0; foreach (char i in belgi_array) { Console.WriteLine("belgi_array[{0}]={1}", i_s, i); i_s++; } } Console.ReadKey(); } } } Listing 9.5. Ismlardan iborat biror matn oling va unda albatta “Anvar” ismi qatnashgan dastur. Listing 9.6. Quyidagi matn berilgan: - “Bugun biz C# ning qatorlar bilan ishlovchi asosiy operatorlari, funksiyalari va metodlarini ko‘rib o‘tdik!”. Ushbu matndan qirqib tashlash orqali “C# ning asosiy operatorlari funksiyalari va metodlari” matnini qoldiring. using System; using System.Text; namespace stroka4 { class Program { static void Main(string[] args) { string s="Bugun biz C# ning qatorlar bilan ishlovchi asosiy operatorlari, funksiyalari va metodlarini ko‘rib o‘tdik!"; Console.WriteLine("Berilgan matn:\n" + s); string s1 = s.Substring(s.IndexOf("C#"), "C# ning qatorlar bilan ishlovchi asosiy operatorlari, funksiyalari va metodlari".Length); s = s1.Remove(s1.IndexOf("qatorlar"), "qatorlar bilan ishlovchi ".Length); Console.WriteLine("Natija:\n"+s); Console.ReadKey(); } } } Listing 9.6. - “Bugun biz C# ning qatorlar bilan ishlovchi asosiy operatorlari, funksiyalari va metodlarini ko‘rib o‘tdik!”. dasturi. O’zlashtirish uchun savollar. 1. System.String sinfida qanday metodlar mavjud 2. System.Char sinfida qanday metodlar mavjud 3. IsDigit metodining vazifasi 4. Replace() metodining vazifasi 5. Split() metodining vazifasi 10-Ma’ruza. Metodlar. Reja: 1. Metod va protsedura tushunchalari 2. C# da Metodlar yaratish 3. return – operatori 4. Ruxsat berish modifikatorlari. Tayanch so’z va iboralar: Metod tushunchasi, Metod yaratish usullari, return operatori, murojaat modifikatorlari 10.1. Metod va protsedura tushunchalari Dasturlashda shunday xolatlarga duch kelinadiki, qandaydir dastur qismini dasturda bir necha marta ishlatishga to‘g‘ri keladi. Bunday xolatlarda dasturning sodda va ixcham ko‘rinishga keltirish uchun ko‘p foydalaniluvchi dasturiy kodni alohida dastur qilib, ya’ni protsedura yoki Metod ko‘rinishidagi qism dastur sifatida ifodalab olinadi. So‘ngra lozim bo‘lganda shu qism dasturga murojaat qilib kerakli natijaga erishiladi. Protsedura-bu ma’lum vazifani bajarishga mo‘ljallangan qism dasturdir. Protseduraga asosiy dastur tanasidan murojaat qilish mumkin. Agar protsedura unga taqdim qilinuvchi o‘zgaruvchilar asosida qandaydir vazifani bajarishga mo‘ljallangan bo‘lsa bunday protseduralar parametrli protseduralar deb ataladi. Metod – protseduraga o‘xshash qism dastur. Farqi, Metod uning tanasidagi qism dastur bajarilgandan so‘ng muayyan bir qiymatni qaytarishga mo‘ljallanganligi va Metodni u qiymat qaytarganligi sababli ifodalar tarkibida qo‘llash mumkinligidir. C# da method, procedure, function kabi kalit so‘zlar yo‘q. C# da har qanday protsedurani Metod ko‘rinishida yozish mumkin, shuning uchun protsedura tushunchasi chiqarib tashlangan. Faqat, agar Metod qiymat qaytarmasligi va xuddi protsedura kabi vazifa bajarishi lozim bo‘lsa, u holda Metodni e’lon qilishda void xizmatchi so‘zidan foydalaniladi. 10.2. C# da Metodlar yaratish C# da Metodni e’lon qilinishi sintaksisi quyidagicha: [modifikator][static] [void] <Qaytariluvchi qiymat tipi> <Metod nomi> <([argumentlar])> { // Metod tanasi } bu yerda : modifikator – Metodning foydalanish mumkin bo‘lgan ta’sir doirasini belgilab public, private, protected, internal kalit so‘zlari bo‘lishi mumkin. Bu to‘g‘rida keyinroq to‘xtalamiz; Modifikator va Metod nomi orasida static kalit so‘zi bo‘lishi mumkin. Ushbu kalit so‘z Metodning statik ekanligini bildiradi. Statik Metodlar u joylashgan sinf yuklanishi bilan avtomatik tarzda xotiraga yuklanadi doimiy tarzda xotirada joylashib o‘tiradi; void – agar Metod protsedura sifatida qo‘llanilsa, ushbu kalit so‘zi qo‘yiladi; Qaytariluvchi qiymat tipi – bu Metod qaytaruvchi qiymatning tipidir; Metod nomi – Metodni dastur va ifodalar ichida qo‘llash uchun unga berilgan nom, ya’ni murojaat qilish nomi; argumentlar – Metod tanasida hisoblashda kerak bo‘ladigan kattalik(parametr)lar. Agar argument sifatida aniq bir o‘zgarmas qiymat uzatilishi lozim bo‘lsa, shu qiymat tipi va ana shu qiymatni Metod tanasiga olib kiruvchi o‘zgaruvchi nomi yoziladi. Agar bunda argumentlar bir nechta bo‘lsa, ular o‘zaro vergul bilan ajratib yoziladi. Masalan: public static int func1(double a, double b, int r, string s) { // Metod tanasi } Bu yerda func1-Metodga murojaat qilish nomi. a, b, r, s lar esa Metod tanasida hisoblash uchun zaruriy parametrlar. Ushbu parametrlar sifatida avval initsializatsiya qilingan o‘zgaruvchi, o‘zgarmas yoki konkret biror qiymat qo‘yish mumkin. Bu tariqa qo‘llanilgan parametrlardan Metod tanasida biror qiymatni hisoblash uchun foydalanish mumkin, lekin aynan ushbu parametrlarning qiymatini Metod tanasida o‘zgartirish mumkin emas. Agar Metod o‘zini qaytaruvchi qiymatidan tashqari yana qandaydir boshqa bir qiymatni qaytarishi, ya’ni Metod bir martalik murojaat qilishda bir nechta qiymatni qaytarishi zarur bo‘lsa, buning uchun qiymatni Metod tanasidan olib chiqib ketishi uchun ham parametrlardan foydalaniladi. Faqat ushbu parametrlardan avval ref kalit so‘zini qo‘llash lozim. Masalan: public double func2(int a, double b, ref double r, ref int x) { r=a+b; x=a*a; return x+r; } Yuqorida keltirilgan misolda a va b sonlari Metod tanasida o‘zgarmas sifatida qo‘llaniladi, ularning qiymatlarini Metod tanasi ichida o‘zgartirish mumkin emas, shu sababli Metodga murojaat qilinganda ushbu parametrlar o‘rnida biror o‘zgaruvchi, o‘zgarmas yoki konkret son qo‘yishimiz mumkin. Lekin r va x lar o‘zi bilan Metod tanasi bajarilib bo‘lingandan so‘ng qiymat olib chiqib ketishi zarur, shu sababli Metodga murojaat qilinganda ushbu parametrlar o‘rnida faqat avval e’lon qilingan o‘zgaruvchi qo‘llaniladi. Masalan yuqoridagi func2 Metodsiga murojaat quyidagicha bo‘lishi mumkin: ... int t; double f,l; t=0; l=func2(3, 5.2, f, t); Console.WriteLine(“l={0}, f={1}, t={2}”,l,f,t); ... 10.3. return – operatori return operatori biror bir operatsiyani bajarishga mo‘ljallangan Metodni bajarilishini to‘xtatib, boshqaruvni ushbu Metod chaqirilgan joyga qaytarish uchun xizmat qiladi. Ushbu opertorning sintaksisi quyidagicha: return [ ifoda ]; bu yerda ifoda Metodning qiymati sifatida qaytariluvchi va tipi - ushbu Metod tipiga mos bo‘lgan ifodadir. Agar Metod qiymat qaytarishi lozim bo‘lsa, qaytariluvchi qiymat return operatori yordamida Metodga o‘zlashtiriladi va boshqaruv Metodga murojaat qilingan joyga uzatiladi. Masalan: public static int Sum1(int a, int b) { return a+b; } Ushbu Metod a va b qiymatlarining yig‘indisini qaytaradi. Agar Metod qiymat qaytarishi lozim bo‘lmasa return operatoridan so‘ng ifoda yozilmaydi. Bunda Metod tanasidagi hisoblash jarayoni to‘xtatilib, boshqaruv shunchaki Metod tanasidan unga murojaat qilingan joyga uzatiladi. Qiymat qaytarmaydigan Metodlardan foydalanilganda return operatorini qo‘llamaslik ham mumkin. Endi Metodlar bilan ishlashga misollar ko‘rib o‘tsak. Misol uchun massivdagi bir nomni yangi nomga almashtirish Metodini yozamiz. Ushbu Metod biror qiymat qaytarishi uchun zarurat bo‘lmaganligi sababli uni protsedura sifatida qo‘llaymiz. using System; namespace ConsoleApplication1 { class Program { public static void ReplaceName(string[] names, string name, string newName) { for (int i=0; i < names.Length; i++) { if (names[i] == name) names[i] = newName; } } static void Main(string[] args) { string[] names = { "Sergey", "Maxim", "Andrey", "Oleg", "Andrey", "Ivan", "Sergey" }; //1 Metodga murojaat. Massivdagi barcha "Andrey" nomlari "Nikolay" ga o‘zgaradi. ReplaceName(names, "Andrey", "Nikolay"); // Metodga murojaat. Massivdagi barcha "Ivan" nomlari "Vladimir" ga o‘zgaradi. ReplaceName(names, "Ivan", "Vladimir"); Console.Readkey(); } } } Listing 10.1. Qiymat qaytarmaydigan Metodni yaratish va undan foydalanish. - Metodni birinchi marta chaqirilgandan so‘ng massiv quyidagicha ko‘rinishda bo‘ladi: "Sergey", "Maxim", " Nikolay ", "Oleg", " Nikolay ", "Ivan", "Sergey". - Metodni ikkinchi marta chaqirganimizdan so‘ng, massiv quyidagi ko‘rinishga keladi: "Sergey", "Maxim", " Nikolay ", "Oleg", " Nikolay ", " Vladimir ", "Sergey". Massivdagi eng katta element qiymatini qaytaruvchi Metodni quyidagi misolda ko‘rib o‘tilgan: using System; namespace ConsoleApplication1 { class Program { //Metod public static int GetMax(int[] array) { int max = array[0]; for (int i = 1; i < array.Length; i++) { if (array[i] > max) max = array[i]; } return max; } static void Main(string[] args) { int[] numbers = { 3, 32, 16, 27, 55, 43, 2, 34 }; int max; max = GetMax(numbers); //Metodga murojaat Console.WriteLine(“Massivdagi eng katta element ”+max); Console.ReadKey(); } } } Listing 10.2. Qiymat qaytaruvchi Metodni yaratish va undan foydalanish. 10.4. Ruxsat berish modifikatorlari Ruxsat berish modifikatorlari Metodga murojaat qilish mumkin bo‘lgan chegarani belgilaydi. C# ob’ektga mo‘ljallangan dasturlash tili bo‘lganligi sababli, Metodlarni sinfning bir a’zosi sifatida qaraladi va uni sinfning uslubi deyish mumkin. Metodga murojaat qilish chegarasini berish uchun 4 ta ruxsat berish modifikatorlaridan foydalaniladi. Bular: - public – Metodga ushbu dastur jamlanmasi(assembly)dagi ixtiyoriy joydan yoki u yozilgan kutubxona(nomlar makoni)ni ulab olish orqali boshqa dasturiy jamlanmadan ham murojaat qilish imkonini beradi; - protected – Metodga faqatgina u e’lon qilingan sinf ichida va uning avlodi vakili bo‘lgan sinflardangina murojaat qilish mumkin; - internal – Metodga faqatgina u e’lon qilingan dasturiy jamlanma ichidan murojaat qilish mumkin. - private – Metodga murojaat faqatgina u e’lon qilingan sinf ichida amalga oshirilishi mumkin. Dasturiy jamlanma (assembly) – bu .NET uchun kompilyatsiya qilingan *.exe yoki *.dll kengaytmali ko‘rinishdagi fayllardir. Dasturiy jamlanmalar avval yozilgan tayyor kodlardan qayta foydalanish imkonini beradi. O’zlashtirish uchun savollar. 1. Metod deb nimaga aytiladi? 2. Return operatori qanday qo`llaniladi? 3. Public modifikatorini izohlang 4. Private modifikatorini izohlang 5. Protected modifikatorini izohlang 11-Ma’ruza. Metodning massivli parametrlari va params kalit so`zi Reja: 1. Massivli parametrlari va params kalit so’zi 2. Parametr sifatida massiv. Tayanch so’z va iboralar: Metodning massivli parametrlari, params kalit so`zi, massivdan parameter sifatida foydalanish 11.1. Massivli parametrlar va params kalit so’zi Oldingi barcha misollarda biz doimiy sonli parametrlardan foydalanganmiz. Params kalit so'zidan foydalanib, biz noaniq parametrlarni o'tkaza olamiz: static void Addition(params int[] integers) { int result = 0; for (int i = 0; i < integers.Length; i++) { result += integers[i]; } Console.WriteLine(result); } static void Main(string[] args) { Addition(1, 2, 3, 4, 5); int[] array = new int[] { 1, 2, 3, 4 }; Addition(array); Addition(); Console.ReadLine(); } Params kalit so'zi bilan parametrning o'zi usulni belgilashda biz foydalanadigan turdagi bir o'lchovli massivni ko'rsatishi kerak. Params modifikatori bilan parametr o'rniga usulni chaqirishda biz individual qiymatlarni ham, qiymatlar qatorini ham berishimiz yoki parametrlarni umuman o'tkazmasligimiz mumkin. Agar biz boshqa parametrlarni topshirishimiz kerak parametrlardan oldin params kalit so'zi bilan ko'rsatilishi kerak: // Bu shunday ishlaydi bo'lsa, ular static void Addition( int x, string mes, params int[] integers) {} Bunday usulni chaqirish: Addition(2, "hello", 1, 3, 4); Biroq, parametrlarni o'zgartiruvchi parametrdan so'ng, biz boshqa parametrlarni aniqlay olmaymiz. Ya'ni, quyidagi usul ta'rifi haqiqiy emas: // bu ishlamaydi static void Addition(params int[] integers, int x, string mes) {} 11.2. Parametr sifatida massiv. Parametrlarni uzatishning ushbu usulini massivni parametr sifatida o'tkazishdan farqlash kerak: // parametrni params bilan o'tkazish static void Addition(params int[] integers) { int result = 0; for (int i = 0; i < integers.Length; i++) { result += integers[i]; } Console.WriteLine(result); } // massivni uzatish static void AdditionMas(int[] integers, int k) { int result = 0; for (int i = 0; i < integers.Length; i++) { result += (integers[i]*k); } Console.WriteLine(result); } static void Main(string[] args) { Addition(1, 2, 3, 4, 5); int[] array = new int[] { 1, 2, 3, 4 }; AdditionMas(array, 2); Console.ReadKey(); } AdditionMas usuli massivni parametr sifatida params kalit so'zisiz qabul qilganligi sababli, biz uni chaqirishda parametr sifatida massivni topshirishimiz kerak. Params kalit so'zi o'zgarmaydigan sonli argumentlarni yaratish usulida ko'rsatilgan turdagi argumentlarni, vergul bilan ajratilgan yoki ko'rsatilgan turdagi argumentlar qatorini o'tkazishga imkon beradi. Siz shuningdek dalillarni qoldirishingiz mumkin. Metodni yaratishda params kalit so'zidan keyin qo'shimcha parametrlarga yo'l qo'yilmaydi va metod yaratishda faqat bitta params kalit so'ziga ruxsat beriladi. Parametrga kiritilgan params kalit so'zi bilan metoddan foydalanish misoli: static void ShowArray(string name, params int[] array) { Console.Write(name); for (int i = 0; i < array.Length; i++) { Console.Write("{0} ", array[i]); } Console.WriteLine(); } static void Main() { int[] arr = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ShowArray("Numbers: ", arr); Console.WriteLine(); ShowArray("Numbers: ", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); Console.ReadKey(); } Dastur natijasi: O’zlashtirish uchun savollar. 1. Massiv deb nimaga aytiladi? 2. Massivdan parametr sifatida qanday foydalaniladi? 3. Params kalit so`zining strukturasi 12-Ma’ruza. Rekursiv va qayta yuklanuvchi metodlar Reja: 1. Rekursiya va Rekursiv funksiyalar 2. Qayta yuklanuvchi metodlar. Tayanch so’z va iboralar: Rekursiya tushunchasi, Rekursiv funksiyalar, to`g`ri rekursiya, yondosh rekursiya, qayta yuklanish 12.1. Rekursiya va Rekursiv funksiyalar. Rekursiya. Rekursiya - funktsiyani o'z ichidan to'g'ridan-to'g'ri (oddiy rekursiya) yoki boshqa funktsiyalar (murakkab yoki bilvosita rekursiya) orqali chaqirish. Rekursiv funksiyalar. Rekursiv funksiyalar o'zini chaqiradigan funksiyalardir. Masalan, faktorialni rekursiv funksiya sifatida hisoblashni aniqlaymiz: Misol uchun, n formulasidan foydalanadigan faktoriy hisobni olaylik! = 1 * 2 *… * n. Ya'ni, aslida, sonning faktorialini topish uchun biz ushbu songacha bo'lgan barcha sonlarni ko'paytiramiz. Masalan, 4 sonining faktoriali 24 = 1 * 2 * 3 * 4, 5 sonining faktoriali esa 120 = 1 * 2 * 3 * 4 * 5. int Factorial(int n) { if (n == 1) return 1; return n * Factorial(n - 1); } Rekursiv funktsiyani yaratishda unda qandaydir asosiy variant bo'lishi kerak, undan funktsiyani hisoblash boshlanadi. Faktorial bo'lsa, bu 1 sonining faktorialidir, ya'ni 1. Barcha eksenel musbat sonlarning faktoriallari 1 sonining faktorialini hisoblashdan boshlanadi. Dasturlash tili darajasida return operatori asosiy holatni qaytarish uchun ishlatiladi: if (n == 1) return 1; Ya'ni, agar kirish raqami 1 bo'lsa, u holda 1 qaytariladi Rekursiv funktsiyalarning yana bir xususiyati: barcha rekursiv chaqirishlar osti funktsiyalar ichida chaqirishi kerak, ular oxir-oqibat asosiy maqsadga yaqinlashadi: return n * Factorial(n - 1); Shunday qilib, funktsiyaga 1 ga teng bo'lmagan raqamni o'tkazishda qism funktsiyalarning keyingi rekursiv chaqiruvlari bilan har safar ularga bittadan kichik raqam uzatiladi. Va nihoyat, biz raqam 1 bo'ladigan va asosiy holat qo'llaniladigan holatga kelamiz. Bu rekursiv tushish deyiladi. Keling, ushbu funktsiyadan foydalanamiz: int Factorial(int n) { if (n == 1) return 1; return n * Factorial(n - 1); } int factorial4 = Factorial(4); // 24 int factorial5 = Factorial(5); // 120 int factorial6 = Factorial(6); // 720 Console.WriteLine("4 faktorial = "+ factorial4); Console.WriteLine("5 faktorial = "+ factorial5); Console.WriteLine("6 faktorial = "+ factorial6); Faktorial(4) chaqirilganda nima sodir bo'lishini bosqichma-bosqich ko'rib chiqamiz. 1. Dastlab, raqam birga teng yoki yo'qligini tekshiradi: if (n == 1) return 1; Lekin boshida n 4 ga teng, shuning uchun bu shart noto'g'ri va shunga ko'ra kod bajariladi. return n * Factorial(n - 1); Ya'ni, aslida bizda: return 4 * Factorial(3); 2. Keyin ifoda bajariladi: Factorial(3) Yana n 1 ga teng emas, shuning uchun kod bajariladi return n * Factorial(n - 1); Ya'ni, aslida: return 3 * Factorial(2); 3. Keyin ifoda bajariladi: Factorial(2) Yana n 1 ga teng emas, shuning uchun kod bajariladi return n * Factorial(n - 1); Ya'ni, aslida: return 2 * Factorial(1); 4. Keyin ifoda bajariladi: Factorial(1); Endi n 1 ga teng, shuning uchun kod bajariladi if (n == 1) return 1; Va 1 qaytadi. Natijada, ifoda Factorial(4); Haqiqatda, u ichkariga tushadi 4 * 3 * 2 * Factorial(1) Fibonachchi rekursiv funktsiyasi. Rekursiv funktsiyaning yana bir keng tarqalgan misoli Fibonachchi raqamlarini hisoblaydigan funksiyadir. Fibonachchi ketma-ketligining n-soni quyidagi formula bilan aniqlanadi: f (n) = f (n-1) + f (n-2) va f (0) = 0 va f (1) = 1. Ya'ni, Fibonachchi ketma-ketligi shunday ko'rinadi: 0 (0chi davr), 1 (1-chi davr), 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, .... uchun ushbu ketmaketlikning raqamlarini aniqlab, biz quyidagi usulni aniqlaymiz: int Fibonachi(int n) { if (n == 0 || n == 1) return n; return Fibonachi(n - 1) + Fibonachi(n - 2); } int fib4 = Fibonachi(4); int fib5 = Fibonachi(5); int fib6 = Fibonachi(6); Console.WriteLine("4 fibonachchi son= "+fib4); Console.WriteLine("5 fibonachchi son= "+fib5); Console.WriteLine("6 fibonachchi son= "+fib6); Bu erda asosiy versiya quyidagicha ko'rinadi: if (n == 0 || n == 1) return n; Ya'ni, agar biz ketma-ketlikning nol yoki birinchi elementini qidiradigan bo'lsak, u holda xuddi shu raqam qaytariladi - 0 yoki 1. Aks holda, Fibonachi (n 1) + Fibonachi (n - 2) ifodasi natijasi; Rekursiyalar va sikllar Bu rekursiya qanday ishlashini tushunishga yordam beradigan rekursiv funksiyalarning eng oddiy misolidir. Shu bilan birga, ikkala funksiya uchun ham rekursiyalar o'rniga loop konstruksiyalaridan foydalanishingiz mumkin. Umuman olganda, tsiklga asoslangan alternativalar rekursiyaga qaraganda tezroq va samaraliroq. Masalan, sikllar yordamida Fibonachchi raqamlarini hisoblash: static int Fibonachi2(int n) { int result = 0; int b = 1; int tmp; for (int i = 0; i < n; i++) { tmp = result; result = b; b += tmp; } return result; } Shu bilan birga, ba'zi holatlarda rekursiya maqbul yechimni taqdim etadi, masalan, turli xil daraxt ko'rinishlarini, masalan, kataloglar va fayllar daraxtini kesib o'tishda. 12.2. Qayta yuklanuvchi metodlar Ba'zan bir xil metodni yaratish kerak bo'ladi, lekin boshqa parametrlar to'plami bilan. Mavjud parametrlarga qarab, metodning ma'lum bir versiyasini qo'llang. Bu xususiyat, shuningdek, metodning qayta yuklanishi (method overloading) deb ataladi. C# da biz bir xil nomga ega, ammo signaturalari har xil bo'lgan sinfda bir nechta usullarni yaratishimiz mumkin. Signatura nima? Signatura quyidagi jihatlardan iborat: •Usul nomi •Parametrlar soni •Parametr turlari •Parametr tartibi •Parametr o'zgartiruvchilar Ammo parametrlarning nomlari signaturaga kiritilmagan. Masalan, quyidagi usulni olamiz: public int Sum(int x, int y) { return x + y; } Ushbu usul uchun signatura quyidagicha ko'rinadi: Sum(int, int) Bu usulning qayta yuklanishi shunchaki usullarning turli xil signaturalariga ega bo'lib, unda faqat usulning nomi bir xil bo'ladi. Ya'ni, usullar bir-biridan farq qilishi kerak: •Parametrlar soni •Parametr turi •Parametrlar tartibi •Parametr modifikatorlar Masalan, bizda quyidagi sinf bor deylik: class Calculator { public void Add(int a, int b) { int result = a + b; Console.WriteLine($"Result is {result}"); } public void Add(int a, int b, int c) { int result = a + b + c; Console.WriteLine($"Result is {result}"); } public int Add(int a, int b, int c, int d) { int result = a + b + c + d; Console.WriteLine($"Result is {result}"); return result; } public void Add(double a, double b) { double result = a + b; Console.WriteLine($"Result is {result}"); } } Add usulining to'rt xil versiyasi mavjud, ya'ni bu usulning to'rtta ortiqcha yuklanishi aniqlangan. Usulning dastlabki uchta versiyasi parametrlar soni bo'yicha farqlanadi. To'rtinchi versiya parametrlar soni bo'yicha birinchisiga to'g'ri keladi, lekin ularning turi bo'yicha farqlanadi. Bunday holda, kamida bitta parametr turi bo'yicha farq qilishi kifoya. Shuning uchun, bu ham Add usulining haqiqiy qayta yuklanishdir. Ya'ni, biz ushbu usullarning signaturalarini quyidagicha ifodalashimiz mumkin: Add(int, int) Add(int, int, int) Add(int, int, int, int) Add(double, double) Qayta yuklangan versiyalarni aniqlagandan so'ng, biz ulardan dasturda foydalanishimiz mumkin: Calculator calc = new Calculator(); calc.Add(1, 2); // 3 calc.Add(1, 2, 3); // 6 calc.Add(1, 2, 3, 4); // 10 calc.Add(1.4, 2.5); // 3.9 Konsol chiqishi: Result is 3 Result is 6 Result is 10 Result is 3.9 Bundan tashqari, qayta yuklangan usullar ishlatilgan modifikatorlarda farq qilishi mumkin. Masalan: void Increment(ref int val) { val++; Console.WriteLine(val); } void Increment(int val) { val++; Console.WriteLine(val); } Bunday holda, Increment metodining ikkala versiyasi ham bir xil turdagi parametrlar to'plamiga ega, lekin birinchi holda, parametr ref modifikatoriga ega. Shuning uchun, usulning ikkala versiyasi ham Increment metodining qayta yuklanishi bo'ladi. Qaytarish turidagi yoki parametrlar nomidagi usullar orasidagi farq qayta yuklanish uchun sabab emas. Masalan, quyidagi usullar to'plamini oling: int Sum(int x, int y) { return x + y; } int Sum(int number1, int number2) { return number1 + number2; } void Sum(int x, int y) { Console.WriteLine(x + y); } Ushbu usullarning barchasi bir xil signaturaga ega bo'ladi: Sum(int, int) Shuning uchun, ushbu usullar to'plami Sum usulining to'g'ri qayta yuklanishini anglatmaydi va ishlamaydi. O’zlashtirish uchun savollar. 1. Rekursiya deb nimaga aytiladi? 2. Rekursiyaning qanday turlari bor? 3. To`g`ri rekursiya deb qanday rekursiyaga aytiladi? 4. Yondosh rekursiya deb qanday rekursiyaga aytiladi? 5. Qayta yuklanish deb nimaga aytiladi? 13-Mavzu: Qiymatlar turlari va havola turlar Reja: 1. Qiymatlar turlari. 2. Havola turlar. Tayanch so’z va iboralar: Qiymat tushunchasi, qiymat turlari, havola tushunchasi, havola turlari, qiymatlarni nusxalash 13.1. Qiymatlar turlari. Avvalgi mavzularda biz quyidagi elementar ma'lumotlar turlarini ko'rib chiqdik: int, byte, double, string, object va boshqalar. Bundan tashqari murakkab turlari ham bor: strukturalar, ro'yxatlar, sinflar. Bu ma'lumotlar turlarining barchasini qiymat turlariga bo'lish mumkin, ularni qiymat turlari deb ham atash mumkin (value types) va mos yozuvlar turlari (reference types). Ularning orasidagi farqni tushunish muhimdir. Qiymat turlari: • Butun sonlar turlari (byte, sbyte, short, ushort, int, uint, long, ulong) • Suzuvchi nuqta turlari (float, double) • decimal turi • bool turi • char turi • Ro'yxatlar enum. • Strukturalar (struct) Malumot turlari: • object turi. • string turi • Sinflar (class) • Interfeyslar (interface) • Delegatlar (delegate) Ularning orasidagi farq nima? Buning uchun .NETda xotiraning tashkil qilinishini tushunish kerak. Bu yerda xotira ikki turga bo'linadi: stack va heap. Qiymat turlarini ifodalovchi metod parametrlari va o'zgaruvchilari o'z qiymatlarini to'plamga qo'yadilar. Stek - bu pastdan yuqoriga qarab o'sadigan ma'lumotlar strukturasi: qo'shilgan har bir yangi element oldingisining ustiga suriladi. Ushbu turdagi o'zgaruvchilarning hayoti ularning konteksti bilan cheklangan. Jismoniy jihatdan, stek - bu manzil maydonidagi ma'lum bir xotira maydoni. Dastur bajarilishi uchun endigina boshlanganda, stack ko'rsatgichi to'plam uchun ajratilgan xotira blokining oxirida o'rnatiladi. Ma'lumotlar to'plamga o'tkazilganda, ko'rsatgich qayta o'rnatiladi, shunda u yana yangi bo'sh joyni ko'rsatadi. Har bir alohida metod chaqirilganda, xotira maydoni yoki stek ramkasi ajratiladi, bu yerda uning parametrlari va o'zgaruvchilari qiymatlari saqlanadi. Masalan: class Program { static void Main(string[] args) { Calculate(5); Console.ReadKey(); } static void Calculate(int t) { int x = 6; int y = 7; int z = y + t; } } Bunday dastur ishga tushirilganda, to'plamda ikkita ramka aniqlanadi - Main metodi uchun (chunki dastur ishga tushganda chaqiriladi) va Calculate metodi uchun: 13.1-rasm. Ushbu Calculate metodi chaqirilganda, t, x, y va z qiymatlari stekdagi uning ramkasiga suriladi. Ular ushbu metod kontekstida aniqlanadi. Metod tugagach, stek uchun ajratilgan xotira maydoni keyinchalik boshqa metodlar bilan ishlatilishi mumkin. Bundan tashqari, agar metodning parametri yoki o'zgaruvchisi qiymat turini ifodalasa, u holda ushbu parametr yoki o'zgaruvchining bevosita qiymati stekda saqlanadi. Misol uchun, bu holda, Calculate metodining o'zgaruvchilari va parametrlari muhim turni - int turini ifodalaydi, shuning uchun ularning raqamli qiymatlari stekda saqlanadi. Yo'naltiruvchi turlari bir xil bo'lmagan ob'ektlarning tartibsiz to'plami sifatida ko'rib chiqilishi mumkin bo'lgan yacheykada saqlanadi. Jismoniy jihatdan, bu jarayon uchun mavjud bo'lgan xotiraning qolgan qismidir. Yo'naltiruvchi turdagi ob'ekt yaratilganda, stekga heap1dagi manzilga havola joylashtiriladi. Agar mos yozuvlar turidagi ob'ekt endi ishlatilmasa, avtomatik axlat yig'uvchi ishga tushadi: u yig'ilgan ob'ektga boshqa havolalar yo'qligini ko'radi, bu ob'ektni shartli ravishda o'chiradi va xotirani tozalaydi - aslida u shuni belgilaydi ushbu xotira segmenti boshqa ma'lumotlarni saqlash uchun ishlatilishi mumkin. Shunday qilib, xususan, agar biz Calculate metodini quyidagicha o'zgartirsak: static void Calculate(int t) { object x = 6; int y = 7; int z = y + t; } Endi x o'zgaruvchisining qiymati heapda saqlanadi, chunki u object mos yozuvlar turini ifodalaydi va stek ob'ektga havolani heapda saqlaydi. 1 Heap ing.- informatika va dasturlashda ma'lumotlar strukturasining nomi bo'lib, uning yordamida ilovaning dinamik ajratilgan xotirasi amalga oshiriladi. heap o'lchami - operatsion tizim (OT) tomonidan to'pni saqlash uchun ajratilgan xotira hajmi. 13.2-rasm. 13.2. Havola turlar. Kompozit turlari. Endi qiymat turi va mos yozuvlar turi kompozit turlarni struktura va sinfni ifodalovchi vaziyatni ko'rib chiqamiz: State state1 = new State(); //State - struktura, uning ma'lumotlari stekga joylashtirilgan Country country1 = new Country(); // Country - sinf, heapdagi manzilga havola stekga suriladi // va heap ccountry1 ob'ektining barcha ma'lumotlarini o'z ichiga oladi struct State { public int x; public int y; } class Country { public int x; public int y; } Bu yerda Main metodida xotira state1 obyekti uchun stekga ajratiladi. Keyinchalik, country1 (Country country1) ob'ekti uchun stekda havola yaratiladi va konstruktorni new kalit so'zi bilan chaqirish orqali heap (new Country()) da bo'sh joy ajratiladi. country1 ob'ekti uchun stekdagi ma'lumotnoma ushbu ob'ekt joylashgan heapdagi joylashuv manzilini ko'rsatadi. 13.3-rasm. Shunday qilib, stek state1 strukturasining barcha maydonlarini va heapdagi country1 ob'ektiga havolani o'z ichiga oladi. Ammo, State strukturasida Country mos yozuvlar tipidagi o'zgaruvchi ham aniqlangan. Agar u qiymat turida aniqlangan bo'lsa, u o'z qiymatini qayerda saqlaydi? State state1 = new State(); Country country1 = new Country(); struct State { public int x; public int y; public Country country = new(); } class Country { public int x; public int y; } state1.country o‘zgaruvchisining qiymati heapda saqlanadi, chunki bu o‘zgaruvchi mos yozuvlar turini ifodalaydi: 13.4-rasm. Qiymatlarni nusxalash. Qiymatlarni nusxalashda ma'lumotlar turini hisobga olish kerak. Qiymat turidagi ob'ektga ma'lumotlarni tayinlaganingizda, u ma'lumotlarning nusxasini oladi. Ma'lumotni mos yozuvlar turidagi ob'ektga tayinlashda u ob'ektning nusxasini emas, balki heapda ushbu ob'ektga havolani oladi. Masalan: State state1 = new State(); // State strukturasi State state2 = new State(); state2.x = 1; state2.y = 2; state1 = state2; state2.x = 5; // state1.x = 1 harakatsiz Console.WriteLine(state1.x); // 1 Console.WriteLine(state2.x); // 5 Country country1 = new Country(); // Country sinfi Country country2 = new Country(); country2.x = 1; country2.y = 4; country1 = country2; country2.x = 7; // bu yerda country1.x = 7, chunki country1 va country2 ikkala havola ham heapdagi bir xil ob'ektga ishora qiladi. Console.WriteLine(country1.x); // 7 Console.WriteLine(country2.x); // 7 state1 struktura bo'lgani uchun siz state1 = state2 ni tayinlaganingizda, u state2 strukturasining nusxasini oladi. Va country1 sinfining ob'ekti country1=country2 tayinlanganda; country2 tomonidan ko'rsatilgan bir xil ob'ektga havola oladi. Shuning uchun, country2 o'zgarganda, country1 ham o'zgaradi. Qiymat turlari ichida mos yozuvlar turlari. Keling, yanada murakkab misolni ko'rib chiqaylik, agar strukturaning ichida biz mos yozuvlar turidagi o'zgaruvchiga ega bo'lishimiz mumkin, masalan, qandaydir sinf: State state1 = new State(); State state2 = new State(); state2.country = new Country(); state2.country.x = 5; state1 = state2; state2.country.x = 8; // Endi state1.country.x = 8, chunki state1.country va state2.country heap da bir xil ob'ektga ishora qiladi. Console.WriteLine(state1.country.x); // 8 Console.WriteLine(state2.country.x); // 8 struct State { public int x; public int y; public Country country = new(); //country ob'ekti uchun xotira ajratish } class Country { public int x; public int y; } Strukturadagi mos yozuvlar turlarining o'zgaruvchilari heapdagi ob'ektga havolani ham stekda saqlaydi. Va ikkita strukturani tayinlashda state1=state2; state1 tuzilishi heapdagi country ob'ektiga havola ham oladi. Shuning uchun state2.country ni o'zgartirish state1.country ni ham o'zgartiradi. 13.5-rasm. Ob'ektlarni metod parametrlari sifatida tasniflash. Parametrlarni qiymat va mos yozuvlar bo'yicha o'tkazishda ob'ektlarni xotirada tashkil etishni hisobga olish kerak. Agar metod parametrlari sinf ob'ektlarini ifodalasa, u holda parametrlardan foydalanish o'ziga xos xususiyatlarga ega. Masalan, Person obyektini parametr sifatida qabul qiluvchi metod yarataylik: Person p = new Person { name = "Tom", age = 23 }; ChangePerson(p); Console.WriteLine(p.name); // Alice Console.WriteLine(p.age); // 23 void ChangePerson(Person person) { // ishlaydi person.name = "Alice"; // faqat shu usul doirasida ishlaydi person = new Person { name = "Bill", age = 45 }; Console.WriteLine(person.name); // Bill } class Person { public string name = ""; public int age; } Sinf ob'ektini qiymat bo'yicha o'tkazishda ob'ekt havolasining nusxasi metodga o'tkaziladi. Ushbu nusxa asl havola bilan bir xil ob'ektga ishora qiladi, shuning uchun biz ob'ektning alohida maydonlari va xususiyatlarini o'zgartirishimiz mumkin, lekin ob'ektning o'zini o'zgartira olmaymiz. Shuning uchun, yuqoridagi misolda faqat person.name = "Alice" qatori ishlaydi. Yana bir qator person=new Person{name = "Bill", age = 45} xotirada yangi ob'ekt yaratadi va p_erson endi xotiradagi yangi ob'ektga ishora qiladi. Agar biz undan keyin uni o'zgartirsak ham, u Main metodidagi p havolasiga hech qanday ta'sir ko'rsatmaydi, chunki p havolasi hali ham xotiradagi eski ob'ektga ishora qiladi. Ammo parametrni havola bo'yicha o'tkazishda (ref kalit so'zidan foydalangan holda), xotiradagi ob'ekt havolasi argument sifatida metodga uzatiladi. Shunday qilib, siz ob'ektning maydonlari va xususiyatlarini ham, ob'ektning o'zini ham o'zgartirishingiz mumkin: Person p = new Person { name = "Tom", age = 23 }; ChangePerson(ref p); Console.WriteLine(p.name); // Bill Console.WriteLine(p.age); // 45 void ChangePerson(ref Person person) { // ishlaydi person.name = "Alice"; // ishlaydi person = new Person { name = "Bill", age = 45 }; } class Person { public string name = ""; public int age; } new operatsiyasi xotirada yangi ob'ektni yaratadi va endi person havolasi (Main metodidan p ga havola) xotiradagi yangi ob'ektga ishora qiladi. O’zlashtirish uchun savollar. 1. Qanday qiymat turlari mavjud? 2. Qanday havola turlari mavjud? 3. Ref kalit so`zining vazifasi 4. New operatsiyasi qanday vazifani bajaradi? 5. Obyektlarni metod parametri sifatida qanday qo`llaniladi? Foydalanilgan adabiyotlar Asosiy adabiyotlar 1. Троелсен Эндрю, Джепикс Филипп | Язык программирования C# 7 и платформы .NET и .NET Core. Вильямс. 2018 2. Troelsen, P. Japikse. Pro C# 8 with .NET Core. Foundational Principles and Practices in Programming. Apress, 2020 3. Албахари Бен, Албахари Джозеф. C# 7.0. Справочник. Полное описание языка. Пер. с англ.-СПб: “Альфа-книга”, 2018, -1024 с Qo`shimcha adabiyotlar 1. Кристиан Нейгел, Билл Ивьен, Джей Глинн, Карли Уотсон, Морган Скиннер. C# 4.0 и платформа .NET 4 для профессионалов. – Изд. Вильямс, 2011, 1440 с. 2. Ю.С. Магда C#. Язык программирования Си Шарп. – Изд. ДМК Пресс, 2013, 190 с. 3. Christian Nagel. PROFESSIONAL C# 7 and .NET Core 2.0. Wrox, 2018. 4. Madraximov Sh.F., Ikramov A.M. C++ tilida programmalash bo’yicha masalalar to’plami. O’quv qo’llanma // Toshkent, O’zbekiston Milliy Universiteti, “Universitet” nashriyoti, 2017. 160 bet Axborot manbaalari 1. 1. https://metanit.com/sharp/tutorial/ – Onlayn darslar 2. 2. http://lib.nuu.uz/ – O’zbekiston Milliy universiteti elektron kutubxonasi 3. http://www.intuit.ru – Национальный Открытый Университет Россия) 4. https://metanit.com/sharp/tutorial/2.11.php - Rekursiv funksiyalar 3. 5. https://metanit.com/sharp/tutorial/3.5.php - Qayta yuklanuvchi metodlar 6. https://metanit.com/sharp/tutorial/2.16.php - Qiymatlar turlari va havola turlar.