我仍在学习C ++,希望我能在此问题上得到一些帮助。我试图遍历C ++中的char数组,但遇到了一些麻烦。
所以我目前的理解方式是,一个char数组只是X数量的8位值,它们在内存中彼此相邻存储(在这里我可能完全错了),以00结尾。
所以我想做的是遍历内存中的这个位集合,并将它们组合成较小或较大的段。例如,如果我有8个字符,并且想将该位字符串转换为两个32位整数或一个64位整数。
除了我试图让自己对C ++如何存储变量有更好的了解之外,这没有其他实际意义,因此,如果我正在做的事情是不可能的或者只是愚蠢地让我知道:D
答案 0 :(得分:1)
所以我目前的理解是
char
的数组只是X个8位值的数量,彼此相邻存储在内存中。
几乎是正确的,但是在C和C ++中,char
不能 保证是8位(八位位组)。请记住,C和C ++几乎可以针对现有的任何处理器和ISA,包括具有各自特色的稀有和奇特的机器。我建议您阅读以下质量检查:Will a `char` always-always-always have 8 bits?
...以00结尾。
抱歉,这是不完全正确的假设。
尽管“字符串”必须具有终止符(根据C语言规范),但是字符数组不一定必须具有NULL
终止符(末尾的'\0'
字符)。从字符串文字初始化的字符串将附加一个空终止符,但是您仍然可以构造一个字符串或char
数组而不使用一个。
所以我想做的是遍历内存中的这个位集合,并将它们组合成较小或较大的段。例如,如果我有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
且当前函数的堆栈帧始于{{1},则进程的只读存储器和堆栈(可能)如下所示},这是一个32位的大端单词机(因此0x1000
),所有值都与16位边界对齐:
(每行是8个字节的内存范围,每行以每行的第一个字节的地址为前缀。行地址后的每个十六进制数字表示单个sizeof(char*) == 4
(八位字节)值。每行char
代表一个具有未定义值的八位字节(实际上,其值可以是最后一个用户....
留下的任何值(用于预先归零的内存)或一些调试器生成的溢出检测测试模式。
0x00