9-bo‘lim
Massivlar
Bir va ko'p o'lchamli massivlar, indekslash, xotirada joylashuvi, chegaradan chiqish xavfi va massivlar bilan ishlash usullari.
Ushbu bo‘lim mundarijasi
Massiv - bir turdagi elementlarni ketma-ket saqlaydigan tuzilma. Bu C dagi eng asosiy ma'lumot tuzilmasi.
Massiv yaratish #
int baholar[5]; /* bo'sh massiv */
int ballar[5] = {85, 92, 78, 95, 88}; /* qiymat bilan */
int nollar[5] = {0}; /* hammasi nol */
int qisqa[] = {1, 2, 3}; /* hajm avtomatik: 3 */
#include <stdio.h>
int main(void) {
int ballar[5] = {85, 92, 78, 95, 88};
printf("Birinchi element : %d\n", ballar[0]);
printf("Uchinchi element : %d\n", ballar[2]);
printf("Oxirgi element : %d\n", ballar[4]);
ballar[1] = 100;
printf("O'zgartirilgan : %d\n", ballar[1]);
return 0;
}
Birinchi element : 85
Uchinchi element : 78
Oxirgi element : 88
O'zgartirilgan : 100
5 elementli massivda indekslar 0, 1, 2, 3, 4. ballar[5] yo'q!
Bu eng ko'p uchraydigan xato - «bittaga adashish» (off-by-one) deb ataladi.
int ballar[5];
for (int i = 1; i <= 5; i++) { /* NOTO'G'RI */
ballar[i] = 0; /* ballar[5] mavjud emas */
}
for (int i = 0; i < 5; i++) { /* to'g'ri */
ballar[i] = 0;
}
Qoida: for (int i = 0; i < hajm; i++) - <, <= emas.
Massivni aylanish #
#include <stdio.h>
int main(void) {
int ballar[5] = {85, 92, 78, 95, 88};
int soni = sizeof(ballar) / sizeof(ballar[0]);
printf("Massivda %d ta element bor.\n", soni);
for (int i = 0; i < soni; i++) {
printf(" [%d] = %d\n", i, ballar[i]);
}
return 0;
}
Massivda 5 ta element bor.
[0] = 85
[1] = 92
[2] = 78
[3] = 95
[4] = 88
int soni = sizeof(massiv) / sizeof(massiv[0]);
Bu «butun massivning bayt hajmini bitta elementning hajmiga bo'lish» degani. Massiv hajmi o'zgarsa, bu hisob avtomatik moslashadi.
Muhim ogohlantirish: bu hiyla faqat massiv e'lon qilingan
funksiyada ishlaydi. Massivni funksiyaga uzatsangiz, u ko'rsatkichga
aylanadi va sizeof ko'rsatkich hajmini beradi. Buni 13-bo'limda
batafsil ko'ramiz.
Chegaradan chiqish #
int ballar[5] = {85, 92, 78, 95, 88};
printf("%d\n", ballar[10]); /* XAVFLI: begona xotira */
ballar[100] = 42; /* XAVFLI: begona xotirani buzadi */
Python'da ballar[10] xatolik beradi. C da esa dastur shunchaki
o'sha manzildagi baytlarni o'qiydi - u yerda nima bo'lsa ham.
Natija uch xil bo'lishi mumkin:
- Axlat qiymat chiqadi (eng «yaxshi» holat - xatoni sezasiz);
- Boshqa o'zgaruvchi buziladi (xato butunlay boshqa joyda ko'rinadi);
- Dastur qulaydi (segmentation fault).
Eng yomoni - birinchi holat, chunki dastur ishlayotgandek ko'rinadi.
Himoya usullari:
- Indeksni doim tekshiring;
- Sikllarda
< hajmyozing; - Kompilyatsiyada
-fsanitize=addressbayrog'ini ishlating (19-bo'lim).
Qidiruv va statistika #
#include <stdio.h>
int main(void) {
int ballar[8] = {85, 92, 78, 95, 88, 61, 100, 73};
int soni = sizeof(ballar) / sizeof(ballar[0]);
int eng_katta = ballar[0];
int eng_kichik = ballar[0];
int yigindi = 0;
for (int i = 0; i < soni; i++) {
if (ballar[i] > eng_katta) {
eng_katta = ballar[i];
}
if (ballar[i] < eng_kichik) {
eng_kichik = ballar[i];
}
yigindi += ballar[i];
}
printf("Elementlar soni : %d\n", soni);
printf("Eng katta : %d\n", eng_katta);
printf("Eng kichik : %d\n", eng_kichik);
printf("Yig'indi : %d\n", yigindi);
printf("O'rtacha : %.2f\n", (double) yigindi / soni);
return 0;
}
Elementlar soni : 8
Eng katta : 100
Eng kichik : 61
Yig'indi : 672
O'rtacha : 84.00
int eng_katta = 0; /* xato bo'lishi mumkin */
Agar barcha elementlar manfiy bo'lsa, natija 0 bo'lib qoladi - bu massivda umuman yo'q qiymat.
To'g'ri yo'l - birinchi elementdan boshlash:
int eng_katta = massiv[0];
Chiziqli qidiruv #
#include <stdio.h>
int main(void) {
int ballar[8] = {85, 92, 78, 95, 88, 61, 100, 73};
int soni = 8;
int qidirilayotgan = 95;
int topilgan_indeks = -1;
for (int i = 0; i < soni; i++) {
if (ballar[i] == qidirilayotgan) {
topilgan_indeks = i;
break;
}
}
if (topilgan_indeks != -1) {
printf("%d qiymati %d-indeksda topildi.\n", qidirilayotgan, topilgan_indeks);
} else {
printf("%d topilmadi.\n", qidirilayotgan);
}
return 0;
}
95 qiymati 3-indeksda topildi.
Massivni saralash #
#include <stdio.h>
int main(void) {
int ballar[6] = {85, 92, 78, 95, 88, 61};
int soni = 6;
/* Pufakcha saralash */
for (int i = 0; i < soni - 1; i++) {
for (int j = 0; j < soni - i - 1; j++) {
if (ballar[j] > ballar[j + 1]) {
int vaqtinchalik = ballar[j];
ballar[j] = ballar[j + 1];
ballar[j + 1] = vaqtinchalik;
}
}
}
printf("Saralangan: ");
for (int i = 0; i < soni; i++) {
printf("%d ", ballar[i]);
}
printf("\n");
return 0;
}
Saralangan: 61 78 85 88 92 95
int vaqtinchalik = a;
a = b;
b = vaqtinchalik;
C da Python'dagi a, b = b, a yo'q. Uchinchi o'zgaruvchi kerak -
aks holda birinchi qiymat yo'qoladi.
Ikki o'lchamli massiv #
#include <stdio.h>
int main(void) {
int jadval[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
for (int qator = 0; qator < 3; qator++) {
for (int ustun = 0; ustun < 4; ustun++) {
printf("%4d", jadval[qator][ustun]);
}
printf("\n");
}
printf("\n[1][2] elementi: %d\n", jadval[1][2]);
return 0;
}
1 2 3 4
5 6 7 8
9 10 11 12
[1][2] elementi: 7
Jadval bilan ishlash #
#include <stdio.h>
int main(void) {
int savdo[3][4] = {
{120, 150, 130, 170},
{200, 180, 210, 190},
{ 90, 110, 100, 120}
};
const char *mahsulotlar[3] = {"Klaviatura", "Sichqoncha", "Monitor"};
printf("%-12s %6s %6s %6s %6s %8s\n",
"Mahsulot", "1-chor", "2-chor", "3-chor", "4-chor", "Jami");
int umumiy = 0;
for (int i = 0; i < 3; i++) {
int qator_jami = 0;
printf("%-12s", mahsulotlar[i]);
for (int j = 0; j < 4; j++) {
printf("%6d", savdo[i][j]);
qator_jami += savdo[i][j];
}
printf("%8d\n", qator_jami);
umumiy += qator_jami;
}
printf("%-12s %6s %6s %6s %6s %8d\n", "JAMI", "", "", "", "", umumiy);
return 0;
}
Mahsulot 1-chor 2-chor 3-chor 4-chor Jami
Klaviatura 120 150 130 170 570
Sichqoncha 200 180 210 190 780
Monitor 90 110 100 120 420
JAMI 1770
Massivni nusxalash #
#include <stdio.h>
int main(void) {
int asl[5] = {1, 2, 3, 4, 5};
int nusxa[5];
/* int nusxa = asl; XATO: massivni shunchaki tenglashtirib bo'lmaydi */
for (int i = 0; i < 5; i++) {
nusxa[i] = asl[i];
}
nusxa[0] = 100;
printf("Asl : %d %d\n", asl[0], asl[1]);
printf("Nusxa : %d %d\n", nusxa[0], nusxa[1]);
return 0;
}
Asl : 1 2
Nusxa : 100 2
memcpy bilan tezroq#include <string.h>
memcpy(nusxa, asl, sizeof(asl));
memcpy xotira bloklarini bir yo'la ko'chiradi va sikldan tezroq
ishlaydi. Faqat hajmni to'g'ri hisoblang - sizeof(asl) baytlarda
beradi, elementlar sonida emas.
Massivni nol bilan to'ldirish #
#include <stdio.h>
#include <string.h>
int main(void) {
int a[5] = {0}; /* barcha elementlar nol */
int b[5];
memset(b, 0, sizeof(b)); /* keyinroq nollash */
printf("a: ");
for (int i = 0; i < 5; i++) printf("%d ", a[i]);
printf("\nb: ");
for (int i = 0; i < 5; i++) printf("%d ", b[i]);
printf("\n");
return 0;
}
a: 0 0 0 0 0
b: 0 0 0 0 0
memset faqat baytlarni to'ldiradiint a[5];
memset(a, 1, sizeof(a)); /* 1 EMAS! */
memset har bir baytga 1 yozadi, shuning uchun har bir int
0x01010101 = 16843009 bo'ladi.
memset faqat 0 va -1 uchun xavfsiz. Boshqa qiymatlar uchun
oddiy sikl yozing.
- 10 elementli massiv yaratib, uni 1 dan 10 gacha to'ldiring.
- Massivning yig'indisi, o'rtachasi va eng kattasini toping.
- Massivni teskari tartibda chiqaring.
- Chegaradan chiqib, nima bo'lishini ko'ring (
massiv[100]). - Massivda berilgan qiymatni qidiring.
- Pufakcha saralashni yozib, har qadamni chiqaring.
- Ikkita massivni birlashtirib, uchinchisiga yozing.
- 3x3 matritsa yaratib, uning diagonali yig'indisini toping.
- Matritsani transponirlang (qator va ustunni almashtiring).
- Massivdagi juft va toq sonlar sonini hisoblang.
Xulosa #
- Massiv - bir turdagi elementlarning ketma-ket to'plami.
- Indeks noldan boshlanadi; oxirgi indeks -
hajm - 1. - C chegarani tekshirmaydi - chegaradan chiqish xotirani buzadi.
- Sikllarda doim
i < hajmyozing,i <= hajmemas. - Elementlar soni:
sizeof(massiv) / sizeof(massiv[0]). - Bu hiyla massiv e'lon qilingan funksiyada ishlaydi.
- Eng katta/kichikni qidirishda boshlang'ich qiymatni birinchi elementdan oling.
- Massivni
=bilan nusxalab bo'lmaydi - sikl yokimemcpykerak. - Ikki o'lchamli massiv xotirada qator bo'yicha ketma-ket yotadi.
memsetbaytlar bilan ishlaydi - faqat 0 uchun xavfsiz.
Keyingi bo'limda satrlarni - C dagi eng o'ziga xos mavzuni 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.