C++基础 指针和引用(int*、int&、int*&、int&*、int**)

相信很多CPPers跟我一样,曾经在指针和引用里徘徊了很久很久。经常弄混指针和引用,尤其是见到如题中列出那些用法,着实是伤脑经。

后来,在项目中用着用着,就能搞清楚区别了,算是会用吧。然而,对于一个Programmer,最忌讳的就是不知其所以然,会用和懂是两番天地。停留在会用的人,始终是原地打转;而懂的人,一通百通,能举一反三。

本文,就如题的指针和引用的用法做一个介绍。

首先我们来普及一下概念,说明一下什么是指针和引用,这里借用一下变量名作为过渡。

     ■指针 ---- 指向某一块内存的变量,其本身存储的信息就是内存地址的首地址,其类型决定指向内存的大小。
            比喻,超市的储物柜。我记住我放包的柜子在第一排右起第三个,这里的1-3就是一个地址,通过地址,我可以找到柜子。这里的地址就是一个指针。

     ■变量 ---- 某一块内存地址数据值的名字
            比喻,超市的储物柜。我记住我放包的柜子上有一张贴纸,上面写着18,通过18,我可以找到柜子。这里的18,就是变量名了。

     ■引用 ---- 变量的别名
            比喻,超市的储物柜。柜子的贴纸上面写着18,但是18不好记,我用谐音记忆法,把18想成“要发”,通过“要发”,也可以找到柜子。这里“要发”就是一个引用。

通过上面的比喻可以看出来,要找到柜子,有三种方法:

1. 第一排右起第三个                      地址(指针)
2. 柜子贴纸上号为18的                    变量名
3. “要发”                              引用

理解了指针、引用的概念,我们来看看它们的使用吧,这里以经典的值交换为例,来说明int、int*、int&、int*&、int&*、int**。

1. int

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>   
  using namespace std;   
           
  void swap1( int a, int b){   
      int tmp;   
      tmp = a;   
      a = b;   
      b = tmp;   
  }   
  int main(){   
      int a = 1;   
      int b = 2;   
      swap1(a, b);   
      cout<< "a = " <<a<<endl;   
      cout<< "b = " <<b<<endl;   
      system ( "pause" );   
      return 0;   
  }

交换失败。基础牢靠的同学一眼就看出来,这样的交换只是交换了形参的值,是无法达到交换值的效果的,这段程序很简单,不做细说。

2. int*

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>   
using namespace std;   
          
void swap2( int *a, int *b){   
     int tmp;   
     tmp = *a;   
     *a = *b;   
     *b = tmp;   
}   
          
int main(){   
     int a = 1;   
     int b = 2;   
     swap2(&a, &b);   
     cout<< "a = " <<a<<endl;   
     cout<< "b = " <<b<<endl;   
     system ( "pause" );   
     return 0;   
}

交换成功。上面是的swap2接受的参数是地址,我们传入地址,就可以直接操作实参的值了,这个也很简单,不做细说。

3. int&

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>   
using namespace std;   
          
void swap3( int & a, int & b){   
     int tmp;   
     tmp = a;   
     a = b;   
     b = tmp;   
}   
          
int main(){   
     int a = 1;   
     int b = 2;   
     swap3(a, b);       
         cout<< "a = " <<a<<endl;   
     cout<< "b = " <<b<<endl;   
     system ( "pause" );   
     return 0;   
}

交换成功。引用即别名,通过引用也是可以直接访问到实参和控制实参的,这里不做细说。

4. int*&

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>   
  using namespace std;   
           
  void swap5( int *&a, int *&b){   
      int tem = *a;   
      *a = *b;   
      *b = tem;   
  }   
           
  int main(){   
      int a = 1;   
      int b = 2;   
           
      int *aPtr = &a;   
      int *bPtr = &b;   
      int *&arPtr = aPtr;   
      int *&brPtr = bPtr;   
           
      swap5(arPtr, brPtr);   
           
      cout<< "a = " <<a<<endl;   
      cout<< "b = " <<b<<endl;   
      system ( "pause" );   
      return 0;   
  }

交换成功。这个稍微复杂一点,int*&  value这样一个声明,我们从最接近value的符号看起,是个&,说明value是一个引用,它是一个什么引用呢?再看*,它是一个指针的引用,即指针的别名,我们用*value就可以访问到实参的值了。所以,其交换函数的内部逻辑跟int *是一样的。

5. int &*

交换成功。这样定义就不合法,如果从字面上来看,我们分析一下,如int &* value,最接近value的是*,说明value是一个指针,再看前面的是&,说明是一个指针的引用,而指针是无法被引用的,所以,这样的定义是不合法的,不要记这个。

6. int**

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>   
  using namespace std;   
           
  void swap6( int **a, int **b){   
      int tmp;   
      tmp = **a;   
      **a = **b;   
      **b = tmp;   
  }   
           
  int main(){   
      int a = 1;   
      int b = 2;   
      int *aPtr = &a; //指向数据的指针   
      int *bPtr = &b; //指向数据的指针   
      int **aaPtr = &aPtr; //指向指针的地址的指针   
      int **bbPtr = &bPtr; //指向指针的地址的指针   
      swap4(aaPtr, bbPtr);   
      cout<< "a = " <<a<<endl;   
      cout<< "b = " <<b<<endl;   
      system ( "pause" );   
      return 0;   
  }

交换成功。同样的,比如int **value, 最接近value的是*,说明value是一个指针,在前一个是*,说明是一个指向指针的指针,这样是合法的,那么如何访问value代表的实际参数的值呢?很简单,用**value就可以了,记住*是一个操作符,如同&一样,不过&是取地址操作符,而*是取值操作符。

来源: 博客园   作者:魔教教主_邵贤军   












关于int *a; int &a; int & *a; int * &a

上述的四条语句,前面两个很好理解,而后面两个,大部分C++初学者都会比较困惑,今天我也是查阅了一些资料以后才恍然大悟。下面具体来说明一下:

int i;

int *a = &i;//这里a是一个指针,它指向变量i

int &b = i;//这里b是一个引用,它是变量i的引用,引用是什么?它的本质是什么?下面会具体讲述

int * &c = a;//这里c是一个引用,它是指针a的引用

int & *d;//这里d是一个指针,它指向引用,但引用不是实体,所以这是错误的


先是第一个问题:引用的本质是什么?

引用就是指针,两者没有区别。我们可以把引用想象成一个不需要"*"就可以访问变量的指针,对比如下程序:

void function(int *a)

{
*a = 100;
}

int main()

{
int x=200;

int *b = &x;

function(b);

return(0);
}


void function(int &a)

{
a = 100;
}

int main()

{
int x = 200;

function(x);

return(0);
}

以上两段程序完成的功能是一样的。

第二个问题:int * &a和int & *a

我在写这两句语句时,在int 和*(&)间空了一格,而后面的&(*)紧跟a。原因是:分析此类语句时,先看a前紧跟的是什么,它决定了a的类型。而int后的一个空格是为了防止int *a, b;//a是指针,而b不是。

其他:int * *a;

它的功能和int * &a一样,两者生成的二进制代码一样。这再一次说明了引用就是指针。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中,指针引用是两个非常常见的概念,它们可以让我们更加灵活地操作内存和变量。下面我们详细介绍一下指针引用的概念及其用法。 1. 指针int*) 指针一个变量,它存储的是某个对象的地址,我们可以通过指针来访问这个对象。指针的类型与它所指向的对象的类型相同,例如int*表示指向int类型的指针指针的定义方式为: ``` int* ptr; //定义一个指向int类型的指针 ``` 我们可以通过&运算符获取一个对象的地址: ``` int a = 10; int* ptr = &a; //将ptr指向a的地址 ``` 指针的解引用使用*运算符,可以访问指针所指向的对象: ``` int b = *ptr; //将b赋值为10,即ptr所指向的对象a的值 ``` 指针还可以通过运算符进行偏移,例如ptr++表示将指针ptr向后移动一个单位,即指向下一个int类型的地址。 2. 引用int&) 引用一个别名,它与某个对象绑定在一起,我们可以通过引用来访问这个对象。引用的类型与它所绑定的对象的类型相同,例如int&表示绑定一个int类型的引用引用的定义方式为: ``` int a = 10; int& ref = a; //定义一个绑定a的引用ref ``` 我们可以直接通过引用来访问对象: ``` ref = 20; //将a的值改为20 ``` 引用指针的区别在于,引用必须在定义时就进行初始化,并且一旦绑定了某个对象,就不能再绑定其他对象;而指针可以在任何时候指向其他对象。 3. 指向指针指针int**) 指向指针指针是一种多级指针,它存储的是一个指向指针的地址。例如int**表示指向int*类型的指针指针。 指向指针指针的定义方式为: ``` int a = 10; int* ptr = &a; int** ptr_ptr = &ptr; //定义一个指向ptr的指针指针 ``` 我们可以通过*运算符进行解引用,获取指向的指针: ``` int* ptr2 = *ptr_ptr; //将ptr2指向a的地址 ``` 4. 指针引用int*&) 指针引用是一种特殊的引用,它绑定的是一个指针的别名。例如int*&表示绑定一个int*类型的指针引用指针引用的定义方式为: ``` int a = 10; int* ptr = &a; int*& ref_ptr = ptr; //定义一个绑定ptr的引用ref_ptr ``` 我们可以直接通过引用来访问指针: ``` ref_ptr = nullptr; //将ptr指向空地址 ``` 指针引用可以用于函数参数,这样可以方便地修改指针的值。 5. 引用指针int&*) 引用指针是一种指向引用指针,它存储的是一个引用的地址。例如int&*表示指向int类型的引用指针引用指针的定义方式为: ``` int a = 10; int& ref = a; int&* ptr_ref = &ref; //定义一个指向ref的指针 ``` 我们可以通过*运算符进行解引用,获取引用: ``` int& ref2 = *ptr_ref; //将ref2绑定到a上 ``` 引用指针也可以用于函数参数,这样可以方便地修改引用的值。 综上所述,指针引用C++中非常常见的概念,它们可以让我们更加灵活地操作内存和变量。在使用时,需要根据实际情况选择适合的方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值