从基类型转换为其他指针

时间:2015-07-31 21:47:21

标签: c++ pointers

我想创建一个double类型的指针,指向int类型的指针,指向另一个var:

 int x=23;
 int *f_var =&x;      
 double*l_ptr = (double *)f_var;

这两个指针都有相同的地址,但是当我显示它们的值时,f_var显示好的但是l_ptr显示一个奇怪的值。为什么会这样,如果你能解释我,我会很高兴。为什么他们没有相同的价值?如果它们都指向同一个位置而double可以存储一个int,为什么它们有不同的值?

4 个答案:

答案 0 :(得分:1)

实际上,当你这样做时:

int x=23;
int *f_var = &x;      
double *l_ptr = (double *)f_var;

l_ptr不是"类型为double的指针[指向] int&#34类型的指针; (如你所说)但是指向double的指针存储了int的地址。取消引用它是未定义的行为 [编辑:实际上,从int*double*的广告投放已经是未定义的行为,因此l_ptr可能存储的内容不是x的地址 [编辑:哎呀,不,你可以"安全" reinterpret_cast从任何指向任何指针/整数的指针大到足以保持其值]

取消引用指向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`)时,您看到的内容被解释为double。然而,它也可能是42或者你做了奇怪的事情" (或崩溃,或根本没有):它是未定义的行为,编译器可能生成他想要的任何东西并仍然符合C ++标准。

答案 1 :(得分:1)

intdouble的存储方式不同。首先,他们很可能在记忆中有不同的大小。但更重要的是,它们的位以非常不同的方式使用。

非常简单:将int的内存重新表示为double是无意义的,不应该期望显示相同的值。

如果您要做类似的事情:

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

那个bool应该表明他们确实不会以同样的方式使用他们的位。

bool isSameSize = (sizeof(a) == sizeof(b));表示它们的大小是否不同。

如果您想了解有关基础细节的更多信息,那么您可以谷歌搜索类似“双倍内存布局”的内容。

答案 2 :(得分:1)

你的问题本身存在缺陷,但我会尝试回应它的几个方面。

首先,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.5E15之类的值{1}}或0.5E-3)同一组位表示不同的值。还有一种皱纹通常是doubleint更多的位 - 所以,通过这种方式打印,你的代码将{{1}右侧的随机内存解释为作为数据。

答案 3 :(得分:0)

然后可以使一个类型的指针指向另一个类型的不同指针,当你取消引用它们以保持它们两个相同的值时?我只想知道,因为你看到我是一个菜鸟。