zoukankan      html  css  js  c++  java
  • [转载]& 引用 取地址

    原文地址:& 引用 取地址作者:beter

    引用实际上就是给同一个变量取了多个名字。  
      举个例子:  
      有个人的名字叫a,之后又改名叫b,这时a和b都是指这个人,这样b就引用了a,即b就是a。

     int   &a   =   b;    ........1  
     int   *a   =   &b;   ........2  
     在1的情况下,   只分配了b的空间  
     在2的情况下,   分配了a和b的空间  
     

    引用是C++的叫法  
    取地址是C的叫法  

       
      简单说:  
      引用,需要一个对象  
      取地址,不用。  
       
      另:把引用说是指针,也不为过。其区别可以这么说  
      引用不能改变,指针可以改变。  
      引用有安全机制检查,指针没有。  

       
    引用的2大作用:    
          1)作为函数的参数,用于提高效率(如常量入参,返回类的成员变量的值)、返回数据...  
     作为函数的参数,用于提高效率这里主要是指用类实例作为参数,因为如果不是用引用,也不使用指针,
    那么在参数的传递过程中,将有一个隐含的调用类的构造函数的操作,也就是说将构造一个新的类作为参数,
    使用引用将避免这个过程,如果担心类中的成员被修改,那么可以再加上const修饰符  

          2)简化代码,使代码易读。如:  
              要使用a->b->c->d->e->f->g,g是一个多重嵌套类中的一个整数成员,书写很麻烦,也容易错。  
     这时:  
              int   &z   =a->b->c->d->e->f->g;  
              以后直接使用z,因为他们的存贮单元本来一致,所以也根本没有效率的损失。


    --------------------------------------------------------------------------------------------------

    //------------>怎样理解引用的作用和意义.
    你是否感觉:&在几个用法中没有一致的性质可循.
    下面我们就来探讨和总结一下:


    #include <iostream>
    #include <stdio.h>

    using namespace std;

    void main(void)
    {
        //测试引用是否可以赋以常量.
       
       
        //考察引用和指针的使用区别
       
       
       //测试对引用取址返回的结果
      
      
       //测试是否可以重新赋值
      
       
        //说明引用的一种错误用法..........
       
       
       
       
        //测试引用和指针混合的情况...
            typedef char* PChar;
            typedef char& RChar;
            typedef PChar& RPChar;
           
            PChar str = "I am programming.";
           
           
           
            RPChar rpchar = str;
            cout<<str<<endl<<rpchar<<endl;
           
            getchar();
    }
    */

    /***********
    /*结论:对于int& a;引用实际是一种隐式指针,是方便编程而引入的,识别由编译器支持
    .
            在函数的使用中.可把它理解为跟后面的结合. int (&a);
            在传递参数的过程中跟取地址值意思差不多.
    /*     而在函数内部使用过程中则相当与数值.你可把它看作便利的原因.其实引用&
    /*      是一个能自动被编译器逆向引用的常量型指针
    总结:      ...
    /*  A.常规使用:
    /*                    1.   int a = 100;
    /*                         int &b = a;
    /*                    2.   int a = 100;
    /*                         int &b = a;
    /*                         int &c = b;
    /*                    3.   int a = 100;
    /*                         int &b;  //必须定义时赋值,不同于指针(int a = 100;
    /*                                    // int *p; p =&a;) 
    /*                         b = a;
    /*                    4.   int &a = 100; //不可将常量赋予引用...

    /*                         const int& a = 100;//可行,作全局看
    /*                    5.   int a = 100;
    /*                         int &b = a;
    /*                         cout<<&b<<endl; //输出的是a(也是b)的地址..而不是指针
    /*                                                   // 的地址...
    /*                    6.   int a = 100;
    /*                         int &b = a;
    /*                         int *ptr;    
    /*                         ptr = &a;
    /*                         cout<<a<<b<<*ptr<<endl;  //结果是一样的..注意*ptr.
    .
    /*                    7.   int a =100;
    /*                         int b = 200;
    /*                         int &c = a;
    /*                         c = b;      //引用可重新赋值...........
    /*                        
    /*B.较难的使用规则:
    /*                    1.   系列错误用法:
    /*                                       char* str = "I am programming.";
    /*                         定义引用数组:int& a[3]; (定义指针数组:int* a[3];
    )
    /*                         定义引用的指针:int&* a; (定义指针的指针:int** pt
    r;
    /*                         定义引用的引用:int&& a;
    /*                    2.   可定义指针的引用:  int*& a = str;  //When it must

    /*                         be initialized when definedv. 
    /*                     
    /*C.引用在函数和对象域的使用
    /*                    1.  做函数返回类型的应用:(当然传递的参数类型为引用,那么

    /*                        是地址传递方式...)
    /*                         int arr[3] = {1,2,3}; 
    /*                         fook(2) = 100;    //函数返回的是引用,做左值时,编译

                                                  //器将其当作地址使用....
    /*                                           //而如返回的是常量,那当然不可
                                                  //赋值
                                      
    /*                         int& fook(int index){ return (arr[index]+1);}
    /*
    /*                    2.返回局部变量
    /*                         int& fook(param){
    /*                              int m = 100;
    /*                                 return m;
    /*                                         }
    /*                         //在函数结束生命周期后,返回的地址将不可用.
    /*
    /*                   3.不好的对普通对象的引用
    /*                     class MClass;
    /*                     MClass* mcptr;
    /*                     mcptr = new MClass(param);
    /*                     if(!mcptr) MError("Constructing object failed.");
    /*                     MClass& mcref = *mcptr;
    /*                     也许上面的引用可以使你感觉更舒服的使用MClass: 如
    /*                      mcref.function();而不必
    /*                     (*mcptr).function();或mcptr->function();
    /*                     可是相比之下,一个严重的问题来了:内存泄露..
    /*                     因为引用不像指针那样明显:你很可能忘记:delete &mcref;

    /*
    /*                  4.对对象相关的参数的引用               
    /*                    void fook(param1)     
    /*                    {
    /*                             param->function(noramlparam);
    /*                    }
    /*                    上面的程式中,我想传递一个对象的地址,从而使用对象的成员函
    /*                    数..怎么办?
    /*                     
    /*                    void fook(MClass* mcpptrparam){};
    /*                    恩,可以.     
    /*                    用一用:
    /*                    MClass mcptr = new MClass(param);
    /*                    fook(mcptr);
    /*                    还有呢:
    /*                    MClass mcobj;
    /*                    fook(&mcobj);
    /*
    /*                    当然你也可:
    /*                    void fook(MClass& mcrefparam){};
    /*                    这样引用的对象可在全局数据区、堆栈、栈
    /*                  5.当然引用真的就是为了方便吗?.......
    /*                    其实正如它在函数返回值里的应用,可由编译器识别为地址,在作
    /*                    为对象相关参数的
    /*                    引用里亦存在同样的好处,指针的引用可替换指针的指针,多变的
    /*                     工作....

    http://blog.sina.com.cn/s/blog_46b7d6050100tvwn.html

  • 相关阅读:
    Android中onBackPressed()的使用
    Python初次学习
    svn Mac下面无法更新png
    UIView的layoutSubviews和drawRect
    "_deflate", referenced from: -[NSData(NSDataAdditions) gzipDeflate] in NSDataAdditions.o
    Error12
    pods安装
    xib为view添加边框
    这些机型将被淘汰
    Development cannot be enabled while your device is locked.
  • 原文地址:https://www.cnblogs.com/dyg540/p/3567161.html
Copyright © 2011-2022 走看看