从基类型到其他指针的转换
conversion from a base type to other pointers
我想让一个double类型的指针指向另一个int类型的指针:
int x=23;
int *f_var =&x;
double*l_ptr = (double *)f_var;
这两个指针都有相同的地址,但是当我显示它们的值时,f_var显示好的值,而l_ptr显示一个奇怪的值。为什么会发生这种情况,如果你能解释我,我会很高兴。为什么它们的值不一样?如果它们都指向相同的位置,并且double类型可以存储int类型,为什么它们有不同的值?
你的问题本身是有缺陷的,但我将尝试回答它的几个方面。
首先,int
不是double
的基类型。指向int
的指针也不是指向double
的指针的基类型。所以这个问题的标题是错误的。
第二,不能保证浮点类型可以存储int
可以存储的所有值。在实践中,这取决于浮点表示(使用多少位来表示尾数)。通常情况下,float
或double
可以表示int
可以表示的某些值,但不能表示其他值(它存储的值是近似值)。这是浮点变量能够在比int
更大的范围内表示非整型值的折衷的一部分。
第三,你的描述"显示它们的值"是模棱两可的。如果你在做
std::cout << f_var << ' ' << l_ptr << 'n';
或(更显式地,不依赖于隐式转换到void指针)
std::cout << (void *)f_var << ' ' << (void *)l_ptr << 'n';
指针的值(即它们保存的地址)将被打印出来。实际上,输出的值通常是相同的——不同的是它们的类型,而不是它们的值。但是这些指针的值是变量x
在内存中的地址,而不是变量x
的值。
或者,如果您正在执行
std::cout << *f_var << ' ' << *l_ptr << 'n';
的结果是未定义的行为,因为l_ptr
被解引用,好像它指向double
,尽管它指向int
。这样做的结果可以是任何东西(打印垃圾,打印您不期望的值,重新格式化您的硬盘驱动器,任何东西)。在实践中,它可能试图解释组成int
的位(即变量x
),就好像它们代表浮点值一样。由于int
中的位与double
中的位具有不同的含义(在浮点表示中有尾数和指数,这就是为什么double
可以表示0.5E15
或0.5E-3
之类的值),同一组位表示不同的值。还有一个问题是,double
通常比int
包含更多的位—因此,通过这种方式打印,您的代码将x
右侧的随机内存解释为数据。
实际上,当你这样做的时候:
int x=23;
int *f_var = &x;
double *l_ptr = (double *)f_var;
l_ptr
不是一个"double类型的指针指向int类型的指针"(如你所说),而是一个指向double的指针,它存储了int
的地址。解引用是未定义的行为。[编辑:实际上,从[编辑:哎呀,不,你可以"安全地"从任何指针到任何足够大的指针/整型来保存其值]int*
到double*
的强制转换已经是未定义的行为,因此l_ptr
可能存储x
以外的地址]
对指向double的指针解引用实际上存储指向int的指针的地址并不更好,尽管,假设您实现了将该地址分配给指向double的指针而不会导致未定义的行为(以及double类型的指针,实际上可能不是指针,但我假设您的意思是"指向double的指针")。
当你输出*l_ptr* is probably the bitwise representation of
x and probably some garbage data (because a
double (may be longer in memory than an
int ')时,你看到的是什么?然而,它也可以是42或"你正在做奇怪的事情"(或崩溃,或什么都没有):这是未定义的行为,编译器可以生成任何他想要的东西,仍然符合c++标准。
int
和double
的存储方式不同。首先,它们很可能在内存中大小不同。但更重要的是,它们的比特的使用方式非常不同。
所以很简单:将int型内存重新解释为double型是没有意义的,不应该期望显示相同的值。
如果你要做这样的事情:
int a = 23;
double b = 23;
bool isSameBits = (memcmp(&a, &b, sizeof(a)) == 0);
该bool值应该表明它们确实不以相同的方式使用它们的位。
如果大小不同,bool isSameSize = (sizeof(a) == sizeof(b));
会显示。
如果你想知道更多的底层细节,那么你也许可以谷歌类似"内存布局的双"。
那么有可能使一个类型的指针指向另一个类型的不同指针,当你对它们解引用以保持它们两个相同的值时?我只是想知道,因为正如你看到的,我是一个新手。
- 正在将指针转换为范围
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- C++:Lambda 函数指针转换的用例是什么?
- 如何将 int 指针转换为浮点指针
- 为什么在将 void 指针转换为整数指针时出现分段错误
- 将(N 个字节)无符号字符指针转换为浮点数和双 C++
- 我们可以在不知道其真实类型的情况下将基类指针转换为派生类指针吗?
- C++中数组大小未知的指针转换
- Antlr cpp 运行时 任何错误的指针转换?
- std::flush可以用于将对象指针转换为其封闭数组指针吗
- C 指针转换会导致内存访问冲突
- 模板类实例化中的指针转换无效
- 函数调用歧义(用户定义的转换和 Derived2Base 指针转换)
- 如何将 void(*)() 类型的指针转换为 void*
- 数组到指针转换期间的临时具体化
- 直接为浮点变量分配十六进制整数与通过指针转换分配之间的区别
- 将基类指针转换为派生的类指针
- 应对 std::字符串中的 std::<char>指针转换后的向量
- 在编译时将函数指针转换为 std::uintptr_t
- 将基类指针转换为未知派生类指针