C++ 中引用、指针、const

引用、指针属于复合类型数据,即由基本数据类型加引用修饰符(&)或指针修饰符(*)而构成。

1.引用:变量或者对象所起的别名

1.1->

引用变量名不存在实体,即在内存中存没有为此变量开辟内存空间。如int a0,程序会在内存中创建2或4字节的空间存储a0变量,但int &a1=a0,并不会在内 存中开辟一个2或4字节的空间来存储a1,而是将a1和a0关联起来,通过操作a1可操作a0(功能类似指针),既然如此,为何非得多此一举?用途见下。

1.2->

引用在定义之初就必须绑定一个变量(如1.1中int &a1=a0),不能只声明而不绑定(如 int &a2 就会编译错误)。因为它不存在实体,是另一个变量的别名, 所以创建之初就必须绑定,这点与指针不同,指针可以修改指向的变量。由于引用不存在实体,所以不能 将引用绑定在另一个引用上。但实际int &a3=a1可 以运行,因为此句相当于执行int &a3=a0;

1.3->

引用变量必须和绑定的变量匹配(如1.1中 int a1绑定 int a0,如果绑定的类型不匹配会错误,如char &a4=a0会出错 )。

1.4->

多个引用可以绑定同一个变量。

2.指针:指向另一个对象的或变量的数据类型,其存储的内容为所指变量或对象的首地址。

2.1->

指针存在实体,即int *a5,即在内存中开辟了一个内存空间(4字节),用来存储a5。

2.2->

指针定义和初始化可以分开(如2.1,也可以先定义,再绑定a5=&a0,即将a5指向a0;也可在定义之初绑定 如int*a6=&a0),而且指针可以通过修改其值指向不同对象或 变量(如int b;a6=&b,即可将a6从指向a0,改为指向b)

2.3->

数组在编译时也会将数组名转化为指针,如int a7[2 ] ={1,2}就定义了一个int型数组a7,包含2个int 变量。a7当做指针来用时,其值指向第一个变量地址,*a7 就是a7[0],

*(a7+1)就是a7[1]。

2.4->

指针最好在定义之初就初始化,避免后续误操作。

2.5->

指针存放的是一个地址,但引用不存在实体,所以不存在指向引用的指针,但int *a8=&a1,可以运行,实际此句执行 int *a8=&a0,因为a1是a0别名。

3.const 修饰符:所修饰对象内容不可变

3.1->

const 修饰的变量不可变,所以在定义之初就必须初始化。如const int a8=3(也可写作int const a8=3),也可用变量初始化 如const int a9=a7[1],之后不可更改,a8=3不允 许,即使赋一样的值也不可。

3.2->

const 修饰符和引用(重要):普通引用(未被const修饰)只能绑定普通变量,const 引用可以绑定普通变 量,也可绑定const 变量。

如 int b311=0; const int b312=1;

     int &b313=b311; //允许,b313绑定b311,通过b313和b311均可修改b311

    const int &b314=b311 //允许,b314绑定b311,只能通过b311修改b311。

    const int &b315=b312 //允许,b315绑定到常量,

   int &316 =b312 //不允许,int 类型不能绑定const

3.2->

const 修饰符和指针(重要):const修饰符修饰距离它最近的变量。

3.2.1未被const 修饰的普通指针,只能指向普通变量

int *P321=&b311;

3.2.2常量指针(指向常量的指针pointer to const),此指针可以指向常量,也可以指向普通变量

const int *p322=&b311; //允许,const  距离 *p322近,所以它修饰的是(*p322)这个整体,,即指向常量的指针。

const int *p323=&b312; //允许,同上

3.2.3指针常量(指针所存的地址是常量,const pointer):此指针只能指向普通常量,且不能指向其他对象,因为此指针是一个常量。

int * const p324=&b311; //允许,p324一直指向b311,不能指向其他量,因为const 修饰 p324,这个指针内容不可改。

int *const p325=&b312; //不允许,b312是一个常量,p325是一个指针常量,const仅仅修饰此指针内容为常量

3.2.4常量指针常量(指针所指对象是常量,并且指向一个固定的变量,不可更改)

const int * const p326=&b312。 //const p326 内层const 修饰p326,* const p326 指这个指针指向固定变量,外层const 修饰这个整体,即指向的变量也是一个 const变量

4、const 修饰的引用与函数参数传递

函数参数传递分为传值(指针传递所传的本质也是数值,只不过是传递进来对象的地址),传引用。

int c40=1,c42=2;

4.1->普通参数传递,如

int add(int x,int y)

{ return x+=y;}

add(c40,c41); //在运行时,内部创建临时变量,函数运行后不更改参数本身值。

4.2->指针参数传递,如 

int add(int *x,int y)

{return *x+=*y;}

add(&c40,&c41); //运行时,通过传递进来的变量地址,寻址到参数本身,进而修改。

4.3->引用参数传递,如

int add(int &x,int y)

{ return x+=y;}

add(c40,c41); //运行时,由于形参 是实参的引用,故也会修改外部参数。

4.4->const 修饰引用形参,如

 int add( const int &x,const int &y)

{ return x+y;}

add(c40,c41) //有const 修饰,不能写成 x+=y;

4.5->const 修饰指针形参,如 

int add(const int *p,const int *y)

{return *x+*y;}

add(&c40,&c41); //有const 修饰,不能写成 *x+=*y;

可以看出:

形参用 const修饰后,函数在运行时,不能修改实参实际的值(如 4.4 写成 return x+=y;则编译不能通过)。这样函数实现者在实现此函数时,不用担心会修改 实参的值,只是读取实参值后做相应操作;而函数调用者在调用时,也不用担心,调用时会对实参产生影响。

一般说来,使用4.4方式比4.5方式好,因为const 引用 形参绑实参后,会一直绑定,直到此函数结束。而const 修饰的指针传入参数后,函数中对形参指针的误操作可能会 导致实参传递失败。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值