C-keeles 16ndbaasi kasutamine: täielik juhend algajatele ja edasijõudnutele

1. Sissejuhatus

C-keel on võimas programmeerimiskeel, mida kasutavad paljud programmeerijad ja mis pakub rohkelt tõhusaid viise arvväärtuste töötlemiseks. Nende hulgas kasutatakse “16-ndbaasi” sageli bititaseme operatsioonides ja mälu haldamisel. Käesolevas artiklis selgitame üksikasjalikult 16-ndbaasi kasutamist C-keeles alates põhiteadmistest kuni rakendusteni. Selgitame samm-sammult, et ka need, kes puutuvad esmakordselt kokku 16-ndbaasiga, saaksid sellest aru.

2. Arvude esitamise viisid

10-, 8- ja 16-ndbaasi erinevused

C-keeles saab arve esitada järgmiselt:

  1. Kümnendsüsteem
    Inimeste igapäevaselt kasutatav arvude esitamise viis. Näiteks 123 tõlgendatakse kümnendarvuna.
  2. Kaheksandsüsteem
    Kui numbri ette panna 0, tõlgendatakse seda kaheksandarvuna. Näiteks 0123 tähendab kaheksandsüsteemis arvu „83“.
  3. Kuueteistkümnendsüsteem
    Kui numbri ette panna 0x või 0X, tõlgendatakse seda kuueteistkümnendarvuna. Näiteks 0x123 tähendab kuueteistkümnendsüsteemis arvu „291“.

16-ndbaasi eelised

16-ndbaasi kasutatakse binaararvu lihtsustatud vormina. Üks 16-ndbaasi number esindab nelja binaarbittti, mistõttu on see väga mugav bititaseme operatsioonides. Seda kasutatakse sageli ka silumisel mälu sisu kontrollimiseks.

年収訴求

3. 16-ndbaasi põhitõed

16-ndbaasi struktuur

16-ndbaas koosneb järgmistest sümbolitest:

  • 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
    Siin tähendab A arvu 10, B arvu 11, …, ja F arvu 15.

16-ndbaasist kümnendsüsteemi teisendamine

Näiteks teisendamaks 16-ndbaasi arvu 0x2F kümnendsüsteemi:

  • 0x2F = (2 × 16) + (15 × 1) = 47

Kümnendsüsteemist 16-ndbaasi teisendamine

Kümnendsüsteemi arvu 47 16-ndbaasi teisendamiseks:

  1. Jaga 16-ga (47 ÷ 16 = 2, jääk 15).
  2. Kasutage jagatist ülemise kohana ja jääki alumise kohana.
  • Tulemus: 0x2F

4. 16-ndbaasi literaalide märkimine C-keeles

Literaali kirjutamine

C-keeles kirjutatakse 16-ndbaasi järgmiselt:

int hexValue = 0x1A; // 16-ndbaasis tähendab „26“

16-ndbaasi väljastamine printf abil

16-ndbaasi väljastamiseks kasutatakse printf funktsiooni:

#include <stdio.h>

int main() {
    int hexValue = 0x1A;
    printf("16ndbaas: %X\n", hexValue); // Suurtes tähtedes
    printf("16ndbaas: %x\n", hexValue); // Väikestes tähtedes
    return 0;
}

Väljund:

16ndbaas: 1A
16ndbaas: 1a

Näide omistamisest täisarvutüübile

16-ndbaasi saab omistada täisarvulistele muutujatele.

int num = 0xFF; // Tõlgendatakse kui 255

5. 16-ndbaas ja bititasandi operatsioonid

Bitimaski kasutamine

16-ndbaasi kasutatakse sageli bitimaskide puhul. Näide:

#include <stdio.h>

int main() {
    unsigned char value = 0xAF; // 16-ndbaasis „AF“
    unsigned char mask = 0x0F;  // Mask, et eraldada alumised 4 bitti

    unsigned char result = value & mask;
    printf("Tulemus: 0x%X\n", result); // Tulemus: „0x0F“
    return 0;
}

Bitilippude seadmine

Konkreetse biti väärtuseks 1 seadmine:

unsigned char flags = 0x00;
flags |= 0x10; // Seab 4. biti väärtuseks 1

6. 16-ndbaas ja ujukomaarvud

Ujukomaarvu kuvamine 16-ndbaasis on erijuht, kuid seda saab teha printf abil:

#include <stdio.h>

int main() {
    double value = 123.456;
    printf("16ndbaasi formaat: %a\n", value);
    return 0;
}

Näide väljundist:

16ndbaasi formaat: 0x1.ed70a3d70a3d7p+6

7. 16-ndbaasi rakendusnäited

Mäludump’i analüüs

Silumise käigus mälu sisu kuvamine 16-ndbaasis:

#include <stdio.h>

void dumpMemory(void* ptr, size_t size) {
    unsigned char* byte = (unsigned char*)ptr;
    for (size_t i = 0; i < size; i++) {
        printf("%02X ", byte[i]);
        if ((i + 1) % 16 == 0) printf("\n");
    }
}

int main() {
    int data = 0x12345678;
    dumpMemory(&data, sizeof(data));
    return 0;
}

8. Kokkuvõte

Käesolevas artiklis selgitasime 16-ndbaasi kasutamist C-keeles alates põhiteadmistest kuni praktiliste rakendusteni. 16-ndbaas on kasulik mitte ainult arvude esitamisel, vaid ka bititasandi operatsioonides ja silumisel. C-keelt kasutades tasub kindlasti oma teadmisi 16-ndbaasist süvendada.

KKK: Levinud küsimused C-keele 16-ndbaasi kohta

K1: Mis juhtub, kui unustan C-keeles 16-ndbaasi ette kirjutada 0x?

Kui 16-ndbaasi literaalil puudub eesliide 0x või 0X, tõlgendatakse seda arvuna kümnendsüsteemis.
Näiteks:

int value = 123; // Seda käsitletakse kui kümnendarvu 123

Kui soovite kasutada 16-ndbaasi, lisage alati 0x.

K2: Kuidas sisestada 16-ndbaasi väärtus C-keeles (scanf)?

scanf abil saab lugeda 16-ndbaasi väärtusi, kasutades vormingumäärajat %x.
Näide:

#include <stdio.h>

int main() {
    int value;
    printf("Sisestage 16ndbaasi arv (nt: 0x1A): ");
    scanf("%x", &value);
    printf("Sisestatud väärtus kümnendsüsteemis: %d\n", value);
    return 0;
}

K3: Kuidas käsitleda 16-ndbaasi kui stringi?

Kui soovite 16-ndbaasi väärtust käsitleda stringina, saate kasutada stringifunktsioone või vormingumääranguid.
Näiteks teisendades arvu 16-ndbaasi stringiks:

#include <stdio.h>

int main() {
    int value = 255;
    char hexStr[10];
    sprintf(hexStr, "%X", value);
    printf("16ndbaasi string: %s\n", hexStr);
    return 0;
}

Väljund:

16ndbaasi string: FF

K4: Mis juhtub, kui 16-ndbaasi number on lühem kui tavaliselt?

C-keeles toimib 16-ndbaasi literaal ka ilma täisnumbrite arvuta. Näiteks 0xA tähendab sama mis 0x000A. Kuid koodi loetavuse huvides võib olla soovitatav kasutada nullidega täitmist.

K5: Mis on peamised vead 16-ndbaasi kasutamisel C-keeles?

Levinumad vead:

  1. Puuduv 0x literaali ees
  • Lahendus: lisa alati 0x või 0X.
  1. Vale vormingumäärang
  • Näiteks püüad printf abil kuvada 16-ndbaasi kasutades %d.
  • Lahendus: kasuta %x või %X.
  1. Tüübiviga
  • Näiteks ei määra unsigned tüüpi ja saad ootamatu märgiga väärtuse.
  • Lahendus: vajadusel kasuta unsigned.

K6: Kuidas teisendada kümnendsüsteemi arv 16-ndbaasi?

Saate kasutada printf funktsiooni:
Näide:

#include <stdio.h>

int main() {
    int decimalValue = 42;
    printf("Kümnendsüsteem: %d -> 16ndbaas: %X\n", decimalValue, decimalValue);
    return 0;
}

K7: Kas 16-ndbaasis saab kasutada negatiivseid väärtusi?

Jah, kuid neid esitatakse kahendtäienduse vormis.
Näide:

#include <stdio.h>

int main() {
    int negativeValue = -16;
    printf("Kümnendsüsteem: %d -> 16ndbaas: %X\n", negativeValue, negativeValue);
    return 0;
}

Väljund:

Kümnendsüsteem: -16 -> 16ndbaas: FFFFFFF0

K8: Kuidas käsitleda 16-ndbaasi massiive C-keeles?

Saate luua massiivi, kasutades otse 16-ndbaasi literaale:
Näide:

#include <stdio.h>

int main() {
    unsigned char hexArray[] = {0x1A, 0x2B, 0x3C, 0x4D};

    for (int i = 0; i < sizeof(hexArray); i++) {
        printf("Massiiv[%d]: 0x%X\n", i, hexArray[i]);
    }
    return 0;
}

Väljund:

Massiiv[0]: 0x1A
Massiiv[1]: 0x2B
Massiiv[2]: 0x3C
Massiiv[3]: 0x4D
侍エンジニア塾