C++如何使用指针与引用?它们有什么区别?

2021年3月27日14:53:38 发表评论 1,064 次浏览

先决条件:指针, 引用文献

C和C ++支持与大多数其他编程语言不同的指针。其他语言包括C ++, Java, Python, Ruby, Perl和PHP支持引用。

从表面上看, 引用和指针非常相似, 都用于使一个变量提供对另一变量的访问。两者都提供了许多相同的功能, 因此通常不清楚这些不同机制之间的区别。在本文中, 我将尝试说明指针和引用之间的区别。

指针:指针是一个变量, 用于保存另一个变量的内存地址。指针需要用*操作符访问它指向的内存位置。

引用:引用变量是别名, 即已经存在的变量的另一个名称。引用(如指针)也通过存储对象的地址来实现。

引用可以被认为是一个具有自动间接指向功能的常量指针(不要与指向常量值的指针混淆),也就是说,编译器将为你应用*操作符。

int i = 3; 

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

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

指针和引用的区别:

1. 指针和引用的初始化:

初始化:可以通过以下方式初始化指针:

int a = 10;        
  int *p = &a;    
         OR 
     int *p;
   p = &a;
we can declare and initialize pointer at same step or in multiple line.

引用的初始化如下

int a=10;
int &p=a;  //it is correct
   but
int &p;
 p=a;    // it is incorrect as we should declare and initialize references at single step.

注意:编译器之间的差异可能有所不同。以上区别指针和引用是针对turbo IDE的。

2. 指针和引用的重新赋值:

重新赋值:可以重新给指针赋值。该属性对于实现诸如链表, 树等数据结构非常有用。请参见以下示例:

int a = 5;
int b = 6;
int *p;
p =  &a;
p = &b;

另一方面, 引用不能重新赋值, 必须在初始化时赋值。

int a = 5;
int b = 6;
int &p = a;
int &p = b;  //At this line it will show error as "multiple declaration is not allowed".

However it is valid statement, int &q=p;

3. 指针和引用的内存地址:

内存地址:指针在栈上有自己的内存地址和大小,而引用(与原始变量)共享相同的内存地址,但也占用栈上的一些空间。

注意:但是, 如果我们需要引用的真实地址, 则可以通过编写以下语句在turbo IDE中找到它:

int &p = a;
   cout << &(&p);

4. 指针和引用的NULL值:

NULL值:

指针可以直接分配为NULL, 而引用则不能。与引用关联的约束(无NULL, 无重新分配)确保基础操作不会遇到异常情况。

5. 指针和引用的间接操作:

你可以使用指向提供额外级别间接功能的指针。而引用仅提供一种间接级别。即,

In Pointers, int a = 10;
int *p;
int **q;  //it is valid.
p = &a;
q = &p;

Whereas in references, int &p = a;
int &&q = p; //it is reference to reference, so it is an error.

6. 指针和引用算术运算:可以对指针执行各种算术运算, 而没有称为引用算术的东西(但是你可以获取引用指向的对象的地址, 并像&obj + 5那样对它进行指针算术)。

什么时候使用

性能完全相同, 因为引用在内部作为指针实现。但是你仍然可以记住一些要点, 以决定何时使用什么:

  • 使用引用
    • 在函数参数和返回类型中。
  • 使用指针:
    • 如果需要使用指针算术或传递NULL指针, 请使用指针。例如对于数组(请注意, 数组访问是使用指针算法实现的)。
    • 由于要指向链表, 树等数据结构及其算法, 因为要指向不同的单元格, 我们必须使用指针的概念。
    • 例如,
      指针中



      int arr[] = {10, 20, 30};
      int *p, i ;
      p = arr;
      for(i = 0; i<3 ; i++)
      {
      cout << *p << endl;
      p++;
      }
      

      输出如下:

      10
      20
      30
      

      注意:此处的指针将在基地址之前

      现在在引用中使用相同的代码

      int arr[] = {10, 20, 30};
      int &p = arr[0];
      int i;
      for(i = 0; i<3 ; i++)
      {
      cout << p << endl;
      p++;  //here it will increment arr[0]++
      }
      

      输出如下:

      10
      11
      12
              

      注意:此处的指针将仅位于基址。

在C ++ FAQ Lite中引用:尽可能使用引用, 而必须使用指针。每当你不需要"重新赋值"时, 引用通常比指针更可取。这通常意味着引用在课程的public接口。引用通常显示在对象的外观上, 而指针则显示在对象的外观上。

上面的例外情况是, 函数的参数或返回值需要"前哨"引用, 即不引用对象的引用。通常最好通过返回/获取指针并给null指针具有特殊意义(引用必须始终是对象的别名, 而不是取消引用的空指针)。

相关文章:

我们什么时候传递参数作为引用或指针?

如果发现任何不正确的地方, 或者想分享有关上述主题的更多信息, 请写评论。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: