我如何将 4 个字符放入一个 int 中?
How would I put 4 chars into a single int?
我正在使用 C++ 开发复制版 GM 缓冲系统以熟悉位等,这还不错,但我 运行 遇到了问题。如何将 4 个不同的字符放入一个 int 中?我不是最擅长按位的东西,我从来没有用过它。我不知道该怎么做。
在事物中,我有一个字符数组;大小为 byteArraySize
,当我调用 grab int 函数时,它将占用从 bufferPointer + 4
到 bufferPointer
的字节;向后以正确获取 int。
我读了一篇关于位移位的 位 (笑),我想我可以将每个字符的位 i
位向右位移。我只是不知道从哪里开始。
非常感谢任何帮助。
是的,您可以将 4 char
(实际上是 sizeof(int)
char
)打包成一个 int
。方法如下:
unsigned int packChars(unsigned char *c)
{
unsigned int val = u0;
for (size_t idx = 0; idx < sizeof(unsigned int); ++idx) {
val |= c[idx] << (idx * CHAR_BIT);
}
}
我使用的是无符号类型,因为当涉及到符号位时,移位会变得棘手。也不是上面的代码在使用的大小上是有意通用的:sizeof(unsigned int)
给你 char
单位的数量适合 unsigned int
,而 CHAR_BIT
指定位数在 char
.
一个可能的解决方案是使用一个联合,它的所有成员都从内存中的相同偏移量对齐。
示例:
union Color
{
std::uint32_t m_rgba;
struct
{
std::uint8_t m_a;
std::uint8_t m_b;
std::uint8_t m_g;
std::uint8_t m_r;
};
};
Color white = { 0xffffffff };
首先你应该知道,sizeof(int) 不一定是 4 *sizeof(char)。标准只保证 sizeof(int) >= sizeof(char) 仅此而已。
事实上 int 可以与 char 的大小相同(或更大),但你永远不知道,除非你发现这一点。
迂腐地说,在纯标准 C++14 或 C++11 中,您可能不能。
AFAIK,没有什么可以禁止假设的 C++14 实现具有所有 char
、short
、unsigned short
、int
、unsigned int
、 long
、unsigned long
、long long
、unsigned long long
是相同的类型(至少相同的内部表示),并且都是 64 位,(或 96 位,或 128位)和所有 sizeof
1. 最近的 C 和 C++ 标准要求 long long
至少有 64 位。
IIRC,一些 Common Lisp 之上的一些奇怪的 C 实现正在做类似的事情。
当然,实际上并没有这样的 C++14 实现。
实际上,在大多数实现中,char
-s 是 8 位字节(可能 signed
或 unsigned
)而 int
-s 通常是 32 位字(例如 std::int32_t
),你显然可以编码
inline int pack4chars(char c1, char c2, char c3, char c4) {
return ((int)(((unsigned char)c1) << 24)
| (int)(((unsigned char)c2) << 16)
| (int)(((unsigned char)c3) << 8)
| (int)((unsigned char)c4));
}
需要强制转换为 (unsigned char)
,因为某些实现已签署 char
-s,而其他实现则未签署。
另请参阅 endianness, serialization, htonl(3)
我正在使用 C++ 开发复制版 GM 缓冲系统以熟悉位等,这还不错,但我 运行 遇到了问题。如何将 4 个不同的字符放入一个 int 中?我不是最擅长按位的东西,我从来没有用过它。我不知道该怎么做。
在事物中,我有一个字符数组;大小为 byteArraySize
,当我调用 grab int 函数时,它将占用从 bufferPointer + 4
到 bufferPointer
的字节;向后以正确获取 int。
我读了一篇关于位移位的 位 (笑),我想我可以将每个字符的位 i
位向右位移。我只是不知道从哪里开始。
非常感谢任何帮助。
是的,您可以将 4 char
(实际上是 sizeof(int)
char
)打包成一个 int
。方法如下:
unsigned int packChars(unsigned char *c)
{
unsigned int val = u0;
for (size_t idx = 0; idx < sizeof(unsigned int); ++idx) {
val |= c[idx] << (idx * CHAR_BIT);
}
}
我使用的是无符号类型,因为当涉及到符号位时,移位会变得棘手。也不是上面的代码在使用的大小上是有意通用的:sizeof(unsigned int)
给你 char
单位的数量适合 unsigned int
,而 CHAR_BIT
指定位数在 char
.
一个可能的解决方案是使用一个联合,它的所有成员都从内存中的相同偏移量对齐。
示例:
union Color
{
std::uint32_t m_rgba;
struct
{
std::uint8_t m_a;
std::uint8_t m_b;
std::uint8_t m_g;
std::uint8_t m_r;
};
};
Color white = { 0xffffffff };
首先你应该知道,sizeof(int) 不一定是 4 *sizeof(char)。标准只保证 sizeof(int) >= sizeof(char) 仅此而已。
事实上 int 可以与 char 的大小相同(或更大),但你永远不知道,除非你发现这一点。
迂腐地说,在纯标准 C++14 或 C++11 中,您可能不能。
AFAIK,没有什么可以禁止假设的 C++14 实现具有所有 char
、short
、unsigned short
、int
、unsigned int
、 long
、unsigned long
、long long
、unsigned long long
是相同的类型(至少相同的内部表示),并且都是 64 位,(或 96 位,或 128位)和所有 sizeof
1. 最近的 C 和 C++ 标准要求 long long
至少有 64 位。
IIRC,一些 Common Lisp 之上的一些奇怪的 C 实现正在做类似的事情。
当然,实际上并没有这样的 C++14 实现。
实际上,在大多数实现中,char
-s 是 8 位字节(可能 signed
或 unsigned
)而 int
-s 通常是 32 位字(例如 std::int32_t
),你显然可以编码
inline int pack4chars(char c1, char c2, char c3, char c4) {
return ((int)(((unsigned char)c1) << 24)
| (int)(((unsigned char)c2) << 16)
| (int)(((unsigned char)c3) << 8)
| (int)((unsigned char)c4));
}
需要强制转换为 (unsigned char)
,因为某些实现已签署 char
-s,而其他实现则未签署。
另请参阅 endianness, serialization, htonl(3)