Skip to content

8-dars: Pointer, massiv va string

Dars haqida

Davomiyligi: 90 daqiqa Maqsad: Talaba pointer va massiv bog'liqligini chuqur tushunishi, dinamik xotira (malloc/free) bilan ishlashi va string funksiyalarining pointer orqali qanday ishlashini bilishi kerak.

O'tgan darsda (7-dars) pointer asoslarini o'rgandik: &, *, NULL, pass by reference. Bugun pointer'ning eng katta ish maydoni — massiv va string.

1. Massiv = pointer

c
int arr[5] = {10, 20, 30, 40, 50};

// Bu ikkalasi bir xil:
printf("%d\n", arr[0]);      // 10
printf("%d\n", *arr);        // 10

// Bu ham:
printf("%d\n", arr[2]);      // 30
printf("%d\n", *(arr + 2));  // 30

Aslida arr[i] = *(arr + i) — compiler shunday o'qiydi.

Pointer'ni massiv kabi ishlatish ham mumkin:

c
int *p = arr;  // & kerak emas — arr o'zi birinchi element manzili

printf("%d\n", p[0]);     // 10
printf("%d\n", p[2]);     // 30
printf("%d\n", *(p + 3)); // 40

2. Massiv va pointer farqi

c
int arr[5];
int *p;

sizeof(arr);  // 20 (5 * 4) — massiv hajmi
sizeof(p);    // 8 — pointer hajmi

arr = NULL;   // XATO — massiv nomi const
p = NULL;     // OK — pointer

Massiv nomi — const pointer (manzilni o'zgartirib bo'lmaydi).

3. Massiv funksiyaga — faqat pointer

c
void print_array(int arr[], int n) { ... }  // arr aslida int*
void print_array(int *arr, int n) { ... }   // bir xil — ikkalasi ham ishlaydi

int arr[] = int *arr (C uchun farqi yo'q). Shuning uchun funksiya ichida sizeof ishlamaydi:

c
void func(int arr[10]) {
    printf("%zu\n", sizeof(arr));  // 8 — pointer hajmi!
}

int main(void) {
    int arr[10];
    printf("%zu\n", sizeof(arr));  // 40 — massiv hajmi
    func(arr);
    return 0;
}

Funksiya massiv hajmini bilmaydi — doim n parametr sifatida uzating.

4. Pointer arithmetic — massiv bo'ylab yurish

c
int arr[] = {10, 20, 30, 40, 50};
int *p = arr;

while (p < arr + 5) {
    printf("%d ", *p);
    p++;   // keyingi elementga
}
// 10 20 30 40 50

Yig'indi — faqat pointer bilan:

c
int sum(int *start, int *end) {
    int total = 0;
    while (start < end) {
        total += *start;
        start++;
    }
    return total;
}

// Chaqirish
int arr[] = {1, 2, 3, 4, 5};
int s = sum(arr, arr + 5);  // 15

5. malloc — dinamik xotira

Oddiy massiv hajmi kompilatsiya vaqtida ma'lum bo'lishi kerak. Dinamik — ish vaqtida aniqlanadi:

c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n;
    printf("Necha element: ");
    scanf("%d", &n);

    int *arr = malloc(n * sizeof(int));  // n ta int uchun joy
    if (arr == NULL) {
        printf("Xotira yetmadi\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        arr[i] = i * 10;   // oddiy massiv kabi ishlatiladi
    }

    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    free(arr);
    arr = NULL;  // xavfsizlik uchun
    return 0;
}

malloc → free

malloc'dan keyin doim free kerak. Aks holda — memory leak. Kichik dasturlarda OS bo'shatadi, lekin uzoq ishlovchi dasturlarda RAM tugab qoladi.

6. calloc va realloc

c
int *a = calloc(100, sizeof(int));   // 100 ta int, hammasi 0
int *b = malloc(100 * sizeof(int));  // 100 ta int, axlat qiymatlar

// Hajmni o'zgartirish:
b = realloc(b, 200 * sizeof(int));   // endi 200 ta element

calloc — biroz sekinroq, lekin xavfsizroq (0 bilan to'ldirilgan).

7. Memory xatolari

Use after free

c
int *p = malloc(10 * sizeof(int));
free(p);
*p = 42;  // CRASH — yo'q joyga yozish

Double free

c
free(p);
free(p);  // CRASH yoki noma'lum xato

// Yechim:
free(p);
p = NULL;  // ikkinchi free xavfsiz bo'ladi

Memory leak

c
int *p = malloc(100);
p = malloc(200);  // Birinchisi yo'qoldi!

Tool'lar: Valgrind (Linux, valgrind ./program), AddressSanitizer (gcc -fsanitize=address).

8. String — char pointer ko'zi bilan

String = char massivi + \0. Demak string bilan ishlash = char pointer bilan yurish:

c
char str[] = "Hello";
char *p = str;

while (*p != '\0') {
    putchar(*p);
    p++;
}
// Hello

Pointer massivi — stringlar ro'yxati:

c
char *names[] = {"Akmal", "Aziza", "Botir", "Dilshod"};

for (int i = 0; i < 4; i++) {
    printf("%s\n", names[i]);
}

String va malloc:

c
char *str = malloc(100);
strcpy(str, "Hello");
printf("%s\n", str);
free(str);

9. string.h funksiyalari ichida nima bor?

2-darsda strlen, strcpy, strcmp, strcat ni ishlatgan edik. Endi ular ichida qanday ishlashini ko'ramiz — hammasi pointer:

my_strlen

c
size_t my_strlen(const char *s) {
    size_t len = 0;
    while (*s != '\0') {
        len++;
        s++;
    }
    return len;
}

my_strcpy

c
char *my_strcpy(char *dst, const char *src) {
    char *start = dst;
    while ((*dst++ = *src++) != '\0');
    return start;
}

(*dst++ = *src++) — klassik C idiomasi: belgini nusxalash, ikkala pointerni surish, \0 nusxalanganda to'xtash.

my_strcat

c
char *my_strcat(char *dst, const char *src) {
    char *start = dst;
    while (*dst != '\0') dst++;          // oxiriga borish
    while ((*dst++ = *src++) != '\0');   // nusxalash
    return start;
}

my_strcmp

c
int my_strcmp(const char *s1, const char *s2) {
    while (*s1 && (*s1 == *s2)) {
        s1++;
        s2++;
    }
    return *(unsigned char*)s1 - *(unsigned char*)s2;
}

strlen tezligi — O(n)

Har chaqirishda oxirigacha o'tadi. Sikl shartida chaqirmang:

c
for (int i = 0; i < strlen(str); i++) {  // SEKIN — har iteration'da qayta hisob
}

int len = strlen(str);
for (int i = 0; i < len; i++) {          // TEZ — bir marta hisoblandi
}

10. Pointer qaytaruvchi funksiyalar: strchr, strstr

c
char str[] = "Hello World";

char *p = strchr(str, 'W');       // 'W' ga pointer (str + 6)
printf("%s\n", p);                // "World"

char *p2 = strstr(str, "World");  // substring boshlanishiga pointer
char *p3 = strstr(str, "xyz");    // NULL — topilmadi

Natija — string ichiga pointer. Topilmasa — NULL (doim tekshiring).

11. strtok — bo'lish

c
char str[] = "apple,banana,orange";
char *token = strtok(str, ",");

while (token != NULL) {
    printf("%s\n", token);
    token = strtok(NULL, ",");  // ikkinchidan boshlab — NULL
}

strtok original'ni o'zgartiradi

strtok, o'rniga \0 qo'yadi. Original string buziladi. Kerak bo'lsa — avval nusxa oling.

12. String algoritmlari — pointer bilan

Reverse (pointer versiyasi)

c
void reverse(char *s) {
    char *end = s;
    while (*end) end++;   // oxiriga borish
    end--;                // \0 dan bitta oldin

    while (s < end) {
        char t = *s;
        *s = *end;
        *end = t;
        s++;
        end--;
    }
}

2-darsda index bilan yozgan edik — pointer versiyasi ixchamroq.

Anagram tekshirish

Anagram — bir xil harflardan tuzilgan ikki so'z (listen va silent):

c
int is_anagram(const char *s1, const char *s2) {
    if (strlen(s1) != strlen(s2)) return 0;

    int count[256] = {0};

    while (*s1) {
        count[(unsigned char)*s1]++;
        s1++;
    }

    while (*s2) {
        count[(unsigned char)*s2]--;
        if (count[(unsigned char)*s2] < 0) return 0;
        s2++;
    }

    return 1;
}

String massivi sort

strcmp bilan taqqoslash, strcpy bilan swap (5-darsdagi bubble sort + string):

c
void sort_strings(char arr[][50], int n) {
    char temp[50];
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - 1 - i; j++) {
            if (strcmp(arr[j], arr[j+1]) > 0) {
                strcpy(temp, arr[j]);
                strcpy(arr[j], arr[j+1]);
                strcpy(arr[j+1], temp);
            }
        }
    }
}

13. Xavfsiz input: fgets, sscanf, snprintf

scanf("%s", ...) — bo'shliqgacha o'qiydi. To'liq qator uchun — fgets:

c
char buffer[100];
fgets(buffer, sizeof(buffer), stdin);
buffer[strcspn(buffer, "\n")] = '\0';  // \n ni olib tashlash

Keyin sscanf bilan tahlil:

c
char input[] = "Akmal 22 Toshkent";
char name[50], city[50];
int age;
sscanf(input, "%s %d %s", name, &age, city);

snprintf — buffer'ga xavfsiz yozish (overflow yo'q):

c
char buffer[100];
snprintf(buffer, sizeof(buffer), "Yosh: %d, Ism: %s", 22, "Akmal");

Darsdagi topshiriqlar

Topshiriq 1 — Pointer va massiv

pointer-array.c — bitta massivni 4 xil usulda chiqaring: arr[i], *(arr + i), p[i] va *(p + i) (bu yerda p — massivga ishora qiluvchi pointer). To'rtala usul ham bir xil natija berishiga ishonch hosil qiling.

Topshiriq 2 — Dinamik massiv

dynamic-input.c — foydalanuvchi N kiritsin, malloc bilan joy ajrating, N ta raqam oling va statistika (sum, max, min, avg) chiqaring. Oxirida free.

Topshiriq 3 — Realloc

realloc.c — o'suvchi massiv (vektor tushunchasi) yozing: kichik capacity bilan boshlang, har safar element qo'shganda size ni oshiring va size capacity ga yetganda realloc bilan hajmni ikki barobarga oshiring. Kamida 10 ta element qo'shib, natijani chiqaring va oxirida free qiling.

Topshiriq 4 — Memory leak test

leak-test.c:

c
void leak(void) {
    int *p = malloc(1000 * sizeof(int));
    // free yo'q
}

int main(void) {
    for (int i = 0; i < 100; i++) {
        leak();
    }
    return 0;
}

Mac'da: Activity Monitor'da RAM oshganini ko'ring. Linux'da: valgrind ./leak-test.

Tuzating: free(p) qo'shing.

Topshiriq 5 — String funksiyalar

string-fn.c — dars matnidagi barcha my_* funksiyalarni yozing va string.h versiyalari bilan natijani taqqoslang.

Topshiriq 6 — Reverse

reverse.c — 2 ta versiya: index bilan (2-darsdan) va pointer bilan. Ikkalasini ham sinab ko'ring.

Topshiriq 7 — Anagram

anagram.c — 2 ta so'z anagramami?

Sinab ko'ring:

  • listen, silent → Ha
  • hello, world → Yo'q
  • evil, vile → Ha

Topshiriq 8 — Tokenize

tokenize.cstrtok bilan:

c
char data[] = "Akmal,22,Toshkent,Talaba";
// 4 ta token: Akmal, 22, Toshkent, Talaba

Topshiriq 9 — GitHub

bash
$ mkdir 5-oy-dars-8
$ git add . && git commit -m "feat: dars 8 - pointer, massiv, string" && git push

Asosiy tushunchalar (lug'at)

TerminIzoh
mallocMemory ALLOCation — dinamik xotira
callocCleared alloc (0 bilan)
reallocHajmni o'zgartirish
freeXotirani bo'shatish
Memory leakYo'qotilgan xotira
Use after freefree'dan keyin ishlatish
Double freeIkki marta free
HeapDinamik xotira joyi
StackLocal o'zgaruvchilar joyi
Pointer arithmeticPointer bilan massiv bo'ylab yurish
strchr / strstrBelgini/substringni topish (pointer qaytaradi)
strtokString'ni bo'lish
snprintfXavfsiz formatlangan yozish
fgetsQator olish (xavfsiz)
AnagramBir xil harflardan tuzilgan so'zlar
ValgrindMemory bug topish vositasi

Keyingi dars

9-dars: Struct asoslari →

Master IT o'quv markazi — o'qitish rejasi