18-bo‘lim

Standart kutubxona

stdlib, math, time, ctype va string kutubxonalarining eng foydali funksiyalari, qsort va bsearch bilan saralash va qidirish.

🕑 18 daqiqa o‘qish 📄 729 so‘z 👁 3 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Asosiy sarlavhalar
  2. stdlib.h - aylantirish
  3. Tasodifiy sonlar
  4. math.h - matematika
  5. ctype.h - belgilar
  6. time.h - vaqt
  7. Dastur tezligini o'lchash
  8. qsort - universal saralash
  9. Strukturalarni saralash
  10. bsearch - ikkilik qidiruv
  11. Xotira funksiyalari
  12. assert.h - ishlab chiqish tekshiruvlari
  13. Dasturdan chiqish
  14. Xulosa

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 #

SarlavhaNima beradi
stdio.hKiritish-chiqarish, fayllar
stdlib.hXotira, tasodifiy sonlar, saralash, aylantirish
string.hSatrlar va xotira bloklari
math.hMatematik funksiyalar
ctype.hBelgilarni tekshirish va o'girish
time.hSana va vaqt
limits.hTurlarning chegaralari
stdbool.hbool, true, false
stdint.hAniq hajmli turlar (int32_t)
assert.hIshlab chiqishda tekshiruvlar

stdlib.h - aylantirish #

C
#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;
}
Natija
atoi("42")      = 42
atof("3.14")    = 3.14
strtol          = 1234, qolgan: "abc"
ikkilik 1011    = 11
o'n oltilik ff  = 255

Tasodifiy sonlar #

C
#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 narsa

1. srand ni bir marta chaqiring. Odatda main boshida:

C
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 #

C
#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;
}
Natija
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 mumkin

Linux'da matematik kutubxonani alohida bog'lash kerak:

Terminal
gcc -std=c17 dastur.c -o dastur -lm

-lm ni unutsangiz:

Natija
undefined reference to `sqrt'

Windows va macOS'da odatda shart emas, lekin -lm yozish hech qachon zarar qilmaydi.

Burchaklar radianda

Trigonometrik funksiyalar radian qabul qiladi, daraja emas.

C
double radian = daraja * M_PI / 180.0;

M_PI POSIX kengaytmasi - ba'zi kompilyatorlarda yo'q. Ko'chma kod uchun o'zingiz aniqlang:

C
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

ctype.h - belgilar #

C
#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;
}
Natija
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     -      -     
!        -      -      -      -     
FunksiyaTekshiradi
isalphaHarfmi
isdigitRaqammi
isalnumHarf yoki raqammi
isspaceProbel, tab yoki yangi qatormi
isupper / islowerKatta / kichik harfmi
ispunctTinish belgisimi
toupper / tolowerKattaga / kichikka o'giradi

time.h - vaqt #

C
#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;
}
Natija
Yil    : 2026
Oy     : 9
Kun    : 10
Soat   : 00:26:40
Formatlangan: 10.09.2026 00:26
Joriy vaqtni olish
C
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 #

C
#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;
}
Natija
Yig'indi hisoblandi: 1249999975000000
Vaqt 0 dan katta   : ha

qsort - universal saralash #

C
#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;
}
Natija
O'sish tartibida  : 61 73 78 85 88 92 95 100 
Kamayish tartibida: 100 95 92 88 85 78 73 61 
return a - b; yozmang
C
int 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 #

C
#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;
}
Natija
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 #

C
#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;
}
Natija
88 topildi, indeks: 4
50 topilmadi
bsearch faqat saralangan massivda ishlaydi

Massiv 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 #

C
#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;
}
Natija
memcpy  : 1 2 3 4 5 
memset  : 0 0 0 0 0 
memcmp  : bir xil
memmove : ababcdef
memcpy va memmove farqi

memcpy 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 #

C
#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;
}
Natija
O'rtacha: 85.00
assert ishlab chiqarishda o'chiriladi
Terminal
gcc -DNDEBUG dastur.c -o dastur

NDEBUG aniqlangan bo'lsa, barcha assert lar butunlay yo'qoladi.

Shuning uchun assert ichiga hech qachon muhim amal yozmang:

C
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 #

C
#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;
}
Natija
Asosiy ish
Dastur tugadi
Tozalash bajarildi
DoimiyQiymatiMa'nosi
EXIT_SUCCESS0Muvaffaqiyatli
EXIT_FAILURE1Xatolik
Amaliy topshiriq
  1. strtol bilan ikkilik va o'n oltilik sonlarni aylantiring.
  2. Tasodifiy sonlar generatoridan foydalanib, tanga tashlash o'yinini yozing.
  3. Uchburchak gipotenuzasini sqrt va pow bilan hisoblang.
  4. Matndagi harf, raqam va tinish belgilarini ctype.h bilan sanang.
  5. Joriy sanani strftime bilan chiroyli formatda chiqaring.
  6. clock bilan ikkita saralash algoritmini taqqoslang.
  7. qsort bilan butun sonlar massivini saralang.
  8. Strukturalar massivini ikki xil mezon bo'yicha saralang.
  9. bsearch bilan saralangan massivda qidiring.
  10. Saralanmagan massivda bsearch ishlatib, natijani kuzating.

Xulosa #

  • strtol atoi dan xavfsizroq - u xatoni aniqlaydi va sanoq sistemasini qo'llab-quvvatlaydi.
  • srand ni bir marta chaqiring; rand() xavfsizlik uchun yaramaydi.
  • math.h uchun Linux'da -lm bayrog'i kerak.
  • Trigonometrik funksiyalar radian qabul qiladi.
  • ctype.h funksiyalariga (unsigned char) ga aylantirib bering.
  • tm_year 1900 dan, tm_mon esa noldan boshlanadi.
  • qsort har qanday massivni saralaydi - unga taqqoslash funksiyasi kerak.
  • Taqqoslashda a - b yozmang - toshib ketish xavfi bor.
  • bsearch faqat saralangan massivda to'g'ri ishlaydi.
  • Ustma-ust bloklar uchun memcpy emas, memmove.
  • assert ishlab chiqarishda o'chadi - unga muhim amal yozmang.

Keyingi bo'limda xotira xavfsizligi va nosozliklarni tuzatishni ko'ramiz.

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.