现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

C++中指针和引用的区别和联系

2012-07-07 07:44 工业·编程 ⁄ 共 2884字 ⁄ 字号 暂无评论

一:关于引用的知识:

1.引用的概念:
      引用就是给变量取一个别名.主要用于函数参数和返回值类型,符号 type & 表示 type 类型的引用.
  

2.引用的特点:
      引用变量和被引用变量的值同步变化(两者实际操作的都是同一个内存空间).可以看做是特殊的指针。
     引用必须在定义时马上被初始化.

3.引用的优势:
      使用引用就是使用"被引用对象本身",不需要建立临时对象,传值效率高.

4.引用的限制:
   (1).引用必须初始化.(初始化指的就是定义的时候赋值,不能先定义后赋值)
       int  iNum1 = 300;
       int  &riNum = iNum1;

   (2).引用初始化之后不能更改其引用关系.
        int &riNum = iNum2; //出错

   (3).不允许直接改变常引用的值,即不允许通过常引用改变被引用变量的值,但是被引用变量本身则是可以改变的.
        int iNum = 500;
       const int &riNum = iNum;//定义一个常引用
       cout << riNum << endl;
       iNum += 100;//被引用变量改变,常引用的值也相应改变
       //riNum += 100;     

   (4).在VC++中不允许定义对一个常量的间接引用(即引用被const修饰的变量).
         const int iNum4 = 500;
         int &riNum4 = iNum4;//编译出错

    (5).指针可以有多级,但是引用只能是一级.

5.引用的使用:
   (1).单纯地给某个变量去一个别名的意义不是很大.即独立引用的实际应用不是很多.
   (2).引用的主要目的是在函数调用参数传递中,解决大块数据或者对象的传值效率和空间效率的问题.也可以作为函数的返回值.
  
6.独立引用声明格式:

7.独立引用的初始化方式:
    独立引用必须在其声明的时候初始化.
(1).int &rNum = iNum;   //被引用变量为变量值.
(2).const double &rd = 1.0;  //被引用变量为常量值.相当于const double rd = 1.0;
  
    独立引用的使用:
        int *p1 = &iNum1;
        int * &p2 = p1;                 //对指针变量的引用(指针类型(int *) + & 引用名 = 指针变量名;)
       cout<< " *p1= " << *p1 << "  *p2 = "<< *p2 << endl;    //p1与p2等效.

        int a[5] = {1,2,3,4,5};
        int &ra = a[4];                 //对数组元素a[4]的引用
       cout<< "a[4] = " << a[4] << " ra = " << ra << endl;       //a[4]与ra等效.

二:指针和引用的区别和联系:

1.相同点:
     (1).在C++中,指针和引用经常用于函数的参数传递,均可实参和形参的双向传值.
     (2).都是地址的概念;
       指针指向一块内存,它的内容是所指内存的地址;
       引用则是某块内存的别名.

2.不同点:
     (1).从概念上讲:
     指针从本质上讲就是存放变量地址的一个变量,指针是一个实体,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变。指针可以为空(使用指针之前必须做判空操作,而引用就不必。)
     引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化(引用不可以为空),而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量)。

     (2).指针传递参数和引用传递参数的本质上不同:
     指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。(这里是在说实参指针本身的地址值不会变,而其指向的内容可以被修改).

     引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。

     (3)."sizeof引用”得到的是被引用变量(对象)的大小.
         “sizeof指针”得到的是指针本身的大小,4个字节;
 
      (4).引用是类型安全的,而指针不是 (引用比指针多了类型检查).
       由于不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,因此引用很安全。对于指针来说,它可以随时指向别的对象,并且可以不被初始化,或为NULL,所以不安全。const 指针虽然不能改变指向,但仍然存在空指针,并且有可能产生野指针(即多个指针指向一块内存,free掉一个指针之后,别的指针就成了野指针)。

     (5).使用形式:
       引用比指针使用起来形式上更漂亮,使用引用指向的内容时可以之间用被引用变量名,而不像指针一样要使用*;定义引用的时候也不用像指针一样使用&取址。

三:常量指针和常量引用:

1.常量指针:
   (1).概念:
   指向常量的指针,在指针定义语句的类型前加const,表示指向的对象是常量。
   定义指向常量的指针只限制指针的间接访问操作,而不能规定指针指向的值本身的操作规定性。
  常量指针定义"const int* pointer=&a"告诉编译器,*pointer是常量,不能将*pointer作为左值进行操作。

        int iNum2 = 20;
        const * i_ptr2 = &iNum2;
   
        iNum2 = 200;
        //*i_ptr2 = 200;  //出错
    (2).

2.常量引用:
    (1).概念:
      常量引用:在引用定义语句的类型前加const,表示指向的对象是常量。也跟指针一样不能利用引用对指向的变量进行重新赋值操作。

        int iNum4 = 40;
       const int & riNum2 = iNum4;

       iNum4 = 400;
      //riNum2 = 400;

给我留言

留言无头像?