C++ 为什么这两个整数变量和两个双变量(看起来)在内存中共享相同的地址?

C++ 为什么这两个整数变量和两个双变量(看起来)在内存中共享相同的地址?,c++,pointers,memory,C++,Pointers,Memory,我编写了一个简单的程序,它有一种打印变量地址和存储在该地址中的内容的方法,只是为了帮助我更好地理解指针: #include <iostream> using std::cout; using std::endl; template<typename Type> void PrintAddressAndContentsOf(Type Variable); /* Entry point */ int main() { int IntegerVariable1

我编写了一个简单的程序,它有一种打印变量地址和存储在该地址中的内容的方法,只是为了帮助我更好地理解指针:

#include <iostream>
using std::cout;
using std::endl;


template<typename Type>
void PrintAddressAndContentsOf(Type Variable);


/* Entry point */
int main()
{
    int IntegerVariable1 = 5;
    int IntegerVariable2 = 6;

    double FloatingVariable1 = 10;
    double FloatingVariable2 = 11;

    PrintAddressAndContentsOf(IntegerVariable1);
    PrintAddressAndContentsOf(IntegerVariable2);
    PrintAddressAndContentsOf(FloatingVariable1);
    PrintAddressAndContentsOf(FloatingVariable2);
}


/* Prints the address and the corresponding contents of a given variable */
template<typename Type>
void PrintAddressAndContentsOf(Type Variable)
{
    Type* Pointer = &Variable;

    cout << "Address: " << Pointer << endl;
    cout << "Contents: " << *Pointer << endl;
}
如您所见,前两个整数似乎具有相同的地址008FFB88;同样,这两个浮动指针变量具有相同的地址008FFB84


我的程序中是否存在缺陷,或者我是否缺少一些了解这里发生了什么的关键知识?

这里的问题是您打印的是
变量的地址,而不是main中变量的地址。
变量的地址
独立于初始化变量的地址,通过多次调用函数可以是同一地址

如果我们改为引用,它为我们提供了实际变量的别名,而不是副本,如:

template<typename Type>
void PrintAddressAndContentsOf(Type& Variable)
{
    Type* Pointer = &Variable;

    cout << "Address: " << Pointer << endl;
    cout << "Contents: " << *Pointer << endl;
}

这里的问题是您打印的是
变量的地址
,而不是main中变量的地址。
变量的地址
独立于初始化变量的地址,通过多次调用函数可以是同一地址

如果我们改为引用,它为我们提供了实际变量的别名,而不是副本,如:

template<typename Type>
void PrintAddressAndContentsOf(Type& Variable)
{
    Type* Pointer = &Variable;

    cout << "Address: " << Pointer << endl;
    cout << "Contents: " << *Pointer << endl;
}
如您所见,前两个整数似乎具有相同的地址008FFB88;同样,这两个浮动指针变量具有相同的地址008FFB84

这些是函数多次调用时函数中变量的地址。它们不是调用函数中变量的地址。如果要检查调用函数中变量的地址,可以使用以下两种方法:

  • 将函数更改为接受指针,并将变量的地址传递给函数

  • 将函数更改为接受引用,并按必须的方式将变量传递给函数


  • 选项1

    // Function declaration
    template<typename Type>
    void PrintAddressAndContentsOf(Type* variableAddress);
    
    // Usage
    PrintAddressAndContentsOf(&IntegerVariable1);
    
    //函数声明
    模板
    作废打印地址和内容(类型*variableAddress);
    //用法
    打印地址和内容(&IntegerVariable1);
    
    选项2

    // Function declaration
    template<typename Type>
    void PrintAddressAndContentsOf(Type& variableReference);
    
    // Usage
    PrintAddressAndContentsOf(IntegerVariable1);
    
    //函数声明
    模板
    作废打印地址和内容(类型和可变参考);
    //用法
    打印地址和内容(整数变量1);
    
    如您所见,前两个整数似乎具有相同的地址008FFB88;同样,这两个浮动指针变量具有相同的地址008FFB84

    这些是函数多次调用时函数中变量的地址。它们不是调用函数中变量的地址。如果要检查调用函数中变量的地址,可以使用以下两种方法:

  • 将函数更改为接受指针,并将变量的地址传递给函数

  • 将函数更改为接受引用,并按必须的方式将变量传递给函数


  • 选项1

    // Function declaration
    template<typename Type>
    void PrintAddressAndContentsOf(Type* variableAddress);
    
    // Usage
    PrintAddressAndContentsOf(&IntegerVariable1);
    
    //函数声明
    模板
    作废打印地址和内容(类型*variableAddress);
    //用法
    打印地址和内容(&IntegerVariable1);
    
    选项2

    // Function declaration
    template<typename Type>
    void PrintAddressAndContentsOf(Type& variableReference);
    
    // Usage
    PrintAddressAndContentsOf(IntegerVariable1);
    
    //函数声明
    模板
    作废打印地址和内容(类型和可变参考);
    //用法
    打印地址和内容(整数变量1);
    
    您正在打印推送到堆栈上的变量副本的地址。模板按值传递“变量”

    您应该期望(尽管决不依赖)从给定函数中对函数的后续调用将参数推送到相同的地址。对不同函数的调用将从同一点开始

    此外,4字节的差异是因为在您的平台上int是4字节,double是8字节。与直觉相反的是,堆栈在地址空间中“颠倒”,这一点对您来说很常见,而且也是正确的在堆栈上按下“变量”实际上会向下移动堆栈的顶部

    尝试以下方法。所有的地址都应该不同

    #include <iostream>
    using std::cout;
    using std::endl;
    
    
    template<typename Type>
    void PrintAddressAndContentsOf(Type* Pointer);
    
    
    /* Entry point */
    int main()
    {
        int IntegerVariable1 = 5;
        int IntegerVariable2 = 6;
    
        double FloatingVariable1 = 10;
        double FloatingVariable2 = 11;
    
        PrintAddressAndContentsOf(&IntegerVariable1);
        PrintAddressAndContentsOf(&IntegerVariable2);
        PrintAddressAndContentsOf(&FloatingVariable1);
        PrintAddressAndContentsOf(&FloatingVariable2);
    }
    
    
    /* Prints the address and the corresponding contents of a given variable */
    template<typename Type>
    void PrintAddressAndContentsOf(Type* Pointer)
    {
        cout << "Address: " << Pointer << endl;
        cout << "Contents: " << *Pointer << endl;
    }
    
    #包括
    使用std::cout;
    使用std::endl;
    模板
    无效打印地址和内容(类型*指针);
    /*入口点*/
    int main()
    {
    整数变量1=5;
    整数变量2=6;
    双浮动变量1=10;
    双浮动变量2=11;
    打印地址和内容(&IntegerVariable1);
    打印地址和内容(&IntegerVariable2);
    打印地址和内容(&FloatingVariable1);
    打印地址和内容(&FloatingVariable2);
    }
    /*打印给定变量的地址和相应内容*/
    模板
    无效打印地址和内容(类型*指针)
    {
    
    cout您正在打印推送到堆栈上的变量副本的地址。您的模板按值传递“Variable”

    您应该期望(尽管决不依赖)从给定函数中对函数的后续调用将参数推送到相同的地址。对不同函数的调用将从同一点开始

    此外,4个字节的差异是因为在您的平台上int是4个字节,double是8个字节。与直觉相反,堆栈在地址空间中是“倒置”的,这一点对您来说是常见的,也是正确的。在堆栈上按下“变量”实际上会将堆栈顶部向下移动

    请尝试以下操作。所有地址都应不同

    #include <iostream>
    using std::cout;
    using std::endl;
    
    
    template<typename Type>
    void PrintAddressAndContentsOf(Type* Pointer);
    
    
    /* Entry point */
    int main()
    {
        int IntegerVariable1 = 5;
        int IntegerVariable2 = 6;
    
        double FloatingVariable1 = 10;
        double FloatingVariable2 = 11;
    
        PrintAddressAndContentsOf(&IntegerVariable1);
        PrintAddressAndContentsOf(&IntegerVariable2);
        PrintAddressAndContentsOf(&FloatingVariable1);
        PrintAddressAndContentsOf(&FloatingVariable2);
    }
    
    
    /* Prints the address and the corresponding contents of a given variable */
    template<typename Type>
    void PrintAddressAndContentsOf(Type* Pointer)
    {
        cout << "Address: " << Pointer << endl;
        cout << "Contents: " << *Pointer << endl;
    }
    
    #包括
    使用std::cout;
    使用std::endl;
    模板
    无效打印地址和内容(类型*指针);
    /*入口点*/
    int main()
    {
    整数变量1=5;
    整数变量2=6;
    双浮动变量1=10;
    双浮动变量2=11;
    打印地址和内容(&IntegerVariable1);
    打印地址和内容(&IntegerVariable2);
    打印地址和内容(&FloatingVariable1);