将双指针转换为int指针

时间:2015-06-01 23:00:11

标签: c++ pointers type-punning

当我打印bd时,它们都拥有相同的地址(a的地址)。 那么为什么*b打印0*d打印5?

 void main() 
 {
    double a = 5.0;
    double *d = &a;
    int *b = (int*)d;
    int a1 = 10;
    cout << "Val of D : " << d << " Address of d :" << &d
         << " Value of *d :" << *d << endl;
    cout << "Val of B : " << b << " Address of B :" << &b
         << " Value of *b :" << *b << endl;
}

3 个答案:

答案 0 :(得分:7)

让我们对代码进行一些小改动:

#include <iostream>

int main() {
    double a = 5.0;
    double *d = &a;
    char *b = (char *)&a;
    int a1 = 10;

    for (int i = 0; i < sizeof(double); i++)
        std::cout << std::hex << (int)b[i] << "\t";
}

这向我们展示了double的各个字节,因为它们存储在内存中。我得到的结果是:

0       0       0       0       0       0       14      40

现在,如果你看看它的前四个字节,它们都是零。假设您的int是两个或四个字节,当您尝试将该内存视为int时,结果将为零,因为double的所有非零字节都将在以后存储记忆而不是你在int使用它时所看到的部分。

当然,如果您将其打印为long long int,则会得到非零结果(要求long long int至少为64位)。同样,如果您在大端系统上执行此操作,14的{​​{1}}和40字节可能会存储在内存中的第一个字节而不是最后一个字节,所以结果将再次为非零。

底线是,在这种情况下,您的演员表大致相当于double。它不是取reinterpret_cast 并将其转换为double值,而是查看int占用的内存字节数,并将其解释为他们是double

请注意,上面的结果并不是真正需要的,您不能指望它在便携式代码中发生。它 非常普遍并且被广泛期待(例如,在大多数具有IEEE浮点和32位int s的小端机器上。

答案 1 :(得分:6)

因为double以与int完全不同的格式表示(即使您假设它们具有相同的大小)。 double使用floating point format,而int不使用trap representation。使用double指针寻址int是未定义的行为。

相关:the example from the documentation of TransactionScope

修改 如果您是初学者,int i = 3.14;之类的内容可能会很奇怪,即double转换为int,但是不能使用指向double的指针表示/转换为int。这是因为在第一种情况下,编译器负责转换,并自动将3.14截断为3,然后将后者表示为int,即3 }。 double 3的{​​{1}}表示在记忆中看起来完全不同。

答案 2 :(得分:0)

此代码由于违反严格别名规则而导致未定义的行为。

由于对齐违规,它也可能导致UB,但我会在这篇文章中假设它没有。

对象d的类型为double。但是您尝试通过类型为*b的glvalue int来访问其内存。这不是[basic.lval] / 10中列出的允许别名类型之一:

  

如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:

     
      
  • 对象的动态类型,
  •   
  • 对象的动态类型的cv限定版本,
  •   
  • 与对象的动态类型相似的类型(如4.4中所定义)
  •   
  • 与对象的动态类型对应的有符号或无符号类型的类型
  •   
  • 对应于动态类型的cv限定版本的有符号或无符号类型   对象,
  •   
  • 聚合或联合类型,包括其元素中的上述类型之一或非   静态数据成员(包括递归地,子集合的元素或非静态数据成员)   或包含联盟),
  •   
  • 一种类型,它是对象动态类型的(可能是cv限定的)基类类型,
  •   
  • char或unsigned char类型。
  •