首页 > 解决方案 > 在 C++ 中遍历 char 数组的位

问题描述

我还在学习 C++,希望能在这个问题上得到一些帮助。我正在尝试迭代 C++ 中的 char 数组,但遇到了一些麻烦。

所以我目前理解的方式是,一个 char 数组只是 X 数量的 8 位值,它们彼此相邻存储在内存中(我在这里可能完全错误)以 00 结尾。

所以我想做的是迭代内存中的这个比特集合,并将它们组合成更小或更大的段。一个例子是,如果我有 8 个字符,并且我想将该字符串转换为两个 32 位整数或一个 64 位整数。

除了我试图让自己更好地理解 C++ 如何存储变量之外,这没有任何意义,所以如果我正在做的事情是不可能的或者只是公然愚蠢,请随时告诉我:D

标签: c++

解决方案


所以我目前理解事物的方式是,一个数组char只是 X 数量的 8 位值,彼此相邻存储在内存中......

几乎正确,但 a在 C 和 C++char保证是 8 位(一个八位字节)。请记住,C 和 C++ 几乎可以针对现有的任何处理器和 ISA,包括具有自身特性的稀有和奇异机器。我推荐阅读这个 QA:'char' always-always-always-always 有 8 位吗?

...以 00 结尾。

这是一个不完全正确的假设,对不起。

虽然“字符串”必须具有终止符(根据 C 语言规范),但字符数组可能不一定具有 aa -NULL终止符('\0'末尾的 char)。从字符串文字初始化的字符串将附加一个空终止符,但您仍然可以构造一个char没有空终止符的字符串或 -array。

所以我想做的是遍历内存中的这个比特集合,并将它们组合成更小或更大的段。一个例子是,如果我有 8 个字符,并且我想将该字符串转换为两个 32 位整数或一个 64 位整数。

如果您想强制 C++ 解释一个内存范围(即 8 个八位字节或 8 个char长字节),然后使用reinterpret_cast并告诉 C++ 查看字符串指针指向的数据的值:

const char* stringFromLiteral = "abcdefgh";

uint64_t* pointerToStringLiteralPretentingToBePointerToUInt64 = reinterpret_cast<uint64_t*>( stringFromLiteral );

uint64_t asUnsigned64bitInteger = *pointerToStringLiteralPretentingToBePointerToUInt64;

在这种情况下,这是进程的只读内存和堆栈(可能)的样子,假设只读内存位于0x0800并且当前函数的堆栈帧从 开始0x1000,并且它是一个 32 位大端字机(so sizeof(char*) == 4) 并且所有值都与 16 位边界对齐:

(每行是 8 个字节的内存,每行以每行第一个字节的地址为前缀。行地址后面的每个十六进制数字代表一个char(八位字节)值。每个....代表一个具有未定义值的八位字节(实际上,它的值可以是最后一个用户留下的任何值0x00(对于预置零内存)或某些调试器生成的溢出检测测试模式)。

0x0800    0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68     # The "abcdefgh" string literal is in read-only memory at 0x8000 through 0x0808, including the 0x00 terminator byte.
0x0808    0x00 .... .... .... .... .... .... ....
0x0810    ....  ... .... .... .... .... .... ....

[ Jump forward about 0x200 bytes ]

0x1000    0x00 0x00 0x80 0x00 .... .... .... ....     # The `stringFromLiteral` variable has a 4-byte sized pointer to the string at 0x0800:
0x1008    .... .... .... .... .... .... .... ....
0x1010    0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68     # The `asUnsigned64bitInteger` value is a 64-bit value that is the same as 8 bytes copied from 0x0800, but without the terminator
0x1018    ....  ... .... .... .... .... .... ....
0x1020    ....  ... .... .... .... .... .... ....

推荐阅读