引用与指针


2022年10月6日, Learn eTutorial
1886

包括 Java、Python、Ruby、Perl 和 PHP 在内的大多数其他编程语言仅支持引用;然而,C 和 C++ 也支持指针。但奇怪的是,C++ 除了指针之外,还提供引用

表面上看,引用指针看起来非常相似,因为它们都用于允许一个变量访问另一个变量。由于它们都提供了许多相同的功能,因此很难区分这些方法的不同之处。在本教程中,让我们详细了解引用和指针之间的主要区别。

尽管 C++ 的引用指针看起来是等价的,但它们之间存在各种区别。指针是存储另一个变量地址的变量,而引用是为现有变量提供另一个名称的变量。

指针 引用
  • 存储另一个变量地址的变量称为指针。可以使用 (*) 运算符解引用它,以便访问指针指向的内存位置。
  • 主要使用指针来存储变量的地址。
  • 可以为指针分配空值。
  • 引用变量实际上是现有变量的别名,或者说是另一个名称。与指针类似,引用也是通过存储对象的地址来创建的。
  • 它总是引用一个现有的变量。
  • 不能为引用分配空值。

 

例如


int i = 5; 

// A pointer to the  variable i or it stores the address of i
int *ptr = &i; 

// A reference or alias for i.
int &ref = i; 
 

C++ 中引用和指针的主要区别

1.    定义

引用:现有变量也称为引用变量。它主要用于“引用传递”情况,其中引用变量作为参数传递给函数,接收的函数将操作原始变量副本。

指针:指针是存储另一个变量地址的变量。它主要通过存储变量的内存地址来简化编程。

2.    声明 

引用:通过在变量前使用符号 "&",我们可以声明一个引用变量。如果在使用此符号时,它将被视为地址运算符。

指针:在使用指针变量之前,必须先声明它,该变量是通过在变量名前添加 '*' 运算符来创建的。

3.    重新赋值

引用:我们无法重新赋值引用变量。现在让我们看一个简短的示例,如下所示:

如上所示的代码不允许多次声明 int &a。因为很明显,重新赋值操作对引用变量无效。


#include <iostream>  
using namespace std;  
void func(int &);  
int main()  
{  
   int i;    // variable declaration  
   int k;    // variable declaration  
   int &a=i;  
   int &a=k; // error  
   return 0;  
} 

指针:可以重新赋值指针。在处理链表、树等数据结构时,这种重新赋值非常有用。

4.    内存地址

引用:使用引用时,引用和实际变量的地址将相同。直到引用变量被销毁或离开作用域,新变量才与之关联。

例如


#include <iostream>  
using namespace std;  
void func(int &);  
int main()  
{  
  int i;  
  int &a=i;  
  std::cout << " address of 'a' variable is : " <<&a<< std::endl;  
  std::cout << " address of 'i' variable is : " <<&i<< std::endl;  
  return 0;  
}

输出

address of 'a' variable is : 0x7ffdfb1460dc
address of 'i' variable is : 0x7ffdfb1460dc

先前显示的输出表明引用变量的地址和实际变量的地址是相同的。

指针:使用指针时,实际变量和指针变量的内存位置将不同。让我们看一个例子来了解它是如何工作的。

例如:


#include <iostream>  
using namespace std;  
int main()  
{  
    int c;  
    int *b;  
    b=&c;  
    cout<<"memory address of  the p variable is :"<<&b;  
    cout<<"\nmemory address of the  k variable is :"<<&c;  
    return 0;  
} 

输出

memory address of  the p variable is :0x7fff1ac4ec28
memory address of the  k variable is :0x7fff1ac4ec24

5.    空值

引用变量不能被赋值为 NULL 值,而指针变量可以。

6.    间接寻址 

引用

在引用方面,不能引用引用。如果我们尝试这样做,C++ 软件将产生编译时错误。

例如,


#include <iostream>  
using namespace std;  
int main()  
{  
    int a=19; // initialization of  variable 
    int &p=a; // creating a reference variable for ?a? variable.  
    int &&q=p;  // the reference to reference is not valid, it  will throws an error.  
    return 0;  
}

输出

/8090589a-5a34-4425-bf6a-d553525c80bf.cpp:7:10: error: cannot bind 'int' lvalue to 'int&&'
  int &&q=p;  // the reference to reference is not valid, it  will throws an error.  

指针:指针可以具有指针到指针的关系,这提供了多个间接寻址级别。

例如,


#include <iostream>  
using namespace std;  
int main()  
{  
   int *p;  
   int a=19;  
   int **q;  
   p=&a;  
   q=&p;  
   std::cout << "value of q is : " <<*q<< std::endl;  
   return 0;  
}

输出

value of q is : 0x7fffd83b054c

在前面的代码中,指针 'p' 指向变量 'a',而 'q' 是一种指向 'p' 的双重指针。因此,'p' 的值是 'a' 变量的地址,而 'q' 变量的值是 'p' 变量的地址。

7.    算术运算

指针:可以对指针应用算术运算,这称为“指针算术”,但不能对引用应用算术运算。C++ 中不存在引用算术;它不存在。

引用:使用示例,让我们了解引用。


#include   
using namespace std;  
int main()  
{  
   
 int value=90;  // variable declaration  
 int &a=value;   // assigning value to the reference  
 &a=&a+5 // arithmetic operation is not all possible withthe reference variable, it throws an error.  
 return 0;  
}  
 

输出


ERROR

由于引用和算术运算不兼容,因此上面的代码将无法编译。

重要提示
由于引用在内部实现为指针,因此性能是相同的。但是,为了帮助您选择何时使用,请牢记这些要点:

引用用法

  • 主要用于返回类型和函数参数。

指针用法

  • 如果需要指针算术或发送 NULL 指针,我们将使用指针。例如,考虑数组(数组的访问主要使用指针算术来实现)。