C++ Reference vs Pointer 参考与指针

C++ 引用和指针看似相似,但它们之间存在一些差异。引用是一个变量,它是现有变量的另一个名称,而指针是存储另一个变量地址的变量。

什么是参考?

引用是一个变量,它被称为已经存在的变量的另一个名称。变量的引用是通过存储另一个变量的地址来创建的。

引用变量可以被认为是具有自动间接寻址的常量指针。此处,自动间接表示编译器自动应用间接运算符 (*)。

参考范例:

句法 (Syntax)

int &a = i;

在上面的声明中,“a”是“i”变量的别名。我们也可以通过“a”变量引用“i”变量。

让我们通过一个例子来理解。

例子 (Example)

#include <iostream>  
using namespace std;  
int main()  
{    
   int i=8;    //变量初始化  
   int &a=i; // 创建引用变量  
   cout<<"'i' 变量的值为:"<<a;  
   return 0;  
}

在上面的代码中,我们创建了一个引用变量,即'a'代表'i'变量。创建引用变量后,我们可以在“a”变量的帮助下访问“i”的值。

什么是指针?

指针是包含另一个变量地址的变量。它可以在 (*)运算符的帮助下取消引用以访问指针指向的内存位置。

引用和指针之间的差异

下面是引用和指针的区别:

  • 定义

引用变量是已经存在的变量的另一个名称。它主要用于“按引用传递”,其中引用变量作为参数传递给函数,并且传递此变量的函数在变量的原始副本上工作。

让我们通过一个简单的例子来理解。

例子 (Example)

#include <iostream>  
using namespace std;  
void func(int &);  
int main()  
{  
   int a=10;  
   std::cout <<"'a' 的值是:" <<a<< std::endl;  
  func(a);   
  std::cout << "'a' 的现在值是:" <<a<< std::endl;  
  return 0;  
}  
void func(int &m)  
{  
   m=8;  
}

输出:


'a' 的值为:10                                                                                                             现在 'a' 的值是:8

指针是一个变量,它存储另一个变量的地址。它使编程更容易,因为它保存了一些变量的内存地址。

  • 宣言

我们可以通过在变量前添加“&”符号来声明引用变量。如果在表达式中使用此符号,则它将被视为地址运算符。

在使用指针变量之前,我们应该先声明一个指针变量,这个变量是通过在变量前加一个'*'运算符来创建的。

  • 重新分配

我们不能重新分配参考变量。现在,我们举一个简单的例子,如下所示:

例子 (Example)

#include <iostream>  
using namespace std;  
void func(int &);  
int main()  
{  
  int i;    // 变量声明  
  int k;    // 变量声明  
  int &a=i;  
  int &a=k; // 错误  
  return 0;  
}

上面的代码显示了不允许多次声明int &a的错误。因此,上述程序得出重新赋值操作对引用变量无效的结论。


而指针可以重新分配。当我们处理链表、树等数据结构时,这种重新分配很有用。

  • 内存地址

在引用的情况下,引用和实际变量都引用相同的地址。在实际变量被删除或超出范围之前,新变量不会分配给引用变量。

让我们通过一个例子来理解这个场景。

例子 (Example)

#include <iostream>  
using namespace std;  
void func(int &);  
int main()  
{  
  int i;  
  int &a=i;  
  std::cout << "'a' 变量的地址是:" <<&a<< std::endl;  
  std::cout << "'i' 变量的地址是:" <<&i<< std::endl;  
  return 0;  
}

输出:

“a”变量的地址是:0x7fff078e7e44 “i”变量的地址是:0x7fff078e7e4

上面的输出显示引用变量和实际变量都具有相同的地址。

在指针的情况下,指针变量和实际变量都将具有不同的内存地址。让我们通过一个例子来理解这一点。

例子 (Example)

#include <iostream>  
using namespace std;  
int main()  
{  
    int k;  
    int *p;  
    p=&k;  
    cout<<"p变量的内存地址为:"<<&p;  
    cout<<"\n变量k的内存地址为:"<<&k;  
    return 0;  
}

输出:

p变量的内存地址为:0x7ffcc5c164b8 k变量的内存地址为:0x7ffcc5c164b4
  • 空值

我们不能给引用变量赋NULL值,但是指针变量可以赋NULL值。

  • 间接

指针可以有指向指针的指针,提供不止一个间接级别。

例子 (Example)

#include <iostream>  
using namespace std;  
int main()  
{  
 int *p;  
 int a=8;  
 int **q;  
 p=&a;  
 q=&p;  
std::cout << "q 的值为:" <<*q<< std::endl;  
return 0;  
}

在上面的代码中,指针“p”指向变量“a”,而“q”是指向“p”的双指针。因此,我们可以说“p”的值是“a”变量的地址,“q”变量的值是“p”变量的地址。

输出:

q 的值为:0x7ffd104891dc

在引用的情况下,不可能引用引用。如果我们尝试执行c++ 程序将抛出编译时错误

让我们通过一个例子来理解这个场景。

例子 (Example)

#include <iostream>  
using namespace std;  
int main()  
{  
  int a=8; //变量初始化  
 int &p=a; // 为 ?a? 创建一个引用变量 多变的。  
 int &&q=p;  // 对引用的引用无效,它会抛出错误。  
 return 0;  
}

输出:

main.cpp:在函数“int main()”中:main.cpp:18:10: 错误:无法将“int”左值绑定到“int&&”诠释 &&q=p;
  • 算术运算

众所周知,可以对名为“ Pointer Arithmetic ”的指针应用算术运算,但不能对引用应用算术运算。没有这个词,即C++中存在 Reference Arithmetic 。

让我们看一个简单的指针示例。

例子 (Example)

#include <iostream>  
using namespace std;  
int main()  
{  
 int a[]={1,2,3,4,5}; // 数组初始化  
  int *ptr;  // 指针声明  
  ptr=a; assigning base address to pointer ptr.  
  cout<<"*ptr 的值为:"<<*ptr;  
  ptr=ptr+1;  // 将 ptr 的值增加 1。  
  std::cout << "\n*ptr 的值为:" <<*ptr<< std::endl;  
  return 0;  
}

输出:

*ptr 的值为:1                                                                                                       *ptr 的值为:2

让我们通过一个例子来理解参考文献。

例子 (Example)

#include <iostream>  
using namespace std;  
int main()  
{  
   
 int value=90;  // 变量声明  
 int &a=value;   // 给引用赋值  
 &a=&a+5 // 不能对引用变量进行算术运算,它会抛出错误。  
 return 0;  
}

上面的代码将抛出编译时错误,因为引用不允许进行算术运算。

  • 使用社交账号登录,本站支持
全部评论(0)