C++ preprotsessor va makroslar
Nomidan ko'rinib turibdiki, C++ preprotsessorlari dasturimizni kompilyatsiya qilishdan oldin o'zgartiradigan (oldindan ishlov beradigan) vositalardir.
Preprotsessorlar kod o'zgarishini boshqarish uchun preprotsessor ko'rsatmalaridan foydalanadilar. Masalan,
#include <iostream>
Bu erda #include - <iostream> sarlavha fayli tarkibini kompilyatsiya qilishdan oldin dasturimizga kiritadigan preprotsessor direktivasi.
Working of C++ preprocessor

Preprotsessor direktivalari
C++ da barcha preprotsessor direktivalari # belgisi bilan boshlanadi. Masalan, #include , #define , #if va boshqalar.
C++ preprotsessorlarining umumiy ilovalaridan ba'zilari:
#include - to include header files#define - to define macros#if - to provide conditional compilationKeling, ushbu preprotsessor direktivalarining har biri bilan batafsil tanishib chiqamiz.
#include direktivasi dasturimizga sarlavhali fayllarni kiritish uchun ishlatiladi. Masalan,
#include <cmath>
Bu erda cmath sarlavha faylidir. #include direktivasi preprotsessorga yuqoridagi kod qatorini cmath sarlavha fayli mazmuni bilan almashtirishni aytadi.
Shuning uchun pow() va sqrt() kabi funksiyalardan foydalanish uchun #include <cmath> dan foydalanishimiz kerak.
Shuningdek, biz #include direktivasi yordamida o'z shaxsiy sarlavha fayllarimizni yaratishimiz va ularni dasturimizda ishlatishimiz mumkin. Masalan,
#include "path_to_file/my_header.h"
Bu erda biz dasturimizga my_header.h nomli maxsus sarlavha faylini kiritdik.
Shunday qilib, biz kattaroq dasturni bir nechta fayllarga ajratishimiz mumkin.
#define direktivasi bizning dasturlarimizda ishlatilishi mumkin bo'lgan preprotsessor o'zgaruvchilarini "aniqlash" uchun ishlatiladi. Masalan,
#define PI 3.1415 // pi qiymati
Endi biz dasturimizda PI dan foydalansak, u 3.1415 bilan almashtiriladi.
Bu erda PI makro sifatida tanilgan. Makros - bu nom berilgan kodning bir qismi.
#include <iostream>
// PI nomli makro yarating
// 3.1415 qiymati bilan
#define PI 3.1415
using namespace std;
int main() {
double radius, area;
cout << "Enter the radius: ";
cin >> radius;
// doira maydonini hisoblash uchun PI dan foydalaning
area = PI * radius * radius;
cout << "Area = " << area;
return 0;
}
Chiqish
Enter the radius: 4
Area = 50.264
Funksiya kabi ishlaydigan makroslarni yaratish uchun #define dan ham foydalanishimiz mumkin. Masalan,
#define circleArea(r) (3.1415 * r * r)
Keling, ishlaydigan misolni olaylik:
#include <iostream>
#define PI 3.1415
// doira maydonini hisoblaydigan makro
// va "r" parametrini oladi
#define circle_area(r) (PI * r * r)
using namespace std;
int main() {
double radius = 2.5;
// circle_area() makrosini chaqiring
// argument sifatida radiusni o'tkazing
cout << "Area = " << circle_area(radius);
return 0;
}
Chiqish
Area = 19.6344
Bu erda circleArea(radius); kodi 3.1415 * 2.5 * 2.5 ga kengayadi.
[!NOTE] Funksiyaga o'xshash makroslardan ko'ra funksiyalardan foydalangan ma'qul, chunki makroslar xatoga ko'proq moyil bo'ladi.
#if direktivasi oldindan protsessorga ma'lum shartlarga qarab kod blokini kiritish yoki kiritmaslikni ko'rsatish uchun ishlatiladi.
Bundan tashqari, bir nechta shartlarda #else va #elif direktivalari bilan birgalikda foydalanish mumkin.
Demak, #if , #else va #elif direktivalari C++ tilidagi if...else operatorlariga juda oʻxshash va bitta katta farq bilan.
if...else operatorlari kod bloki bajarilishi kerakmi yoki yo'qligini tekshirish uchun bajarish vaqtida sinovdan o'tkaziladi.
Boshqa tomondan, shartli direktivalar dasturga kod blokini kiritish yoki kiritmaslik to'g'risida qaror qabul qilish uchun kompilyatsiya qilishdan oldin preprotsessor tomonidan sinovdan o'tkaziladi. Mana oddiy misol,
#include <iostream>
// 3 qiymatiga ega NUMBER ta makro yarating
#define NUMBER 3
using namespace std;
int main() {
// tekshirish uchun #if direktivasidan foydalaning
// agar NUMBER 0 dan katta bo'lsa
#if (NUMBER > 0)
cout << NUMBER << " is greater than 0.";
#else
cout << NUMBER << " is less than 0.";
#endif
return 0;
}
Chiqish
3 is greater than 0.
Bu erda #endif direktivasi #if va #else direktivalarining bajarilishini ko'rsatish uchun ishlatiladi. Biroq, if...else iboralari ishlash vaqtida kodning qaysi qismini bajarish kerakligini hal qilish uchun preprotsessor ko'rsatmalariga qaraganda afzalroqdir. Shunga qaramay, #if direktivalari ko'proq qo'llanilishi mumkin bo'lgan bir nechta holatlar mavjud:
#include <iostream>
using namespace std;
int main() {
// Windowsda ishlayotgan bo'lsa, o'z ichiga oladi
#ifdef _WIN32
cout << "Hello from Windows!" << endl;
// Linuxda ishlayotgan bo'lsa, o'z ichiga oladi
#elif __linux__
cout << "Hello from Linux!" << endl;
// boshqa tizimda ishlayotgan bo'lsa, o'z ichiga oladi
#else
cout << "Hello from an unknown platform!" << endl;
#endif
return 0;
}
Chiqish
Hello from Linux!
Bu shartli kompilyatsiya yordamida platformaga xos kodning namunasidir.
Bu yerga,
-_WIN32 - Windows platformalarida Microsoft Visual C++ kompilyatori tomonidan belgilangan makros
__linux__ - a macro defined by GNU C Compiler on Linux systems#ifdef - a variant of #if which checks if a macro has been defined or not_WIN32 va __linux__ makroslari dastur ishlayotgan tizimni aniqlash uchun ishlatiladi.
Bu erda C++ dasturlashda tez-tez ishlatiladigan oldindan belgilangan makroslar mavjud.
Ibratli qiymat __DATE__ Joriy sanani o'z ichiga olgan qator. __FILE__ Hozirda bajarilayotgan dasturning fayl nomini o'z ichiga olgan qator. __LINE__ Joriy satr raqamini ifodalovchi butun son. __TIME__ Joriy vaqtni (GMT) o'z ichiga olgan qator.
[!NOTE] Bular oldindan belgilangan makroslar bo'lgani uchun biz ulardan foydalanish uchun
#definedirektivasidan foydalanishimiz shart emas.
#include <iostream>
using namespace std;
int main() {
// joriy vaqtni chop eting
cout << "Current time: " << __TIME__;
return 0;
}
Chiqish
Current time: 04:23:31
Ushbu dastur joriy vaqtni (GMT) __TIME__ makrosidan foydalanib chop etadi.