DEV Community

Cover image for CS50 - Week 4
Dilbar
Dilbar

Posted on

CS50 - Week 4

Piksellar

Piksellar – bu rasmni tashkil etuvchi eng kichik rangli nuqtalardir.
Rasmni nollardan va birlardan iborat deb tasavvur qilsak, bunda nollar qora rangni, birlar esa oq rangni ifodalaydi:

smiley

RGB (Red, Green, Blue) – bu har bir rangning miqdorini ifodalovchi sonlar. Adobe Photoshop dasturida ushbu sozlamalarni ko‘ramiz:

hex in photoshop

Qizil, yashil va ko‘k ranglarining tanglangan miqdori rangni qanday o‘zgartirishini yuqoridagi rasmda ko‘rishimiz mumkin. Shuningdek, ushbu rasmda rang faqat uchta qiymat orqali emas, balki maxsus raqam va belgilardan tashkil topgan qiymat bilan ifodalanishini ham ko‘rishimiz mumkin. Masalan, 255 qiymati FF sifatida ko‘rsatilgan.


O‘n oltilik sanoq sistemasi (Hexadecimal)

O‘n oltilik sanoq sistemasi - sonlarni faqat 16 belgidan foydalanib yozishga asoslangan sanoq sistemasi. Ular quyidagilar:

0 1 2 3 4 5 6 7 8 9 A B C D E F
Enter fullscreen mode Exit fullscreen mode

O‘n oltilik sanoq sistemasida har bir ustun 16 darajasini ifodalaydi.
000 sifatida
101 sifatida
909 sifatida
100A sifatida
150F sifatida
1610 sifatida
255FF sifatida ifodalanadi, chunki 16 x 15 (yoki F) 240 ga teng, unga yana 15 qo‘shilganda 255 bo‘ladi. Bu o‘n oltilik sanoq sistemasida ifodalash mumkin bo‘lgan ikki xonali eng katta son hisoblanadi.

O‘n oltilik sanoq sistemasi ma’lumotlarni qisqaroq ko‘rinishda ifodalash imkonini beradi. Shuning uchun u ma’lumotlarni ixchamroq ifodalash uchun qulay hisoblanadi.


Xotira (Memory)

Xotira bloklarini o‘n oltilik sanoq sistemasi orqali raqamlab chiqsak, ularni quyidagicha tasavvur qilishimiz mumkin:

memory hex

Rasmdagi 10 bloki xotiradagi joylashuvni yoki 10 qiymatini ifodalayotganini aniqlash qiyin bo‘lishi mumkin. Shuning uchun, odatda, barcha o‘n oltilik sonlar 0x prefiksi bilan ifodalanadi:

0x

Butun son n o'zgaruvchisiga 50 qiymatini beramiz:

#include <stdio.h>

int main(void)
{
    int n = 50;
    printf("%i\n", n);
}
Enter fullscreen mode Exit fullscreen mode

Dasturning ushbu qiymatni xotirada qanday saqlayotganini quyidagicha tasavvur qilish mumkin:

hex

C tilida xotira bilan ishlashga oid quyidagi operatorlar mavjud:

  • & – Xotiradagi biror qiymatning manzilini beradi.
  • * – Kompilyatorga xotiradagi joylashuvga borishni buyuradi.

Agar n o'rgaruvchimizning xotiradigi manzilini bilmoqchi bo'lsak, yuqoridagi kodimizni quyidagicha o'zgartirishimiz mumkin:

#include <stdio.h>

int main(void)
{
    int n = 50;
    printf("%p\n", &n);
}
Enter fullscreen mode Exit fullscreen mode

%p – xotiradagi joylashuv manzilini ko‘rish imkonini beradi. &n esa kodni ishga tushirganimizda n o'zgaruvchisining xotiradagi 0x bilan boshlangan manzilini qaytaradi.


Ko'rsatkichlar (Pointers)

Ko‘rsatkich – bu qiymatning kompyuter xotirasidagi manzilini o‘zida saqlaydigan o‘zgaruvchi.

int n = 50;
int *p = &n;
Enter fullscreen mode Exit fullscreen mode

Bunda p ko‘rsatkich bo‘lib, u butun son nning manzilini o‘z ichiga oladi.

pointer

Ko‘rsatkichlar odatda 8 baytli qiymat sifatida saqlanadi. p yuqoridagi rasmda 50 qiymatining manzilini saqlamoqda.
Ko‘rsatkichni xotiradagi bir manzildan boshqasiga ishora qiluvchi o‘q sifatida tasavvur qilishimiz mumkin:

pointer


String

String - bu oddiygina belgilar massividir. Masalan, string s = "HI!"ni kompyuter xotirasida quyidagicha tasvirlash mumkin:

hi

s deb nomlangan ko‘rsatkich kompilyatorga berilgan qiymatning birinchi bayti qayerda joylashganini ko‘rsatadi:

hi pointer

string ma'lumot turidagi o'zgaruvchini quyidagicha yaratishimiz mumkin:

#include <stdio.h>

int main(void)
{
    char *s = "HI!";
    printf("%s\n", s);
}
Enter fullscreen mode Exit fullscreen mode

Yuqoridagi kod s joylashuvdan boshlanadigan belgilar massivini ekranga chiqaradi.


String Comparison (Solishtirish)

string ma'lumot turidagi o'zgaruvchi qiymatlarni bir-biri bilan solishtiramiz:

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    // Qiymatlarni olish
    char *s = get_string("s: ");
    char *t = get_string("t: ");

    // Solishtirish
    if (s == t)
    {
        printf("Bir xil\n");
    }
    else
    {
        printf("Turlicha\n");
    }
}
Enter fullscreen mode Exit fullscreen mode

Yuqoridagi kodimizda s va t o'zgaruvchilarimizga bir xil "Hi!" qiymatini bersak ham natija sifatida "Turlicha" xabari ekranga chiqadi.
Nega bunday bo'layotganligini bilish uchun s va t o'zgaruvchilarimizga bir xil qiymat berib, ularni kompyuter xotirasida quyidagicha tasvirlashimiz mumkin:

two strings

Demak, yuqoridagi kod aslida, s va t o'zgaruvchilarining xotiradagi manzillarini solishtirishga urinayotgan ekan, ularning qiymatlarini emas.


Copying (Nusxalash)

Quyidagi kod berilgan bo'lsin:

#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    // Qiymat kiritamiz
    string s = get_string("s: ");

    // Manzilini nusxalaymiz
    string t = s;

    // Birinchi harfini kattalashtiramiz
    t[0] = toupper(t[0]);

    // Ekranga chop etamiz
    printf("s: %s\n", s);
    printf("t: %s\n", t);
}
Enter fullscreen mode Exit fullscreen mode

string t = s kodida s manzili tga nusxalanadi. Bu biz xohlagan natijani bermaydi, chunki qiymat nusxalanmadi – faqat uning manzili nusxalandi.

copying

s va t bir xil xotira bloklariga ishora qilmoqda. sdan tga uning qiymatini nusxalay olmadik, balki ular bitta qatorni ko‘rsatib turgan ikkita ko‘rsatkichga aylanishdi.

malloc – dasturchiga ma’lum o‘lchamdagi xotira blokini ajratish imkonini beradi.
free – oldin ajratilgan xotira blokini bo‘shatishni kompyuterdan so‘raydi.
Kodni haqiqiy nusxa yaratish uchun quyidagicha o‘zgartiramiz:

#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    // Qiymat kiritamiz
    char *s = get_string("s: ");

    // Yangi o'zgaruvchi uchun xotira ajratamiz
    char *t = malloc(strlen(s) + 1);
    if (t == NULL)
    {
        return 1;
    }

    // Qiymatni yangi o'zaruvchi uchun ajratilgan xotiraga nusxalaymiz
    for (int i = 0, n = strlen(s); i <= n; i++)
    {
        t[i] = s[i];
    }

    // Birinchi harfini kattalashtiramiz
    t[0] = toupper(t[0]);

    // Ekranga chop etamiz
    printf("s: %s\n", s);
    printf("t: %s\n", t);

    // Xotirani bo‘shatish
    free(t);
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

malloc(strlen(s) + 1) - s o'zgaruvchi uzunligiga birni qo‘shib, \0 belgisi uchun joy ajratadi. Keyin for sikli orqali s qiymatlari tga nusxalanadi.


Garbage Values (Keraksiz qiymatlar)

Agar kompilyatordan xotira bloki so‘rasak, bu xotiraning bo‘sh bo‘lishiga kafolat yo‘q. Ajratilgan xotira ilgari kompyuter tomonidan ishlatilgan bo‘lishi mumkin, shuning uchun u yerda keraksiz qiymatlar bor bo‘lishi ehtimoli mavjud:

garbage values

#include <stdio.h>

int main(void)
{
    int scores[1024];
    for (int i = 0; i < 1024; i++)
    {
        printf("%i\n", scores[i]);
    }
}
Enter fullscreen mode Exit fullscreen mode

Ushbu kodni ishga tushirganimizda, massiv uchun 1024 ta xotira joyi ajratiladi, lekin for sikli yordamida massiv elementlarining qiymatlarini ekranga chiqarganimizda ularning hammasi ham 0 qiymatga ega bo'lmasligini ko'ramiz.

Kompyuterdan har doim biror-bir o'zgaruvchi uchun xotira ajratishni so'raganimizda, unga 0 yoki boshqa qiymat berib boshlang'ich holatga keltirish yaxshi amaliyot hisoblanadi.

Ushbu maqolada CS50x 2024 manbasidan foydalanilgan.

Top comments (0)