7-bo‘lim
Xotira, manzillar va bayt tartibi
Xotira baytlar massivi sifatida, katta va kichik bayt tartibi, bir xil baytlarni turlicha o'qish va tuzilmalarni tekislash.
Ushbu bo‘lim mundarijasi
Xotira - bu shunchaki raqamlangan kataklar massivi. Har katak bitta bayt, har baytning manzili bor.
Bitta baytdan katta son esa bir necha katakka yoziladi. Va shu yerda kutilmagan savol chiqadi: qaysi tartibda?
Ikki xil tartib #
0x12345678 sonini olaylik. U to'rt baytdan iborat:
12, 34, 56, 78. Savol - ular xotiraga qaysi
tartibda yoziladi?
| Tartib | Baytlar |
|---|---|
| Katta (big-endian) | 12 34 56 78 |
| Kichik (little-endian) | 78 56 34 12 |
Manzillar bo'yicha yoyib ko'rsak:
| Manzil | Katta tartibda | Kichik tartibda |
|---|---|---|
| +0 | 0x12 | 0x78 |
| +1 | 0x34 | 0x56 |
| +2 | 0x56 | 0x34 |
| +3 | 0x78 | 0x12 |
Katta tartibda son odam o'qiganidek yoziladi - eng katta bayt oldinda. Kichik tartibda esa teskari.
Bugungi kompyuterlarning aksariyati (Intel, AMD va odatdagi holatda ARM) kichik tartibni ishlatadi.
Ikkalasi ham to'g'ri - shunchaki ikki xil kelishuv:
| Tartib | Birinchi baytda | Kim ishlatadi |
|---|---|---|
| Katta (big-endian) | Eng muhim bayt | Tarmoq protokollari, PNG, Java |
| Kichik (little-endian) | Eng kichik bayt | x86, ARM, RISC-V, BMP |
1980-yilda Denni Koen "On Holy Wars and a Plea for Peace" nomli maqola yozdi va atamani Jonatan Sviftning "Gulliverning sayohatlari" asaridan oldi.
Romanda ikki davlat tuxumni qaysi tomondan - yo'g'on (big end) yoki ingichka (little end) - chaqish kerakligi ustida urushadi.
Koen shu bilan aytmoqchi ediki: bahs mazmunsiz, muhimi - kelishib olish. Qaysi tartib "to'g'ri" degan savolning javobi yo'q.
Qiziq: x86 kichik tartibni ishlatadi, internet esa katta tartibni. Shuning uchun har paket yuborilganda baytlar o'giriladi.
Nima uchun bu muhim #
Tarmoqdan to'rt bayt keldi: 00 00 04 d2. Ularni son deb
o'qiymiz:
| Qanday o'qildi | Natija |
|---|---|
| Katta tartibda (to'g'ri) | 1234 |
| Kichik tartibda (xato) | 3 523 477 504 |
Farq - uch milliarddan ortiq. Va eng yomoni shundaki, bu xato jimgina yuz beradi: hech qanday ogohlantirish chiqmaydi, dastur shunchaki noto'g'ri son bilan ishlayveradi.
Shuning uchun tartib oldindan kelishib olinadi:
| Qayerda | Qaysi tartib |
|---|---|
| Tarmoq protokollari | har doim katta |
| PNG fayl formati | katta |
| BMP fayl formati | kichik |
| Intel va AMD protsessorlari | kichik |
Yana bir misol: 41 42 43 44 baytlarini turlicha o'qish
mumkin, va har safar boshqa natija chiqadi:
| Qanday o'qildi | Natija |
|---|---|
| Matn sifatida | ABCD |
| Katta tartibdagi son | 1 094 861 636 |
| Kichik tartibdagi son | 1 145 258 561 |
| Ikkita 2 baytli son | 16 706 va 17 220 |
| To'rtta alohida bayt | 65, 66, 67, 68 |
Baytlarning o'zida ma'no yo'q. Ma'no - ularni qanday o'qishga kelishib olganingizda.
Oxirgi blok eng muhim xulosani beradi: baytlarning o'zida ma'no yo'q.
41 42 43 44 - bu ABCD matnimi, 1094861636 soni-mi yoki
ikkita kichik son-mi? Javob faqat bitta narsaga bog'liq:
siz uni qanday o'qiysiz.
Tur (type) aynan shu ma'lumotni beradi - baytlarni qanday talqin qilish kerakligini.
Yuqoridagi misolda 1234 o'rniga 3523477504 chiqdi.
Dastur yiqilmadi, xato bermadi - shunchaki noto'g'ri son bilan ishlashda davom etdi.
Bunday xatolar eng qimmatga tushadi. Himoya usullari:
| Chora | Izoh |
|---|---|
! yoki > ni aniq yozing | Hech qachon tartibni faraz qilmang |
| Qiymat diapazonini tekshiring | Kutilmagan katta son - belgi |
| Sinov ma'lumotini ikkala tartibda o'qing | Qaysi biri mantiqli ekani ko'rinadi |
Fayl formatlarida ko'pincha sehrli son (magic number) boshida turadi - u ham tartibni aniqlashga yordam beradi.
Tekislash va tuzilma hajmi #
Protsessor xotiradan 8 baytli sonni 8 ga karrali manzildan o'qiganda tez ishlaydi. Shuning uchun kompilyator maydonlar orasiga bo'sh joy qoldiradi.
Uchta qismdan iborat tuzilmani olaylik:
| Qism | Hajmi |
|---|---|
| Belgi | 1 bayt |
| Butun son | 4 bayt |
| Haqiqiy son | 8 bayt |
| Yig'indi | 13 bayt |
Mantiqan tuzilma 13 bayt bo'lishi kerak. Amalda esa uning hajmi qismlar tartibiga bog'liq:
| Tartib | Haqiqiy hajm | Nazariy hajm | Baho |
|---|---|---|---|
| belgi, haqiqiy, butun | 20 bayt | 13 | eng yomon |
| belgi, butun, haqiqiy | 16 bayt | 13 | yomon |
| haqiqiy, butun, belgi | 13 bayt | 13 | eng yaxshi |
Sabab - tekislash:
Amaliy xulosa sodda: tuzilmadagi maydonlarni kattadan kichikka tartiblang. Bu hech narsa talab qilmaydi, lekin millionlab yozuvda sezilarli joy tejaydi.
Maydonlar tartibini o'zgartirish hech narsaga to'lamaydi: kod bir xil, mantiq bir xil, faqat e'lon tartibi boshqa.
Millionlab yozuvli massivda bu sezilarli tejash beradi - ham xotira, ham kesh bo'yicha (14-bo'limda ko'ramiz).
Qoida sodda: kattadan kichikka tartiblang.
Rust va Go kompilyatorlari ba'zan buni o'zi qiladi, C va C++ esa sizning tartibingizni saqlaydi - chunki tuzilma tashqi formatga mos kelishi kerak bo'lishi mumkin.
Aynan shuning uchun fayl yoki tarmoq formatini tavsiflaganda tekislashni o'chirish kerak bo'ladi: u yerda har bayt aniq belgilangan o'rinda turishi shart va qo'shimcha bo'sh baytlar formatni buzadi.
x86 tekislanmagan manzildan o'qishga ruxsat beradi, faqat sekinroq ishlaydi.
Lekin ba'zi ARM va ko'p o'rnatilgan protsessorlarda bu dastur qulashiga olib keladi (bus error).
Bu klassik "mening mashinamda ishlayapti" holati: kod x86 da yillab ishlaydi, keyin boshqa arxitekturaga ko'chirilganda darhol yiqiladi.
Shuning uchun xotiradagi xom baytlarni to'g'ridan-to'g'ri tuzilma deb o'qish xavfli. Ularni nusxalab, keyin o'qish ancha ishonchli.
0xDEADBEEFni ikkala bayt tartibida yozib chiqing.- Sizning kompyuteringiz qaysi tartibda ishlaydi? Toping.
00 00 04 d2baytlarini ikkala tartibda son qilib o'qing.- Nima uchun tarmoqda katta tartib tanlanganini ayting.
41 42 43 44ni matn va son sifatida o'qib, farqni yozing.- Belgi, butun va haqiqiy sondan iborat tuzilmani eng zich tartibda joylang.
- Unga 2 baytli son qo'shilsa, tartib qanday o'zgaradi?
- Nima uchun tekislash tezlik beradi - uch qatorda yozing.
- PNG faylining birinchi 8 baytini o'qib, sehrli sonni toping.
- Nima uchun bir xil baytlar turli ma'no berishini tushuntiring.
Xulosa #
- Xotira - raqamlangan baytlar massivi; har baytning manzili bor.
- Ko'p baytli son ikki xil tartibda yozilishi mumkin: katta va kichik.
- Ikkalasi ham to'g'ri - bu shunchaki kelishuv.
- x86 va ARM kichik tartibni, tarmoq protokollari esa katta tartibni ishlatadi.
- "Endian" atamasi Sviftning romanidan olingan: bahs mazmunsiz, kelishuv muhim.
- Bayt tartibi xatosi jimgina yuz beradi - dastur yiqilmaydi, faqat noto'g'ri ishlaydi.
- Baytlarning o'zida ma'no yo'q - tur ularni qanday o'qishni aytadi.
- Protsessor tekislangan manzillardan tez o'qiydi.
- Shuning uchun tuzilma hajmi maydonlar tartibiga bog'liq.
- Maydonlarni kattadan kichikka tartiblang - bu bepul tejash.
Keyingi bo'limda eng pastki qatlamga tushamiz: mantiqiy elementlardan sumator quramiz.
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.