【问题标题】:How does C++ look at a pointer to an unsigned char when it's treated like an array?当将无符号字符视为数组时,C++ 如何看待指向无符号字符的指针?
【发布时间】:2014-07-21 22:13:45
【问题描述】:

我正在尝试破译一些代码,它似乎将顺序内存地址中的值与我预期的相反。 64 位有符号整数被转换为 8 位无符号字符 这是它的简化版本:

unsigned char* ucMyChar;
unsigned __int64 ui64MyInt;
CString strMyString;

//some code that assigns a value to ui64MyInt

ucMyChar = (unsigned char*)&ui64MyInt;

strMyString.Format("%02x%02x%02x%02x-%02x%02x-1%01x%02x",
                    ucMyChar[3], ucMyChar[2], ucMyChar[1], ucMyChar[0],
                    ucMyChar[5], ucMyChar[4], ucMyChar[7], ucMyChar[6]);

如果ui64MyInt 的值为:

0x010203040a0b0c0d

以下哪个是正确格式的字符串?

04030201-0b0a-1d0c

0a0b0c0d-0304-1102

我问的原因是因为我有一个值,我试图在这段代码中向后运行数学,因为一些需要的信息包含在用于生成这个字符串的原始值中,并且没有由于文件损坏而恢复所述信息的其他方法。到目前为止,我使用第一个字符串得出的值似乎超出了预期范围,我不确定我是否犯了数学错误,或者我是否不理解 unsigned char 指针的工作方式.

【问题讨论】:

标签: c++ pointers char byte


【解决方案1】:

它是由实现定义的,整数位存储在内存中的顺序。 (这意味着编译器可以做出决定,而且几乎可以肯定它基于 CPU 做出的关于 CPU 如何在内存中存储整数的决定。

两种最常见的布局是(最低地址优先)

  • 01 02 03 04 0a 0b 0c 0d(典型例子:ARM)
  • 0d 0c 0b 0a 04 03 02 01(典型示例:x86/x64)

其他布局也是可能的。例如,如果 32 位 CPU 的编译器通过将两个 32 位 int 彼此相邻放置来支持__int64,它甚至可能会:

  • 04 03 02 01 0d 0c 0b 0a

C 和 C++ 语言经过精心设计,因此这些细节并不重要;您可以编写代码,使其无论使用哪种表示形式都能正常工作。

当有人编写如下代码时:

ucMyChar = (unsigned char*)&ui64MyInt;

他们有意识地绕过了 C++ 的工具来独立于整数表示。 (强制转换是一个好兆头,表明正在绕过类型系统!)

【讨论】:

  • 联合还允许访问较低级别的表示详细信息。
  • @andrewmu:联合不允许在 C++ 中使用类型双关语。另一方面,不同类型之间的memcpy 可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-27
  • 1970-01-01
相关资源
最近更新 更多