Bittikartan toteutus

Aloitin äskettäin projektieni siivoamisen ja päätin, että haluan luoda henkilökohtaisen tietovaraston hyödyllisistä koodibiteistä. Löysin tämän välillä bittikarttakoodin ja muokkain sitä voimakkaasti, ja arvostan, voisiko joku tarkistaa sen, koska en ole tottunut bittikohtaisiin operaatioihin ja vastaaviin. Onko koodi riittävän kannettava, vai onko siihen muutoksia?

bittikartta.h

#ifndef BITMAP__ #define BITMAP__ #define BIT (8*sizeof(byte)) #define BITMAP_NOTFOUND -1 typedef enum{false=0, true} bool; typedef unsigned char byte; bool bitmapGet (byte *, int); void bitmapSet (byte *, int); void bitmapReset (byte *, int); int bitmapSearch(byte *, bool, int, int); #endif 

bittikartta.c

#include "bitmap.h" static bool get (byte, byte); static void set (byte *, byte); static void reset(byte *, byte); /* CAREFUL WITH pos AND BITMAP SIZE! */ bool bitmapGet(byte *bitmap, int pos) { /* gets the value of the bit at pos */ return get(bitmap[pos/BIT], pos%BIT); } void bitmapSet(byte *bitmap, int pos) { /* sets bit at pos to 1 */ set(&bitmap[pos/BIT], pos%BIT); } void bitmapReset(byte *bitmap, int pos) { /* sets bit at pos to 0 */ reset(&bitmap[pos/BIT], pos%BIT); } int bitmapSearch(byte *bitmap, bool n, int size, int start) { /* Finds the first n value in bitmap after start */ /* size is the Bitmap size in bytes */ int i; /* size is now the Bitmap size in bits */ for(i = start+1, size *= BIT; i < size; i++) if(bitmapGet(bitmap,i) == n) return i; return BITMAP_NOTFOUND; } static bool get(byte a, byte pos) { /* pos is something from 0 to 7*/ return (a >> pos) & 1; } static void set(byte *a, byte pos) { /* pos is something from 0 to 7*/ /* sets bit to 1 */ *a |= 1 << pos; } static void reset(byte *a, byte pos) { /* pos is something from 0 to 7*/ /* sets bit to 0 */ *a &= ~(1 << pos); } 

Kommentit

  • Kaikille, jotka edelleen seuraavat tätä viestiä, annoin koodin github tänne . Lisäsin myös kaikki kommenttisi ongelmiksi. Kiitos kommenteistasi ja aloitan niiden toteuttamisen.

Vastaa

Jos uskot, että koodisi tulee koskaan olemaan käytetään C ++: sta (mikä on paljon C-koodia), sinun ei tule käyttää tunnuksia, joissa on kaksoisviiva.

#ifndef BITMAP__ // ^^ May cause problems in C++ 

Koska tämä on varattu toteutukselle C ++: ssa. Myös termi BITMAP on hyvin yleinen ja olet todennäköisesti ristiriidassa muiden kirjastojen kanssa ja yritä tehdä siitä ainutlaatuisempi projektillesi.

Oletat, että merkin arvo on 8 bittiä.

#define BIT (8*sizeof(byte)) 

Standardi ei sano tätä (se on vähintään 8 bittiä), mutta se on itse asiassa määritelty makron CHAR_BITS kautta, joten sinun tulisi käyttää:

#define BIT (CHAR_BITS*sizeof(byte)) 

Otsikkotiedostosi on, kuinka useimmat ihmiset näkevät koodisi ensin ja yrittävät ymmärtää, miten sitä käytetään. Siksi parametrien nimien lisääminen otsikkotiedostoon on todennäköisesti hyvä idea, koska se auttaa dokumentoimaan niiden käytön.

bool bitmapGet (byte *, int); void bitmapSet (byte *, int); void bitmapReset (byte *, int); int bitmapSearch(byte *, bool, int, int); 

Lisätään toiminnon ei ole ilmeinen, joten kommentti sen käytöstä otsikossa olisi todennäköisesti hyvä idea. Oikeastaan pieni idea siitä, kuinka ensimmäinen parametri voi olla taulukko, olisi todennäköisesti hyvä idea (koska se ei ole ilmeistä lukematta koodia).

Ole varovainen kommenttien kanssa:

/* pos is something from 0 to 7*/ 

Tämä pätee vain, jos teet oletuksia (A: (tavun koko) == 1 B: kerrot tämän kahdeksalla). Kommentin olisi pitänyt olla:

/* pos is a value between [0, BIT) */ 

Huomaa ”[” vasemmalla ja ”)” oikealla. Se on matemaattinen merkintä, joka osoittaa, että 0 on sisällyttävä ja BIT ei sisälly alueeseen (se on yleistä molemmissa C / C ++ -dokumentaatioissa).

Vastaus

  1. Tyypit ovat tarpeettomia – käytä vain allekirjoittamatonta merkkiä ja int kuten tavallinen kirjasto.

  2. Samasta aiheesta enum-boolisi on tarpeeton, koska C: ssä ei-nolla osoittaa todellisen tilan. Vahvistat sen itse, koska get () olettaa, että arvo 1 on tosi. Kaikki olettavat tämän, joten tyyppi on tarpeeton. Lisäksi se on väärin, koska jos vaihdan enumisi

    typedef enum{true=0, false} bool; 

    toiminto epäonnistuu, vaikka se onkin loogisesti järkevää.

    Jos haluat käyttää tällaista boolia, sinun on palautettava yksi sen arvoista nimenomaisesti:

    return ((a >> pos) & 1) ? true : false; 

    mutta tässä ei ole mitään järkeä. Palauta vain int kuten tavallinen kirjasto.

  3. bitmapGet () palauttaa boolin, minusta tuntuu väärältä. Bittikarttabiteillä on arvot 1 ja 0, eivät tosi ja epätosi (vaikka nämä ovat tällä hetkellä samat). Kutsuminen sille bitmapIsSet () olisi loogisempi.

  4. sizeof (char) on määritelmänsä mukaan 1, joten BIT voidaan korvata CHAR_BIT

  5. Funktioiden avaamissulkeet ovat normaalisti sarakkeessa 0

  6. Parametrien järjestys bittikarttahakuun olisi loogisempi, koska sen koko, jota se viittaa (bittikartta).

  7. BitmapSearch-aloitusparametri on väärä. Jos haluat määrittää haun bitistä 0 alkaen (varmasti yleisin), soittajan on läpäistävä -1 !!

  8. Miksi ”pos” -parametri välitetään tavuna? Olet määrittänyt ”tavu” edustamaan bittikarttatavuja ja ”pos” ei todellakaan kuulu niihin. Saat kääntäjävaroituksia, jos ne ovat käytössä (niiden pitäisi olla) prototyyppien vuoksi erilaisten argumenttien välittämisestä. Ja ”pos”: n rajoittaminen tavuun voi lisätä koneen ylimääräisen käskyn (katso kokoonpanijaa) ja saavuttaa mitään. Jos pystyt määrittelemään tyypin pos_t alueella 0..7, jota näytät haluavan, saatat väittää, että se oli jollain tavalla oikea, mutta koska et voi tehdä sitä C: ssä ja tavuarvolla on selvästi alue 0. 255, se ei ole parempi kuin käyttää int.

Vastaa

En tehnyt ”t kysy suorituskyvystä, mutta voit nopeuttaa bitmapSearch harvoja bittikarttoja varten katsomalla ensin tavua kerrallaan. Jos etsit 1: tä, voit ohittaa tavuja, jotka ovat 0x00, ja jos etsimällä 0, voit ohittaa tavut, jotka ovat 0xFF. Sen jälkeen voit skannata seuraavan tavun bittejä tai käyttää siinä hakutaulukkoa.

API: n suhteen voit lisätä

byte * bitmapAlloc(int sizeInBits); void bitmapFree(byte * bitmap); 

joten asiakkaan ei tarvitse huolehtia siitä, kuinka monta tavua allokointi.

Ja / tai tarjoa makro, joka auttaa allokoinnissa. Makro funktion sijasta, jos haluat sen näkyvän taulukon allokoinnissa. div>

Minulla on myös bitmapSearch otettava sen koko bittilaskuna tavujen määrän sijaan. Jos asiakas sitten välittää vain sanoista 26 bittiä kirjeistä, heidän ei tarvitse huolehtia hausta, joka palauttaa 27, koska bittikartassa on todella 32 bittiä.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *