为什么我必须将地址转换为整数以使其可分配?

时间:2016-10-05 12:41:19

标签: c++ pointers

指针在堆上或堆栈上存储地址。经过一番搜索,我试图了解什么是“地址”;我发现它只是一个映射内存区域的整数值。

  • 我想知道:只要一个地址只是一个整数,为什么我不能把它分配给一个整数变量:

    #include <iostream>
    using std::cout;
    using std::endl;
    
    int main()
    {
        int  a    = 1024;
        int* ptrA = &a;
    
        cout << "ptrA: " << ptrA << endl;   //  0018FF44
        cout << "*ptrA: " << *ptrA << endl; //  1024
        cout << "&a: " << &a << endl;       //  0018FF44
        cout << "a: " << a << endl;         //  1024
    
    //  int b = ptrA;      // why this is incorrect
        int b = (int)ptrA; // why I need this?
    
        cout << "b: " << std::hex << b << endl; //  18FF44
    
        // so b is identic to ptrA!
    
        std::cout << std::endl;
        return 0;
    }
    

6 个答案:

答案 0 :(得分:7)

主要有两个原因。

  1. int可能不足以存储指针值。这是一个特定于实现的细节。在具有64位内存地址的64位平台上找到C ++实现仍然很常见,其中int只有32位。

  2. 类型安全。编译器存在不同类型的原因之一是捕获明显的错误,例如在指向不同类的指针时使用指向一个类的指针。如果对每个对象的所有指针都只是简单的整体,那么这些错误就会被删除。

答案 1 :(得分:4)

  

我发现它只是一个整数值,就像内存的映射方式一样。

通常是,但这一定是真的。

C ++标准允许许多有问题的事情,例如。变量中不用于存储值的位,无效的特定值,可能导致崩溃等,等等。指针和整数可能在这些方面有所不同。

它的一部分是常用平台上的实际问题:int和指针可以有不同的大小(例如4和8字节)。

  

我想知道:只要一个地址只是一个整数,为什么我不能分配   它是一个整数变量

...这就是为什么你不能这样做的原因:不能保证在内存中分配值是可能和/或有意义的。

在类似x86的平台上,只要你使用正确的int大小,就没有真正的问题,但是C ++不仅仅是x86 ......

答案 2 :(得分:1)

您可以,但仅适用于足以容纳指针值的整数类型。在64位系统上,指针长64位,而int通常只有32位。虽然您可以使用long intlong long int(取决于哪种处理器和哪种操作系统),但intptr_t中还有inttypes.h类型,保证能够保持指针的值。

但请注意,您几乎不必将指针的值放入整数变量。

答案 3 :(得分:0)

来自C语言标准ISO /IEC9899§6.3.2.3/ p6指针:

  

任何指针类型都可以转换为整数类型。除了   之前指定的,结果是实现定义的。如果   结果不能用整数类型表示,行为是   未定义。结果不必在任何值的范围内   整数类型。

正如标准所述,将指针转换为整数时存在某些问题。

  1. 结果是实现定义的。
  2. 结果可能无法通过整数类型表示,从而导致未定义的行为。
  3. 结果不必在任何整数类型的值范围内。
  4. 考虑到上述原因,C ++作为一种强类型语言禁止这种类型的隐式转换,以避免意外行为。但是,允许在精神上进行这种明确的转换,作为程序员,你知道自己在做什么。

答案 4 :(得分:0)

类型由数据表示定义,它通过可应用于它的操作使用。 “地址只是一个整数”是关于数据表示,而不是关于操作。地址不是整数。

答案 5 :(得分:-1)

c ++是一种强类型语言。当然,在大多数情况下,指针的地址只是整数的十六进制表示,表示存储器中的一个点。数据类型将告诉编译器需要在堆栈上保存多少空间来存储变量。指针通常是32位机器上的4个字节。

至于转换,它只是语言的制作方式。指针最初只能指向同型变量的位置。唯一的例外是无效。

对于使用强制转换的转换,上面提到的是必需的,c ++是一种强类型语言,必须知道它正在处理什么类型。