从基类型到其他指针的转换

conversion from a base type to other pointers

本文关键字:指针 转换 其他 基类 类型      更新时间:2023-10-16

我想让一个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可以存储的所有值。在实践中,这取决于浮点表示(使用多少位来表示尾数)。通常情况下,floatdouble可以表示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.5E150.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++标准。

intdouble的存储方式不同。首先,它们很可能在内存中大小不同。但更重要的是,它们的比特的使用方式非常不同。

所以很简单:将int型内存重新解释为double型是没有意义的,不应该期望显示相同的值。

如果你要做这样的事情:

int a = 23;
double b = 23;
bool isSameBits = (memcmp(&a, &b, sizeof(a)) == 0);

该bool值应该表明它们确实不以相同的方式使用它们的位。

如果大小不同,bool isSameSize = (sizeof(a) == sizeof(b));会显示。

如果你想知道更多的底层细节,那么你也许可以谷歌类似"内存布局的双"。

那么有可能使一个类型的指针指向另一个类型的不同指针,当你对它们解引用以保持它们两个相同的值时?我只是想知道,因为正如你看到的,我是一个新手。