18-bo‘lim
Standart kutubxona
stdlib, math, time, ctype va string kutubxonalarining eng foydali funksiyalari, qsort va bsearch bilan saralash va qidirish.
Ushbu bo‘lim mundarijasi
C ning standart kutubxonasi kichik, lekin unda kundalik ish uchun zarur hamma narsa bor. Bu bo'limda eng ko'p ishlatiladiganlarini ko'ramiz.
Asosiy sarlavhalar #
| Sarlavha | Nima beradi |
|---|---|
stdio.h | Kiritish-chiqarish, fayllar |
stdlib.h | Xotira, tasodifiy sonlar, saralash, aylantirish |
string.h | Satrlar va xotira bloklari |
math.h | Matematik funksiyalar |
ctype.h | Belgilarni tekshirish va o'girish |
time.h | Sana va vaqt |
limits.h | Turlarning chegaralari |
stdbool.h | bool, true, false |
stdint.h | Aniq hajmli turlar (int32_t) |
assert.h | Ishlab chiqishda tekshiruvlar |
stdlib.h - aylantirish #
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("atoi(\"42\") = %d\n", atoi("42"));
printf("atof(\"3.14\") = %.2f\n", atof("3.14"));
char *qolgan;
long son = strtol("1234abc", &qolgan, 10);
printf("strtol = %ld, qolgan: \"%s\"\n", son, qolgan);
long ikkilik = strtol("1011", NULL, 2);
printf("ikkilik 1011 = %ld\n", ikkilik);
long onoltilik = strtol("ff", NULL, 16);
printf("o'n oltilik ff = %ld\n", onoltilik);
return 0;
}
atoi("42") = 42
atof("3.14") = 3.14
strtol = 1234, qolgan: "abc"
ikkilik 1011 = 11
o'n oltilik ff = 255
Tasodifiy sonlar #
#include <stdio.h>
#include <stdlib.h>
int main(void) {
srand(42); /* qat'iy urug' - natija takrorlanadi */
printf("Besh tasodifiy son (1-100):\n");
for (int i = 0; i < 5; i++) {
int son = rand() % 100 + 1;
printf(" %d\n", son);
}
return 0;
}
rand() haqida uchta muhim narsa1. srand ni bir marta chaqiring. Odatda main boshida:
srand((unsigned) time(NULL)); /* har safar boshqa natija */
Uni sikl ichida chaqirsangiz, bir xil sonlar chiqadi.
2. rand() % n mukammal emas. Kichik sonlar biroz ko'proq
uchraydi. Oddiy dasturlar uchun bu muhim emas, lekin statistika yoki
o'yin uchun yaxshiroq usul kerak.
3. Xavfsizlik uchun ishlatmang. rand() oldindan aytish
mumkin. Parol, token yoki kalit yaratishda operatsion tizimning
kriptografik generatorini ishlating.
math.h - matematika #
#include <stdio.h>
#include <math.h>
/* -std=c17 qat'iy rejimida M_PI va M_E aniqlanmagan bo'lishi mumkin */
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_E
#define M_E 2.71828182845904523536
#endif
int main(void) {
printf("sqrt(16) = %.2f\n", sqrt(16.0));
printf("pow(2, 10) = %.0f\n", pow(2.0, 10.0));
printf("fabs(-7.5) = %.2f\n", fabs(-7.5));
printf("ceil(4.2) = %.0f\n", ceil(4.2));
printf("floor(4.8) = %.0f\n", floor(4.8));
printf("round(4.5) = %.0f\n", round(4.5));
printf("fmod(17, 5) = %.2f\n", fmod(17.0, 5.0));
printf("log(M_E) = %.2f\n", log(M_E));
printf("log10(1000) = %.2f\n", log10(1000.0));
double burchak = M_PI / 6.0; /* 30 daraja */
printf("sin(30 daraja) = %.4f\n", sin(burchak));
printf("cos(30 daraja) = %.4f\n", cos(burchak));
return 0;
}
sqrt(16) = 4.00
pow(2, 10) = 1024
fabs(-7.5) = 7.50
ceil(4.2) = 5
floor(4.8) = 4
round(4.5) = 5
fmod(17, 5) = 2.00
log(M_E) = 1.00
log10(1000) = 3.00
sin(30 daraja) = 0.5000
cos(30 daraja) = 0.8660
math.h uchun -lm kerak bo'lishi mumkinLinux'da matematik kutubxonani alohida bog'lash kerak:
gcc -std=c17 dastur.c -o dastur -lm
-lm ni unutsangiz:
undefined reference to `sqrt'
Windows va macOS'da odatda shart emas, lekin -lm yozish hech qachon
zarar qilmaydi.
Trigonometrik funksiyalar radian qabul qiladi, daraja emas.
double radian = daraja * M_PI / 180.0;
M_PI POSIX kengaytmasi - ba'zi kompilyatorlarda yo'q. Ko'chma kod
uchun o'zingiz aniqlang:
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
ctype.h - belgilar #
#include <stdio.h>
#include <ctype.h>
int main(void) {
const char *matn = "Salom C-2026!";
printf("%-8s %-6s %-6s %-6s %-6s\n",
"Belgi", "harf", "raqam", "probel", "katta");
printf("----------------------------------------\n");
for (int i = 0; matn[i] != '\0'; i++) {
unsigned char b = (unsigned char) matn[i];
printf("%-8c %-6s %-6s %-6s %-6s\n",
matn[i],
isalpha(b) ? "ha" : "-",
isdigit(b) ? "ha" : "-",
isspace(b) ? "ha" : "-",
isupper(b) ? "ha" : "-");
}
return 0;
}
Belgi harf raqam probel katta
----------------------------------------
S ha - - ha
a ha - - -
l ha - - -
o ha - - -
m ha - - -
- - ha -
C ha - - ha
- - - - -
2 - ha - -
0 - ha - -
2 - ha - -
6 - ha - -
! - - - -
| Funksiya | Tekshiradi |
|---|---|
isalpha | Harfmi |
isdigit | Raqammi |
isalnum | Harf yoki raqammi |
isspace | Probel, tab yoki yangi qatormi |
isupper / islower | Katta / kichik harfmi |
ispunct | Tinish belgisimi |
toupper / tolower | Kattaga / kichikka o'giradi |
time.h - vaqt #
#include <stdio.h>
#include <time.h>
int main(void) {
/* qat'iy vaqt - natija takrorlanadigan bo'lsin */
time_t vaqt = 1789000000;
struct tm *mahalliy = gmtime(&vaqt);
printf("Yil : %d\n", mahalliy->tm_year + 1900);
printf("Oy : %d\n", mahalliy->tm_mon + 1);
printf("Kun : %d\n", mahalliy->tm_mday);
printf("Soat : %02d:%02d:%02d\n",
mahalliy->tm_hour, mahalliy->tm_min, mahalliy->tm_sec);
char bufer[64];
strftime(bufer, sizeof(bufer), "%d.%m.%Y %H:%M", mahalliy);
printf("Formatlangan: %s\n", bufer);
return 0;
}
Yil : 2026
Oy : 9
Kun : 10
Soat : 00:26:40
Formatlangan: 10.09.2026 00:26
time_t hozir = time(NULL);
struct tm *mahalliy = localtime(&hozir);
localtime mahalliy vaqt mintaqasini hisobga oladi, gmtime esa UTC
beradi.
tm_year 1900 dan boshlab sanaladi, tm_mon esa noldan -
bu klassik tuzoq.
Dastur tezligini o'lchash #
#include <stdio.h>
#include <time.h>
int main(void) {
clock_t boshlandi = clock();
long long yigindi = 0;
for (long long i = 0; i < 50000000LL; i++) {
yigindi += i;
}
clock_t tugadi = clock();
double soniya = (double) (tugadi - boshlandi) / CLOCKS_PER_SEC;
printf("Yig'indi hisoblandi: %lld\n", yigindi);
printf("Vaqt 0 dan katta : %s\n", (soniya >= 0.0) ? "ha" : "yo'q");
return 0;
}
Yig'indi hisoblandi: 1249999975000000
Vaqt 0 dan katta : ha
qsort - universal saralash #
#include <stdio.h>
#include <stdlib.h>
int solishtir_osib(const void *a, const void *b) {
int birinchi = *(const int *) a;
int ikkinchi = *(const int *) b;
if (birinchi < ikkinchi) return -1;
if (birinchi > ikkinchi) return 1;
return 0;
}
int solishtir_kamayib(const void *a, const void *b) {
return solishtir_osib(b, a);
}
int main(void) {
int sonlar[] = {85, 92, 78, 95, 88, 61, 100, 73};
int soni = sizeof(sonlar) / sizeof(sonlar[0]);
qsort(sonlar, soni, sizeof(sonlar[0]), solishtir_osib);
printf("O'sish tartibida : ");
for (int i = 0; i < soni; i++) printf("%d ", sonlar[i]);
qsort(sonlar, soni, sizeof(sonlar[0]), solishtir_kamayib);
printf("\nKamayish tartibida: ");
for (int i = 0; i < soni; i++) printf("%d ", sonlar[i]);
printf("\n");
return 0;
}
O'sish tartibida : 61 73 78 85 88 92 95 100
Kamayish tartibida: 100 95 92 88 85 78 73 61
return a - b; yozmangint solishtir(const void *a, const void *b) {
return *(const int *) a - *(const int *) b; /* XAVFLI */
}
Katta sonlarda ayirish toshib ketishi mumkin:
-2000000000 - 2000000000 int chegarasidan chiqadi va natija
noto'g'ri ishorali bo'ladi.
Yuqoridagi uch shartli variant har doim xavfsiz.
Strukturalarni saralash #
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char ism[30];
int yosh;
double baho;
} Talaba;
int baho_boyicha(const void *a, const void *b) {
const Talaba *x = a;
const Talaba *y = b;
if (x->baho < y->baho) return 1; /* kamayish tartibi */
if (x->baho > y->baho) return -1;
return 0;
}
int ism_boyicha(const void *a, const void *b) {
const Talaba *x = a;
const Talaba *y = b;
return strcmp(x->ism, y->ism);
}
void chiqar(const char *sarlavha, const Talaba guruh[], int soni) {
printf("%s\n", sarlavha);
for (int i = 0; i < soni; i++) {
printf(" %-18s %3d %6.2f\n", guruh[i].ism, guruh[i].yosh, guruh[i].baho);
}
}
int main(void) {
Talaba guruh[] = {
{"Husanboy Qodirov", 25, 4.60},
{"Malika Yusupova", 21, 4.90},
{"Nodira Sobirova", 24, 4.30},
{"Aziza Tosheva", 22, 4.10}
};
int soni = sizeof(guruh) / sizeof(guruh[0]);
qsort(guruh, soni, sizeof(guruh[0]), baho_boyicha);
chiqar("Baho bo'yicha:", guruh, soni);
qsort(guruh, soni, sizeof(guruh[0]), ism_boyicha);
chiqar("\nIsm bo'yicha:", guruh, soni);
return 0;
}
Baho bo'yicha:
Malika Yusupova 21 4.90
Husanboy Qodirov 25 4.60
Nodira Sobirova 24 4.30
Aziza Tosheva 22 4.10
Ism bo'yicha:
Aziza Tosheva 22 4.10
Husanboy Qodirov 25 4.60
Malika Yusupova 21 4.90
Nodira Sobirova 24 4.30
bsearch - ikkilik qidiruv #
#include <stdio.h>
#include <stdlib.h>
int solishtir(const void *a, const void *b) {
int x = *(const int *) a;
int y = *(const int *) b;
if (x < y) return -1;
if (x > y) return 1;
return 0;
}
int main(void) {
int sonlar[] = {61, 73, 78, 85, 88, 92, 95, 100}; /* saralangan! */
int soni = sizeof(sonlar) / sizeof(sonlar[0]);
int qidirilayotgan[] = {88, 50};
for (int i = 0; i < 2; i++) {
int *natija = bsearch(&qidirilayotgan[i], sonlar, soni,
sizeof(sonlar[0]), solishtir);
if (natija != NULL) {
printf("%d topildi, indeks: %ld\n",
qidirilayotgan[i], natija - sonlar);
} else {
printf("%d topilmadi\n", qidirilayotgan[i]);
}
}
return 0;
}
88 topildi, indeks: 4
50 topilmadi
bsearch faqat saralangan massivda ishlaydiMassiv saralanmagan bo'lsa, bsearch noto'g'ri javob beradi va
hech qanday xato ko'rsatmaydi.
Avval qsort, keyin bsearch - bir xil taqqoslash funksiyasi
bilan.
Almashuv: chiziqli qidiruv O(n), ikkilik qidiruv O(log n).
Million elementda bu 1 000 000 ta taqqoslash o'rniga atigi 20 ta
degani.
Xotira funksiyalari #
#include <stdio.h>
#include <string.h>
int main(void) {
int manba[5] = {1, 2, 3, 4, 5};
int maqsad[5];
memcpy(maqsad, manba, sizeof(manba));
printf("memcpy : ");
for (int i = 0; i < 5; i++) printf("%d ", maqsad[i]);
memset(maqsad, 0, sizeof(maqsad));
printf("\nmemset : ");
for (int i = 0; i < 5; i++) printf("%d ", maqsad[i]);
printf("\nmemcmp : %s\n",
memcmp(manba, manba, sizeof(manba)) == 0 ? "bir xil" : "farqli");
char matn[20] = "abcdefgh";
memmove(matn + 2, matn, 6); /* ustma-ust joylar uchun xavfsiz */
matn[8] = '\0';
printf("memmove : %s\n", matn);
return 0;
}
memcpy : 1 2 3 4 5
memset : 0 0 0 0 0
memcmp : bir xil
memmove : ababcdef
memcpy va memmove farqimemcpy xotira bloklari ustma-ust tushmasligini taxmin qiladi -
shuning uchun tezroq.
memmove esa ustma-ust holatni to'g'ri boshqaradi.
Shubha bo'lsa - memmove ishlating. Tezlik farqi juda kichik,
lekin xatolik xavfi yo'qoladi.
assert.h - ishlab chiqish tekshiruvlari #
#include <stdio.h>
#include <assert.h>
double ortacha(const int massiv[], int soni) {
assert(massiv != NULL);
assert(soni > 0);
int yigindi = 0;
for (int i = 0; i < soni; i++) {
yigindi += massiv[i];
}
return (double) yigindi / soni;
}
int main(void) {
int ballar[] = {85, 92, 78};
printf("O'rtacha: %.2f\n", ortacha(ballar, 3));
return 0;
}
O'rtacha: 85.00
assert ishlab chiqarishda o'chiriladigcc -DNDEBUG dastur.c -o dastur
NDEBUG aniqlangan bo'lsa, barcha assert lar butunlay yo'qoladi.
Shuning uchun assert ichiga hech qachon muhim amal yozmang:
assert(fayl_och() == 1); /* XATO: ishlab chiqarishda fayl ochilmaydi */
assert - «bu hech qachon bo'lmasligi kerak» degan holatlar uchun.
Foydalanuvchi xatosini (noto'g'ri kiritish, yo'q fayl) esa oddiy
if bilan tekshiring.
Dasturdan chiqish #
#include <stdio.h>
#include <stdlib.h>
void tozalash(void) {
printf("Tozalash bajarildi\n");
}
int main(void) {
atexit(tozalash); /* chiqishda avtomatik chaqiriladi */
printf("Asosiy ish\n");
if (0) {
exit(EXIT_FAILURE); /* istalgan joydan chiqish */
}
printf("Dastur tugadi\n");
return EXIT_SUCCESS;
}
Asosiy ish
Dastur tugadi
Tozalash bajarildi
| Doimiy | Qiymati | Ma'nosi |
|---|---|---|
EXIT_SUCCESS | 0 | Muvaffaqiyatli |
EXIT_FAILURE | 1 | Xatolik |
strtolbilan ikkilik va o'n oltilik sonlarni aylantiring.- Tasodifiy sonlar generatoridan foydalanib, tanga tashlash o'yinini yozing.
- Uchburchak gipotenuzasini
sqrtvapowbilan hisoblang. - Matndagi harf, raqam va tinish belgilarini
ctype.hbilan sanang. - Joriy sanani
strftimebilan chiroyli formatda chiqaring. clockbilan ikkita saralash algoritmini taqqoslang.qsortbilan butun sonlar massivini saralang.- Strukturalar massivini ikki xil mezon bo'yicha saralang.
bsearchbilan saralangan massivda qidiring.- Saralanmagan massivda
bsearchishlatib, natijani kuzating.
Xulosa #
strtolatoidan xavfsizroq - u xatoni aniqlaydi va sanoq sistemasini qo'llab-quvvatlaydi.srandni bir marta chaqiring;rand()xavfsizlik uchun yaramaydi.math.huchun Linux'da-lmbayrog'i kerak.- Trigonometrik funksiyalar radian qabul qiladi.
ctype.hfunksiyalariga(unsigned char)ga aylantirib bering.tm_year1900 dan,tm_monesa noldan boshlanadi.qsorthar qanday massivni saralaydi - unga taqqoslash funksiyasi kerak.- Taqqoslashda
a - byozmang - toshib ketish xavfi bor. bsearchfaqat saralangan massivda to'g'ri ishlaydi.- Ustma-ust bloklar uchun
memcpyemas,memmove. assertishlab chiqarishda o'chadi - unga muhim amal yozmang.
Keyingi bo'limda xotira xavfsizligi va nosozliklarni tuzatishni ko'ramiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.