引用与指针

指针和引用一直是C++中难懂的部分,为此我也困惑了很久,下面说说我对引用和指针的简单理解。

在使用函数时我们常常会纠结实参传递到形参后,函数对形参的操作会不会改变实参的值(也就是主函数的相应变量),最典型的例子是swap(int a,int b)。我们都知道,函数在调用时会给变量重新开辟一个存储空间,而这个存储空间会暂时存储形参的值,如果函数在调用完毕后,其相应存储空间的值会被释放。例如下面一段代码:

void swap1(int a, int b)
{
    int temp = 0;
    temp = a;
    a = b;
    b = temp;
}
void swap2(int *a, int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}
int main()
{
    int i = 3, j = 8;
    swap1(i, j);
    swap2(&i, &j);
    return 0;
}

当主函数调用swap1(int a, int b)时,变量a,b会被放到一个存储空间中,而这个存储空间和原来的i,j存储空间没有关系。函数执行完毕后,a,b被临时存放的空间会被释放,也就是说原来a,b的值也不会存在,因此这个函数不会影响主函数中i,j的值,因为这个函数没有对i,j的相应地址进行相应操作。程序中只有对变量的地址进行操作时,其变量的值才会发生改变。(简单理解)。

在函数swap2(int *a, int *b)中,由于函数中的形参就是i,j的地址,因此对地址进行操作(函数中是对地址存放的变量值进行操作)就会改变实参的值。而引用的实质就是直接对变量的地址进行操作,因此引用也能改变实参的值。指针和引用在很多时候具有相同的功能,但两者也有一定的区别,这在其他的地方也能查到。下面讨论更为复杂点的情况。

 

typedef struct TreeNode
{
    char val;
    TreeNode *left;
    TreeNode *right;
}*Tree;

 

void creat(Tree &T)
{
    char val=' ';
    cin >> val;
    if (val == '#')
        T = NULL;
    else
    {
        T = new(TreeNode);
        T->val = val;
        creat(T->left);
        creat(T->right);
    }

}

上面是建立二叉树的代码。creat(Tree &T)形参为引用,而不是指针。不能用指针的原因是形参为指针的话,传递的进去的是指针所指向的变量的地址,也就是T所指向的地址,函数在建立完链表后,主函数中指针T本身的值不会被改变,因此我们不能得到函数中建立的二叉树,因为指针本身T的值没有改变,只是T所指对象的值发生了改变。这点和swap函数是一致的,而引用却可以改变主函数中T的值。如果想用指针进行操作的话,可以使用指向指针的指针,也就是要对指针T的地址而不是T所指对象的地址进行操作,这样才能在函数中改变实参的值。简单的说,函数中形参只有是对地址进行操作时才能改变实参的值。

另外,在C++中取地址和引用符号相同,简单的区别方法是引用符号前面一半是类型名,而取地址时,符号后面是变量。

原文地址:https://www.cnblogs.com/helloforworld/p/5652748.html