繁体   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