庖丁解牛<C++primer>系列一:引用和指针

还是开始吧,虽然犹豫了那么久。最近经常有工作之后或者大四快毕业的童鞋询问我如何学习编程。本人水平不高,又唯恐误人子弟,所以准备重新对编程的一些经典教材进行解读,这次首先看的是《 C++primer》,争取做到浅显易懂。如有遗漏之处,请各位客官多多指正。

       1.引用

        先说引用(reference)。引用的定义:为对象起的另外一个名字。这里对象(object)可不是指你的男朋友或者女朋友,而是指一块能存储数据并且具有某种类型的内存空间,内存中的一小块存储空间,并且它的空间大小根据数据而定,数据是int型就是16位,如果是double就是十位有效数字。

        同理,引用类型就是引用(refers to)另外一种类型。并且是以“&d”的形式来表示的,而“d”是一个变量名,只要你高兴你可以写成“&a”、“&apple”,“&taobao”等任意形式,但是最好符合书写规范以及你要表达的意思。

  

   强调1.引用必须初始化

  1. //例子1  
  2. int ival=1024;  //初始化变量ival为1024  
  3. int &reval=ival; //把reval名字改为ival的名字, 那reval也为1024了   
  4. int &reval;  // 错误,由于引用没有进行初始化,程序会报错  


  强调2.比较引用和赋值之间的区别

  1. int i=100,j=200; //对i和j进行赋值  
  2. int &i2= i; //把i2的名字改成i,那么i2为100;  
  3. int &j2=j; //把j的值赋给j2  

  1. int &i=100; //错误,不能对引用直接值,只能引用一个变量  
  2. double j=3.14;  
  3. int &i=j; //错误,类型错误  


       指针和引用的区别:一、指针本身就是一个对象,可以赋值和拷贝;二、指针在定义时候可以赋初始值也可以不赋初始值。

     

      2.指针

      指针(pointer):定义时候要写成“*d”的形式,其中*也被成为解引用符,也称操作符。

      取地址符(&d):指针指向某个对象的地址,这个地址和你寄顺丰快递时候所写的地址意思差不多,只不过这里指的是内存中的地址位置,想要获取该地址就要用到取地址符。

     

  1.        double dval;  
  2. double *pd=&dval; //正确,初始值是double型对象的地址   
  3. double *pd2=pd; //正确,初始值是指向double对象的指针  
  4. int *pi=pd; //错误,指针pi的类型和pd指针的类型是不匹配的  
  5. pi=&dval; //错误,试图把double型对象的地址赋给int型指针   

     指针值:也就是地址必须是下列四种情况之一

     ①.指向一个对象


  1. int ival=42;  
  2. int *p=&ival; //p存放着变量ival的地址,或者说p是指向变量ival的指针   
  3. cout<<*p; //由符号*得到指针p所指的对象,输出42  
  1.  //知识拓展  
  2.  int i=42;  
  3. int *p;  
  4. p=&i; //&是一个取地址符,因为出现在表达式中   
  5. *p=i; //*是一个解引用符 ,因为出现在表达式中   
  6. int &r1=*p; //&是声明的一部分,*是一个解引用符   

     指针可以用在条件表达式中,使用“==”或者“!=”来进行比较,如果指针的值取0,则条件去false;

  

          
             int ival=1024;  
  1. int *pi=0; //pi是合法的,是一个空指针   
  2. int *p2=&ival; //pi2是一个合法的指针,存放着ival的地址   
  3. if(pi) //pi的值是0,因此条件的值是false   
  4.        //.....  
  5. if(p2) //pi2指向ival,为1024,条件值是true   
  6. //.....   
     void指针:void指针是一个特殊的指针类型,可以存放任意对象的地址。
  1. double obj=3.14,*pd=&obj; //void能够存放任意类型对象的地址   
  2. void*pv=&obj; //obj可以是任意类型的对象   
  3. pv=pd; //pv存放任意类型的指针   
  4. //std::cout<<pv<<std::endl; //输出obj地址0X22fea0  
  5. //std::cout<<pd<<std::endl; //输出obj地址0X22fea0  
  6. //std::cout<<&obj<<std::endl; //输出obj地址0X22fea0  
  7. std::cout<<obj<<std::endl; //输出obj的值3.14   

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

    

     ③.空指针,意味着指针没有指向任何对象

    

  1.  //空指针是不指向任何对象的,下面介绍三种常用的空指针   
  2. int*p1=nullpter; //等价于int *p1=0;   
  3. int *p2=0; //直接将p2初始化为字面常量0   
  4. int *p3=NULL; //等价于int *p3-0;   
  5. //其中NULL是预处理变量,不属于命名空间std,属于预处理器负责管理,而预处理器是运行于编译过程之前的一段程序   

注意:把int变量赋给指针是一个错误的操作,哪怕int变量初始值为0也不行
  1. int zero=0;  
  2. ; //错误,不能把int变量直接赋给指针  
  1.  int i=42;  
  2. int *pi=0; //pi被初始化,但没有指向任何对象   
  3. int *pi2=&i; //pi2被初始化。存有i的地址,即42  
  4. int *pi3; //如果pi3定义于内存块内,则pi3的值无法确定  
  5. pi3=pi2; //pi3和pi2指向同一个对象  
  6. pi2=0; //现在pi2不指向任何对象   

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

       

    3.符合类型的声明

  1. int i=1024,*p=&i,&r=i; //i是一个int类型的数,p是一个int类型的指针,r是一个int类型的引用   
  2. ut<<i<<' '<<p<<' '<<r<<std::endl; //结果分别是1024,0x22fea4, 1024  

    *是指指针,**是指指向指针的指针,***是指指向指针的指针的指针

 

  1.         int ival=1024;  
  2.     int *pi=&ival; //pi指向一个int类型的数  
  3.     int **ppi=&pi; //ppi指向一个int类型的指针   
  4.         std::cout<<ival<<"\n"  
  5.         <<*pi<<"\n"  
  6.         <<**ppi  
  7.         <<std::endl;  //结果都是1024   

  特别提醒输出指针*p时,p是指向内存中的地址,*p是类型的内容,不要搞错了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值