使用指针缩小C++中的类型转换
Narrowing type conversion in C++ using pointers
我在使用指针C++向下转换时遇到了一些问题,在我想出这样做的想法之前,谷歌基本上告诉我这是不可能的,而且我从中学到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";
第五行的增量可能不正确,但输出让我担心我正在使用 gcc 3.4.2 的 C 编译器会自动将 TheInt1 转换为长整型或其他东西。输出如下所示...
双倍是723330,即723330*4067360
TheInt1 的输出高得不可思议,而 TheInt2 的输出不存在。
我有三个问题...
我甚至走在正确的轨道上吗?
第五行的正确增量是多少?
为什么 TheInt1/TheInt2 允许这么大的值?
int
可能是 32 位,这给了它 -2*10^9 到 2*10^9 的范围。
在long int * pTheLong2 = &TheLong + 0x4;
行中,您正在对long int*
进行指针算术,这意味着地址将增加 0x4
long int
s 的大小。我猜你假设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
我甚至走在正确的轨道上吗?
应该不会。 你似乎很困惑。
第五行的正确增量是多少?
没有。 指针算术只能在数组内部使用,这里没有数组。 所以
long int * pTheLong2 = &TheLong + 0x4;
是未定义的行为,并且要替换0x4的 0(可能为 1)以外的任何值也将是 UB。
为什么 TheInt1/TheInt2 允许这么大的值?
int
和long int
通常具有相同的可能值范围。
TheInt2 = *pTheLong2;
这将调用未定义的行为,因为C++标准不保证pTheLong2
指向哪个内存位置,因为它被初始化为:
long int * pTheLong2 = &TheLong + 0x4;
&TheLong
是变量TheLong
的内存位置,pTheLong2
被初始化为内存位置,该内存位置要么不是程序的一部分,因此是非法的,要么指向程序本身内的内存位置,尽管您不知道确切的位置,C++标准都没有提供任何保证它指向的位置。
因此,取消引用此类指针会调用未定义的行为。
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++中的双指针类型转换
- 逐位操作的隐式类型转换
- 模板中的类型转换
- 在 C++(和 C)中进行类型转换时明显不一致
- 字符类型转换不兼容
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- C++:用户定义的显式类型转换函数错误
- 将类指针类型转换为键时出错
- 通过引用传递参数时C++类型转换
- 在 C++ 中将一个模板类型的对象类型转换为另一个模板类型
- C++显式类型转换(C 样式强制转换)的强制表示法和static_cast的多种解释
- C++无效的函数类型转换
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 如何将Windows产品类型转换为名称?
- 通过构造函数方法输出的类到类类型转换是 5500 为什么不是 5555
- 事件系统:使用类型转换或联合进行继承
- 如何在参数中定义隐式类型转换的构造函数?
- 类模板实例化中的类型转换