我有一个四字节的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);
答案 0 :(得分:9)
抛弃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
,您可以想象我们正在向左移动字节索引。
答案 1 :(得分:4)
进行指针运算时,增量或减量的数量乘以指向的类型的大小。将int32
指针强制转换为char
指针,以便在char
基址的偏移处访问col
个大小的部分。
由于不同平台上的字节序差异,此技术可能很脆弱,因此我建议使用另一个答案中提供的更便携的位掩码操作。
// 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);
答案 2 :(得分:2)
向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上运行。
答案 3 :(得分:1)
因为col是int32 + 1,所以添加4字节的偏移量
在Google上搜索指针算术
答案 4 :(得分:0)
每个人都给出了不同的答案,而且所有答案都是正确的。有些是特定于字节序的(如按位操作)。其他人不是。为清楚起见,我可能会这样做:
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;
这是字节序中立的:它不依赖于整数的组织。通常这很好,但你仍然需要意识到它。