Bitmap megvalósítás

Nemrég kezdtem el takarítani a projektjeimet, és úgy döntöttem, hogy szeretnék létrehozni egy személyes tárhelyet hasznos kódfájlokból. Megtaláltam közöttük ezt a bitkép kódot, és erősen szerkesztettem, és nagyra értékelném, ha valaki át tudná nézni, mert nem szoktam a bitenkénti műveleteket meg ilyeneket. Elég hordozható a kód, vagy változtatásokra van szükség?

bitmap.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 

bitmap.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); } 

Megjegyzések

  • Bárki számára, aki még mindig követi ezt a bejegyzést, arra késztettem a kódot, hogy github ide . Az összes hozzászólását kérdésként is felvettem. Köszönjük észrevételeit, és elkezdem őket végrehajtani.

Válasz

Ha arra számítasz, hogy a kódod valaha is C ++ – ból (amely sok C kódból áll), akkor ne használjon kettős aláhúzással rendelkező azonosítókat.

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

Mivel ez a megvalósításhoz van fenntartva C ++ – ban. A BITMAP kifejezés szintén nagyon általános, és nagy valószínűséggel ütközik más könyvtárakkal, és próbáld egyedibbé tenni a projektedet.

Feltételezed, hogy egy karakter 8 bites.

#define BIT (8*sizeof(byte)) 

A szabvány ezt nem mondja meg (legalább 8 bit), de a CHAR_BITS makrón keresztül van meghatározva, ezért használd:

#define BIT (CHAR_BITS*sizeof(byte)) 

A fejlécfájl az, ahogyan a legtöbb ember először meglátja a kódot, és megpróbálja megérteni, hogyan kell használni. Ezért valószínűleg jó ötlet a paraméternevek felvétele a fejlécfájlba, mivel segít dokumentálni a használatukat.

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

Kiegészítse a nem nyilvánvaló, ezért a fejlécben való használatával kapcsolatos megjegyzés valószínűleg jó ötlet lenne. Valójában jó ötlet, hogy az első paraméter miként lehet egy tömb (valószínűleg nem egyértelmű a kód elolvasása nélkül).

Legyen óvatos a megjegyzésekkel:

/* pos is something from 0 to 7*/ 

Ez csak akkor igaz, ha feltételezéseket tesz (A: a (byte) mérete == 1 B: ezt megszorozza 8-val). A megjegyzésnek a következőnek kellett volna lennie:

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

Vegye figyelembe a bal oldalon a “[“, a jobb oldalon a “)” szót. Matematikai jelölés azt jelzi, hogy a 0 inkluzív és a BIT nem szerepel a tartományban (mindkét C / C ++ dokumentációban gyakori).

Válasz

  1. A típusai feleslegesek – csak írja be az előjel nélküli karaktert és az int-et, mint a szokásos könyvtár.

  2. Ugyanezen témakörben az enum bool nem szükséges, mert C-ben a nulla nem az igazi állapotot jelöli. Ezt te magad is megerősíted, mert a get () feltételezi, hogy az 1 érték igaz. Mindenki ezt feltételezi, ezért a típus felesleges. Sőt, ez azért is hibás, mert ha az enum-ot

    typedef enum{true=0, false} bool; 

    -re változtatom, akkor a funkciója meghiúsul, annak ellenére, hogy logikailag ésszerű dolog.

    Ha ilyen boolt szeretne használni, akkor kifejezetten vissza kell adnia az egyik értékét:

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

    de ennek valójában nincs értelme. Csak adja vissza az int-t, ahogy a szokásos könyvtár megtenné.

  3. A bool visszaadása tévesnek tűnik számomra. A bittérkép bitjeinek értéke 1 és 0, nem igaz és hamis (annak ellenére, hogy ezek jelenleg ugyanazok). A bitmapIsSet () hívása logikusabb lenne.

  4. A size (char) definíció szerint 1, így a BIT helyettesíthető CHAR_BIT

  5. A függvények nyitó zárójelei általában a 0 oszlopban vannak.

  6. A bitmapSearch paramétereinek sorrendje logikusabb lenne, mivel a követett méret követi a tárgyat (bitkép).

  7. A bitmapSearch kezdési paramétere hibás. A 0-tól (biztosan a leggyakoribb) kezdő keresés megadásához a hívónak -1-et kell átadnia !!

  8. Miért adja át a “pos” paramétert “bájtként”? Meghatározta, hogy a “bájt” képviselje a bittérkép bájtokat, és a “pos” természetesen nem tartozik ezek közé. Fordítói figyelmeztetéseket kap, ha engedélyezik őket (legyenek) a prototípusok miatt különböző szélességű argumentumok átadásáról. A “pos” bájtra való korlátozása további gépi utasításokat adhat hozzá (nézze meg az összeszerelőt), miközben semmit nem ér el. Ha megadhat egy olyan pos_t típust a 0..7 tartományban, amelyet látszólag szeretne, akkor azzal érvelhet, hogy valamilyen módon helyes volt, de mivel ezt C-ben nem teheti meg, és egyértelműen a bájt értéke 0-ig terjed. 255, ez nem jobb, mint egy int használatát.

Válasz

Nem sikerült kérdezzen a teljesítményről, de a ritka bittérképekért felgyorsíthatja a bitmapSearch t, ha először egy-egy bájtot néz meg. Ha 1-et keres, akkor kihagyhatja a 0x00-as bájtokat, és ha 0 keresése esetén kihagyhatja a 0xFF bájtokat. Ezt követően beolvashatja a következő bájt bitjeit, vagy használhat rajta egy keresőtáblát.

Ami az API-t illeti, hozzáadhat

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

így az ügyfélnek nem kell aggódnia, hogy hány bájt kiosztás.

És / vagy egy makrót ad meg az allokációkhoz. Makró a függvény helyett, ha azt szeretné, hogy tömb allokációkban jelenjen meg. div>

Ezenkívül bitmapSearch is bitszámként veszi a méretét a bájtok helyett. Aztán ha az ügyfél csak mondjuk 26 bitet érdekel a levelekért, akkor nem kell attól tartania, hogy a keresés 27-et ad vissza, mert a bittérképben valóban 32 bit van.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük