我一直在使用指针在 C++ 中进行向下类型转换时遇到一些问题,在我想出这样做的想法之前,Google 基本上告诉我这是不可能的,而且我学习 C++ 的任何书籍都没有涵盖它从。我认为这会起作用...
long int TheLong=723330;
int TheInt1=0;
int TheInt2=0;
long int * pTheLong1 = &TheLong;
long int * pTheLong2 = &TheLong + 0x4;
TheInt1 = *pTheLong1;
TheInt2 = *pTheLong2;
cout << "The double is " << TheLong << " which is "
<< TheInt1 << " * " << TheInt2 << "\n";
第 5 行的增量可能不正确,但输出让我担心我使用 gcc 3.4.2 的 C 编译器会自动将 TheInt1 转换为 long int 或其他东西。输出看起来像这样......
The double is 723330 which is 723330 * 4067360
TheInt1 的输出高得离谱,而 TheInt2 的输出不存在。
我有三个问题...
我走在正确的轨道上吗?
第五行的正确增量是多少?
为什么 TheInt1/TheInt2 允许这么大的值?
最佳答案
int
可能是 32 位,范围是 -2*10^9 到 2*10^9。
在 long int * pTheLong2 = &TheLong + 0x4;
行中,您正在对 long int*
进行指针运算,这意味着地址将增加0x4
long int
。我猜您假设 long int
的大小是 int
的两倍。这绝对不能保证,但如果您在 64 位模式下编译,则可能是真的。因此,您想将 long int
的一半大小(在您的假设下恰好是 int
的大小)添加到您的指针。 int * pTheLong2 = (int*)(&TheLong) + 1;
实现了这一点。
您走在正确的轨道上,但请记住,正如其他人所指出的,您现在正在探索未定义的行为。这意味着可移植性被破坏,优化标志很可能会改变行为。
顺便说一句,更正确的输出(假设机器是小端)是:
cout << "The long is " << TheLong << " which is "
<< TheInt1 << " + " << TheInt2 << " * 2^32" << endl;
为了完整起见,一个 32 位整数到两个 16 位整数的定义明确的转换:
#include <cstdint>
#include <iostream>
int main() {
uint32_t fullInt = 723330;
uint16_t lowBits = (fullInt >> 0) & 0x0000FFFF;
uint16_t highBits = (fullInt >> 16) & 0x0000FFFF;
std::cout << fullInt << " = "
<< lowBits << " + " << highBits << " * 2^16"
<< std::endl;
return 0;
}
输出:723330 = 2434 + 11 * 2^16
关于c++ - 使用指针在 C++ 中缩小类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6001447/