C++多彩的运算符语义以及对引用的语义解析

本文通过实例详细介绍了C++中的引用概念,包括引用作为变量别名的特点及其与指针的区别,展示了如何利用引用进行变量赋值及修改,并比较了C++引用与Java、C#中的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 熟悉C/C++编程语言的朋友都知道,在C/C++中对于有些运算符和关键字在不同场合会有不同的语义,有时甚至是截然不同。比如,在作为双目运算符时,*表示乘法运算;&表示按位相与运算。而作为单目运算符时,*表示取指针所指地址的内容;&表示取变量地址或脱去解引用(参考http://blog.youkuaiyun.com/zenny_chen/archive/2008/06/04/2512056.aspx)。然而,对于一种变量在不同场合下会有不同的效果,这个可能在其它编程语言中也不多见吧?在C语言中似乎没有,但是在C++中却有。

 

由于C++有操作符重载以及对象类型转换,使得C++对象作为左值和右值可以有截然不同的行为,参照以下代码:

 

  1. #include <iostream>
  2. using namespace std;
  3. class Test
  4. {
  5. private:
  6.     const char* name;
  7.     int* pValue;
  8. public:
  9.     Test(const char* n) : name(n)
  10.     {
  11.     }
  12.     const intoperator = (int& i)
  13.     {
  14.         pValue = &i;
  15.         return *pValue;
  16.     }
  17.     operator const char* (void)
  18.     {
  19.         return name;
  20.     }
  21.     void Output(void)
  22.     {
  23.         cout << "The name is: " << name << endl;
  24.         if(pValue == NULL)
  25.             cout << "The value is null!" << endl;
  26.         else
  27.             cout << "The value is: " << *pValue << endl;
  28.     }
  29. };
  30. int main(void)
  31. {
  32.     int a;
  33.     Test t("Hello");
  34.     t = a = 10;
  35.     const char *p = t;
  36.     cout << "p is: " << p << endl;
  37.     t.Output();
  38.     return 0;
  39. }

下面我们将介绍C++特有的一种内在语法——引用。

对C++比较熟悉的朋友应该知道,当一个引用指向一个变量时,如果变量引用被赋予另一个值,那么被引用的变量的值也会被相应改变。如以下代码:

 

  1. #include <iostream>
  2. using namespace std;
  3. int main(void)
  4. {
  5.     int a = 0;
  6.     int &r = a;
  7.     r = 1;
  8.     cout << "The value is: " << a << endl;
  9.     return 0;
  10. }

这只是一个简单的例子,来说明引用的基本特性。下面将切入正题,解开引用的神秘面纱:

 

  1. #include <iostream>
  2. using namespace std;
  3. void MagicSummon(int* &rp)
  4. {
  5.     int *p = rp;
  6.     cout << "The content is: " << *p << endl;
  7.     p = NULL;
  8.     rp = p;
  9. }
  10. int main(void)
  11. {
  12.     int a = 10;
  13.     int *p = &a;
  14.     MagicSummon(p);
  15.     cout << "The value of the pointer is: " << p << endl;
  16.     return 0;
  17. }

对于引用,我们可以将它理解为作为被引用变量的别名——比如:int &r = a; 当你在使用引用r时,你可以将它想象为正在使用a,也就是说对r进行操作与对a进行操作没有本质上的区别。为了能实现这个语义,如果现在把r看作为存在实体的变量,那么它在扮演左值与扮演右值时具有相同的操作。这似乎看起来不是很明显。

在上述例子中使用了对指针变量的引用,更能看清事实真相。我们现在假设参数rp是一个实体(有为它分配存储地址的),然后用以下代码来做个对比:

 

  1. #include <iostream>
  2. using namespace std;
  3. void MagicSummon(int** pp)
  4. {
  5.     int *p = *pp;
  6.     cout << "The content is: " << *p << endl;
  7.     p = NULL;
  8.     *pp = p;
  9. }
  10. int main(void)
  11. {
  12.     int a = 10;
  13.     int *p = &a;
  14.     MagicSummon(&p);
  15.     cout << "The value of the pointer is: " << p << endl;
  16.     return 0;
  17. }

可以看出,在C++中,定义一个变量的引用可以实现为定义一个指向该变量的指针,然后总是以解引用(取内容)的操作使用该指针

比如:int &r = a;  r = 0; int b = r  ==> int *p = &a; *p = 0; int b = *p;

            int* &rp = p; rp = NULL; int *q = rp;  ==>  int **pp = &p; *pp = NULL; int *q = *pp;

这个显然与Java和C#中的引用功能不同。所以在C++中做一个交换值的函数比在Java和C#中要方便得多。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值