6-dars: Pointer asoslari
Dars haqida
Davomiyligi: 90 daqiqa Maqsad: Talaba pointer tushunchasini, xotira manzili va dereference operatorlarini bilishi kerak. C tilining eng kuchli (va eng qiyin) tushunchasi.
1. Pointer nima?
Pointer — xotiradagi manzilni saqlovchi o'zgaruvchi.
int x = 42; // x — int o'zgaruvchi
int *p = &x; // p — pointer, x ning manzilini saqlaydiAslida — pointer xotira hujayrasining raqami (manzili).
Xotira:
┌────────────┐
│ address │
├────────────┤
│ 0x100: 42 │ ← x bu yerda
├────────────┤
│ 0x104: 0x100│ ← p bu yerda (x ning manzili)
└────────────┘2. & — address-of operator
int x = 42;
printf("%p\n", &x); // x ning manzili (masalan, 0x7ffd...)&x — x ning manzili.
scanf("%d", &x) da ham shu — x manzilini berish.
3. * — dereference operator
int x = 42;
int *p = &x;
printf("%d\n", *p); // 42 — pointer orqali qiymatni olish*p — pointer ko'rsatayotgan joydagi qiymat.
4. Pointer e'lon qilish
int *p; // int uchun pointer
double *dp; // double uchun pointer
char *cp; // char uchun pointer
int *arr_p; // massiv elementi uchun* — turning bir qismi. Bu ikkisi bir xil:
int* p;
int *p;Lekin int* p1, p2; — faqat p1 pointer, p2 — oddiy int!
To'g'ri:
int *p1, *p2;5. Pointer initialize
int x = 42;
int *p = &x; // OK
int *p2; // ko'rsatmaydigan pointer (xavfli!)
int *p3 = NULL; // bo'sh pointer (xavfsiz)Initialize unutmang
int *p;
*p = 5; // CRASH! p qayerga ko'rsatayotgani noma'lumDoim NULL yoki real manzil bilan.
6. NULL pointer
int *p = NULL;
if (p == NULL) {
printf("Pointer bo'sh\n");
}NULL — "hech qayerga ko'rsatmayapti". Maxsus qiymat (0 ga teng).
Doim tekshiring:
if (p != NULL) {
*p = 42; // xavfsiz
}7. Pointer arithmetic
int x = 42;
int *p = &x;
printf("%p\n", p); // 0x100 (taxminan)
printf("%p\n", p + 1); // 0x104 (4 bayt o'tdi — int 4 bayt)Pointer + 1 — navbatdagi element manzili.
p + n — n ta element o'tib.
8. Birinchi misol
#include <stdio.h>
int main(void) {
int x = 42;
int *p = &x;
printf("x ning qiymati: %d\n", x);
printf("x ning manzili: %p\n", &x);
printf("p ning qiymati: %p\n", p);
printf("*p (ko'rsayotgan): %d\n", *p);
// O'zgartirish
*p = 100;
printf("Yangi x: %d\n", x); // 100!
return 0;
}*p = 100 — pointer orqali x ni o'zgartirdi.
9. Pointer va funksiya — Pass by Reference
C'da funksiya argumentlari nusxa uzatiladi. Pointer bilan — manzil.
void increment(int *x) {
*x = *x + 1;
}
int main(void) {
int n = 10;
increment(&n);
printf("%d\n", n); // 11
return 0;
}Endi funksiya tashqaridagi qiymatni o'zgartirdi.
10. Swap funksiyasi
Pointer'siz ishlamaydi:
void swap_bad(int a, int b) {
int temp = a;
a = b;
b = temp;
}
int main(void) {
int x = 5, y = 10;
swap_bad(x, y);
printf("%d %d\n", x, y); // 5 10 (o'zgarmadi!)
return 0;
}Pointer bilan — ishlaydi:
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main(void) {
int x = 5, y = 10;
swap(&x, &y);
printf("%d %d\n", x, y); // 10 5
return 0;
}11. Bir nechta qiymat qaytarish
C funksiyasi bitta qiymat qaytaradi. Bir nechta — pointer orqali.
void divide(int a, int b, int *quotient, int *remainder) {
*quotient = a / b;
*remainder = a % b;
}
int main(void) {
int q, r;
divide(17, 5, &q, &r);
printf("17 / 5 = %d (qoldiq %d)\n", q, r); // 3 qoldiq 2
return 0;
}12. Pointer va array bog'liqligi
Array nomi — pointer (birinchi element manzili).
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr; // arr == &arr[0]
printf("%d\n", *p); // 10
printf("%d\n", *(p+1)); // 20
printf("%d\n", *(p+2)); // 30
printf("%d\n", arr[0]); // 10
printf("%d\n", *arr); // 10 (bir xil)arr[i] aslida *(arr + i).
13. Pointer va string
String — char massivi. Demak — pointer:
char str[] = "Hello";
char *p = str;
printf("%c\n", *p); // H
printf("%c\n", *(p+1)); // e
printf("%s\n", p); // Hello14. Pointer to pointer
Pointer'ga pointer:
int x = 42;
int *p = &x;
int **pp = &p;
printf("%d\n", x); // 42
printf("%d\n", *p); // 42
printf("%d\n", **pp); // 42Foydalanish — kam, lekin mavjud (matritsa pointer, command line argumentlar).
15. const pointer
const int x = 10;
const int *p = &x; // p — const int ga ko'rsatadi
// *p = 20; ← XATO
int y = 10;
int *const q = &y; // q ning o'zi const (manzilni o'zgartirib bo'lmaydi)
// q = NULL; ← XATO
// *q = 20; ← OK (y o'zgaradi)
const int *const r = &x; // ham qiymat, ham manzil const16. Pointer va printf
int x = 42;
int *p = &x;
printf("%p\n", p); // %p — pointer formati
printf("%p\n", &x); // bir xil17. Common pitfalls
1. Dereferencing NULL
int *p = NULL;
*p = 42; // CRASH (segmentation fault)2. Dangling pointer
int *p;
{
int x = 10;
p = &x;
}
// x — yo'q, lekin p hali ko'rsatadi
*p; // noma'lum — bug3. Pointer arithmetic xatolari
int arr[5];
int *p = arr;
p = p + 100;
*p = 5; // CRASH — chegaradan tashqari4. & va * ni aralashtirish
int x = 5;
int *p;
*p = &x; // XATO — *p int, &x int*
p = &x; // To'g'ri18. Pointer foydasi
| Foyda | Misol |
|---|---|
| Pass by reference | swap(&x, &y) |
| Multiple return | divide(a, b, &q, &r) |
| Massiv funksiyaga | C'da boshqa yo'l yo'q |
| Dinamik xotira | malloc() |
| Linked list, tree | Data structures |
| Tezlik | nusxa olish kerak emas |
19. To'liq misol: Statistika
#include <stdio.h>
void analyze(int arr[], int n, int *sum, int *max, int *min, double *avg) {
*sum = 0;
*max = arr[0];
*min = arr[0];
for (int i = 0; i < n; i++) {
*sum += arr[i];
if (arr[i] > *max) *max = arr[i];
if (arr[i] < *min) *min = arr[i];
}
*avg = (double)*sum / n;
}
int main(void) {
int data[] = {12, 45, 7, 23, 89, 34, 56};
int n = 7;
int sum, max, min;
double avg;
analyze(data, n, &sum, &max, &min, &avg);
printf("Sum: %d\n", sum);
printf("Max: %d\n", max);
printf("Min: %d\n", min);
printf("Avg: %.2f\n", avg);
return 0;
}Darsdagi topshiriqlar
1 — Asosiy
pointer-basics.c:
#include <stdio.h>
int main(void) {
int x = 42;
int *p = &x;
printf("x = %d\n", x);
printf("&x = %p\n", &x);
printf("p = %p\n", p);
printf("*p = %d\n", *p);
*p = 100;
printf("Yangi x = %d\n", x);
return 0;
}Natijani oldindan o'ylab daftarga yozing.
2 — Swap
swap.c — pointer bilan ishlovchi swap.
Test:
int a = 5, b = 10;
swap(&a, &b);
// a = 10, b = 53 — Increment funksiya
increment.c:
void increment(int *x) {
(*x)++;
}
void multiply_by_2(int *x) {
*x *= 2;
}
int main(void) {
int n = 10;
increment(&n);
printf("%d\n", n); // 11
multiply_by_2(&n);
printf("%d\n", n); // 22
return 0;
}4 — Multiple return
divide.c — dars matnidagi divide funksiya.
Yana — min_max.c:
void min_max(int arr[], int n, int *min, int *max);5 — Statistika
Dars matnidagi to'liq analyze funksiya.
6 — Pointer arithmetic
arithmetic.c:
#include <stdio.h>
int main(void) {
int arr[] = {10, 20, 30, 40, 50};
int *p = arr;
for (int i = 0; i < 5; i++) {
printf("arr[%d] = %d, *(p+%d) = %d, p[%d] = %d\n",
i, arr[i], i, *(p+i), i, p[i]);
}
return 0;
}7 — String pointer
string-pointer.c:
char str[] = "Hello World";
char *p = str;
while (*p != '\0') {
putchar(*p);
p++;
}
putchar('\n');8 — NULL handling
null.c:
void safe_print(int *p) {
if (p == NULL) {
printf("Pointer bo'sh\n");
return;
}
printf("Qiymat: %d\n", *p);
}
int main(void) {
int x = 42;
safe_print(&x);
safe_print(NULL);
return 0;
}9 — Hisoblash
calc-with-ptr.c:
void calculate(int a, int b, int *sum, int *diff, int *prod, int *quot) {
*sum = a + b;
*diff = a - b;
*prod = a * b;
if (b != 0) {
*quot = a / b;
} else {
*quot = 0;
}
}
int main(void) {
int s, d, p, q;
calculate(20, 4, &s, &d, &p, &q);
printf("Sum: %d, Diff: %d, Prod: %d, Quot: %d\n", s, d, p, q);
return 0;
}10 — GitHub
$ mkdir 5-oy-dars-6
$ git add . && git commit -m "feat: dars 6 - pointers" && git pushLug'at
| Termin | Izoh |
|---|---|
| Pointer | Manzilni saqlovchi o'zgaruvchi |
| Address | Xotiradagi joy raqami |
& | Address-of operator |
* | Dereference operator |
| NULL | Bo'sh pointer |
| Pass by reference | Manzil orqali uzatish |
| Dereferencing | Pointer orqali qiymat olish |
| Pointer arithmetic | Pointer'ni qo'shish/ayirish |
| Dangling pointer | Yo'q joyga ko'rsatuvchi |
| Memory leak | Yo'qotilgan xotira |