簡體   English   中英

C ++將DWORD分解為字符

[英]C++ Breaking DWORD into characters

我有一個四字節的DWORD,我需要分成四個不同的字符。 我以為我知道怎么做到這一點但每次都得到奇怪的數字。 這是我的代碼:

    // The color memory
    int32 col = color_mem[i];

    // The four destination characters
    char r, g, b, a;

    // Copy them in advancing by one byte every time
    memcpy(&r, &col, 1);
    memcpy(&g, &col + 1, 1);
    memcpy(&b, &col + 2, 1);
    memcpy(&a, &col + 3, 1);

拋棄memcpy並使用位操作:

r = (col & 0x000000ff);
g = (col & 0x0000ff00) >>  8;
b = (col & 0x00ff0000) >> 16;
a = (col & 0xff000000) >> 24;

十六進制數中的ff表示所有1位的字節。 這和& - 按位AND - 將使您不感興趣的字節 - 在每個位置 - 0 ,並保留您感興趣的位。

>>從左移零,將我們想要的字節放在最重要的位置,用於實際分配。 8個移位寬度為1個字節,16個為2個字節,24個為3個字節。

在視覺上,看着ff ,你可以想象我們正在將字節索引向左移動。

進行指針運算時,增量或減量的數量乘以指向的類型的大小。 int32指針強制轉換為char指針,以便在col的基址偏移一定距離處訪問char大小的部分。

由於不同平台上的字節序差異,此技術可能很脆弱,因此我建議使用另一個答案中提供的更便攜的位掩碼操作。

// The color memory  
int32 col = color_mem[i];  

// The four destination characters  
char r, g, b, a;  

// Copy them in advancing by one byte every time  
memcpy(&r, (char*)&col, 1);  
memcpy(&g, ((char*)&col) + 1, 1);  
memcpy(&b, ((char*)&col) + 2, 1);  
memcpy(&a, ((char*)&col) + 3, 1); 

向int32添加+1將使地址增加4個字節。

您可以使用memcpy(&g, reinterpret_cast<char *>(&col)+1, 1)等。

更好的方法:

int32 col = color_mem[i];

struct splitted4byte
{
    char r;
    char g;
    char b;
    char a;
}

splitted4byte rgb;

memcpy(&rgb, &col, 4);

你應該關心col字節的順序。 我不知道int32的哪一部分是哪種顏色。

你應該閱讀關於字節序的內容。 (谷歌,有文件)

當R最高值和其他顏色為0時,如果它存儲為1111 1111 0000 0000 0000 0000 0000 0000 ,則表示顏色RGBA(255,0,0,0)的整數表示等於此二進制值。 它將在內存中反向排序,即0000 0000 0000 0000 0000 0000 1111 1111 ,因此您需要計算它。

您可以使用網絡轉換函數將網絡字節順序(big-endian)轉換為主機 - 機器字節順序(小端或大端)。 這樣您就不需要根據機器更改代碼。 (函數是ntohl(網絡到主機長),還有htons(主機到網絡短)等2字節,64位整數也有64toh(),但該函數僅在Unix變種上退出我記得沒錯。)你需要做的就是int32 col = ntohl(color_mem[i]);

或者你可以根據這個來制作你的結構順序,但這樣你的代碼就無法在big-endian上運行。

因為col是int32 + 1,所以添加4個字節的偏移量

在谷歌上搜索指針算術

每個人都給出了不同的答案,而且所有答案都是正確的。 有些是特定於字節序的(如按位操作)。 其他人不是。 為清楚起見,我可能會這樣做:

char *bytes = (char*)&color_mem[i];
char r = bytes[0];
char g = bytes[1];
char b = bytes[2];
char a = bytes[3];

我認為沒有任何理由使用memcpy 即使有結構。 結構分配是一種語言功能 - 您無需復制它。

還沒有看到任何關於工會的提及......

union Pixel {
    DWORD packed;
    struct Components {
        char r, g, b, a;
    };
    char bytes[4];
};

// You can just specify your image data like this...
Pixel *pixels = (Pixel*)color_mem;

// Reference one pixel for convenience - don't need to reference, you can
// just copy it instead if you want (alternative: Pixel p = pixels[i])
Pixel &p = pixels[i];

char r = p.r;
char g = p.g;
char b = p.b;
char a = p.a;

int32 col = p.packed;

這是endian-neutral:它不依賴於整數的組織。 通常這很好,但你仍然需要意識到它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM