C++学习2.3_引用,指针

1.引用必须被初始化。

  程序将引用和它的初始值绑定在一起,而不是将初始化拷贝给引用,因为无法令引用重新绑定到另一个对象,因此引用必须初始化。

2.引用即别名

  引用并不是对象,只是为一个已经存在的对象起的一个别名。

3.引用只能定义在对象上,而不能与某个字面值或某个表达式的计算结果绑定在一起。

  int &refVal4 = 10;    //错误 ,引用只能定义在对象上

  double dval = 3.14;  

  int &refVal5 = dval;  //错误,引用以及初始值类型不同。

引用的类型要与之绑定的对象类型严格匹配。

 

指针

  指针是指向另外一种类型的复合类型,实现了对其他对象的间接访问。与引用的不同点如下:

    a.指针本身是一个对象,允许指针赋值和拷贝,可以在指针生命周期先后指向不同的对象。

    b.指针无须再定义时赋初值,在块作用域内定义的指针如果没有被初始化,将拥有一个不确定的值。

 

获取对象的地址

  指针若想获取某对象的地址,需要使用取地址符。( & ) 

  指针的类型要和它所指向的对象严格匹配。

    int ival = 42;

    int *p = &ival;  //p存放变量ival的地址,或者说p是指向变量ival的指针。

    

   指针与引用:因为引用不是对象,没有实际地址,因此不能定义指向引用的指针。

指针的值

  指针的值(即地址)应属于下列四种状态之一

  a.指向一个对象。

  b.指向紧邻对象所占空间的下一个位置。

  c.空指针,意味着指针没有指向任何对象。[访问无效指针的后果无法预计,野指针的危害!]

  d.无效指针。也就是上述情况之外的其它值。

 

这里写个小程序输出一下指针里面的东西:

 1 #include<iostream>
 2 using namespace std;
 3 int main() 
 4 {
 5     double dval;
 6     double *pd = &dval;
 7     
 8     double *pd2 = pd;
 9     
10     dval = 3.1;
11     cout<<" dval   "<<dval<<endl<<" pd "<<pd<<endl<<"*pd "<<*pd<<endl; 
12     return 0;
13 }

 

其输出结果为:

  

 利用指针来访问对象

  如果指针指向了一个对象,则允许使用解引用符( * )来访问该对象。【就像上面代码里所表示的那样】

  对指针解引用会得出所指的独享,因此如果给解引用的结果赋值,实际上也就是给指针所指的对象赋值

注意:解引用符仅仅适用于确实指向了某个对象的有效指针。

 

关键概念:有多重含义的符号,符号的上下文决定了符号的意义。

在之前的代码基础上增加了一些引用指针的一些操作验证:

 1 #include<iostream>
 2 using namespace std;
 3 int main() 
 4 {
 5     double dval;
 6     double *pd = &dval;
 7     
 8     double *pd2 = pd;
 9     
10     dval = 3.1;
11     cout<<" dval   "<<dval<<endl<<" pd "<<pd<<endl<<"*pd "<<*pd<<endl; 
12     
13     double *pd3;
14     
15     pd3 = pd;
16     cout<< *pd3<<endl;
17     
18     *pd = 4.1;
19     cout<<"*pd    "<<*pd<<"    "<<"dval     "<<dval<<"     "<<endl;
20     
21     cout<<"***************************************************"<<endl;
22     
23     double  &r2 = *pd;//引用,r2引用指针pd,因为指针是一个对象,可以这么搞,其实相当于 &r2 = dval; 
24     cout<<"r2    "<<r2; 
25      
26     return 0;
27 }

 

  其输出为:

    

空指针

   空指针不指向任何对象,生成空指针的方法如下:

  

int *p1 = nullptr;        //等价于int *p1 = 0;
int * p2 = 0;
//需要include cstdlib
Int *p3 = NULL;    //等价于int *p3 = 0 ;

  上面的几种方法里,第一个nullptr是C++11新标准刚引入的一种方法。

  第三个,使用名未NULL的预处理变量来给指针赋值,这个变量在cstdlib中定义,它的值为0;

  【在新标准下建议使用第一个】

 

建议初始化所有的指针,这很重要!

 

赋值和指针

  要搞清一条赋值语句到底是改变了指针的值还是指针所指对象的值,最好的办法就是记住: 赋值永远改变的是等号左侧的对象。

其它指针操作

  只要指针拥有一个合法值,就能将他用在条件表达式中,如果指针的值为0,则条件取false;而任何非0指针对应的条件都是true;

 

void* 指针

  void* 是一种特殊的指针类型,可以用于存放任意对象的地址,只是对地址中到底是个什么类型的对象并不了解。

  不能直接操作void*指针所指的对象,因为不知道类型。

指向指针的指针

  通过指针的个数来区别指针的级别,**表示指向指针的指针,**表示指向指针的指针的指针。

  从左至右第一个pointer存放的是pi的地址,第二个pointer存放的是value的地址。所以,*pi就是value的值,pi就是value的地址,ppi是pi的地址,*ppi是value的地址,**ppi就是value的值。

  [一次解引用得到的是所指向的指针里存放的东西,也就是value的地址,第二次解引用就是value的值。

 

指向指针的引用

  引用本身不是对象,因此不能定义指向引用的指针,但是指针是对象,所以存在对指针的引用。

 

posted @ 2019-03-19 22:11  Stephen_A  阅读(127)  评论(0编辑  收藏  举报