zoukankan      html  css  js  c++  java
  • C++指针和引用的区别?

    参考来自;https://www.jb51.net/article/160003.htm

    1、指针和引用的本质(是什么)

    (1)指针是存放内存地址的一种变量,特殊的地方就在它存放的是内存地址。因此,指针的大小不会像其他变量一样变化,只跟当前平台相关——不同平台内存地址的范围是不一样的,32位平台下,内存最大为4GB,因此只需要32bit就可以存下,所以sizeof(pointer)的大小是4字节。64位平台下,32位就不够用了,要想内存地址能够都一一表示,就需要64bit(但是目前应该没有这么大的内存吧?),因此sizeof(pointer)是8。
    (2)引用的本质是“变量的别名”,就是给变量又重新起了一个名字,既然是“别名”,那么就一定要有本体。

    2、声明和初始化时的区别

    指针指向的是一个内存地址, 因此可以指向一块为0x00000000的地址,声明时可以暂时不初始化(不推荐),即pointer = NULL;

    引用是变量的别名,别名就一定对应着一个“本名”,因此必须在声明时就初始化,且不能初始化为空。

    3、使用时区别

    (1)根据声明和初始化时二者的区别,指针在声明周期内随时可能会为Null,所以使用时一定要做检查,防止出现空指针、野指针的情况;而引用则不用再操这个心,只要初始化了,在哪里都可以直接使用,再也不用担心它会不会为空什么的了。
    (2)指针因为自己存的是一个内存地址,既然可以存初始化(或者赋值)的地址,那么在指针生命周期内就可以存其他的地址,只要你是同一类型(不同类型这个对应的类型偏移不一样)的变量,对于指针都OK。

    引用作为一个变量AA的别名,在它的整个生命周期内,它只能“从一而终”,始终是第一次初始化它的那个变量的别名,在这期间任何对它的操作,都等同于对变量AA的操作。

    Talk is cheap,show you my code:

    
    
     1     std::string s1 = "萝卜";
     2      std::string s2 = "青菜";
     3      std::string s3 = "鸡蛋";
     4      std::string s4 = "西红柿";
     5      /** 指针可以初始化为空 **/
     6      std::string *p_Str = NULL;
     7      /** 引用一开始必须初始化 **/
     8      std::string& r_Str = s1;
     9     
    10      p_Str = &s2;
    11      std::cout<<"我是指针"<<*p_Str<<std::endl; /** 青菜 **/
    12      std::cout<<"我是引用"<<r_Str<<std::endl; /** 萝卜 **/
    13      std::cout<<std::endl;
    14      std::cout<<"*********分别修改指针和引用***********"<<std::endl;
    15      /** 分别修改指针和引用 **/
    16      r_Str = s3; /** 试图让r_Str为s3的别名 **/
    17      p_Str = &s4; /** p_Str重新指向了s4 **/
    18       
    19      std::cout<<"我是指针"<<*p_Str<<std::endl; /** 西红柿 **/
    20      std::cout<<"我是引用"<<r_Str<<std::endl;  /** 鸡蛋 **/
    21      std::cout<<std::endl;
    22      std::cout<<"*********查看刚刚的修改对最初初始化的影响***********"<<std::endl;
    23      /** 貌似成功了,都按照意图修改了,但是,稍等 **/
    24      std::cout<<"我是s1"<<s1<<std::endl; /** 鸡蛋 !!!注意 !!! **/
    25      std::cout<<"我是s2"<<s2<<std::endl; /** 青菜 **/
    26      std::cout<<"我是s3"<<s3<<std::endl; /** 鸡蛋 **/
    27      std::cout<<"我是s4"<<s4<<std::endl; /** 西红柿 **/
    28     
    29      /**
    30      发现s1 "萝卜" 被变成了和s3一样的"鸡蛋",这也说明了任何对引用的操作都等同于操作原先的变量本身
    31      相比较之下,指针就自由度很高了,想指向谁就指向谁,并不会影响任何之前指向过的变量
    32      惊不惊喜,意不意外 :)
    33      **/
    

    4、总结

    一个不大恰当的比喻是,指针就像是一个可以(注意是可以,但未必一定)到处沾花惹草(可以随时指向任意地址)的“渣男”;而引用则像是一个只能“从一(谁初始化就跟谁)而终”的“老实人”。

    此文仅为鄙人学习笔记之用,朋友你来了,如有不明白或者建议又或者想给我指点一二,请私信我。liuw_flexi@163.com/QQ群:582039935. 我的gitHub: (学习代码都在gitHub) https://github.com/nwgdegitHub/
  • 相关阅读:
    LAMP实例搭建wordpress博客步骤
    MySQL Replication
    Mariadb源码和二进制安装
    Linux九阴真经之九阴白骨爪残卷13(LVM的备份还原,恢复最新状态)
    Linux九阴真经之九阴白骨爪残卷12(日志功能)
    Linux九阴真经之九阴白骨爪残卷11(并发访问控制和事务Transactions)
    Linux九阴真经之九阴白骨爪残卷10(MySQL架构、缓存及索引)
    Linux九阴真经之九阴白骨爪残卷9(存储引擎MyISAM、MySQL服务器变量)
    Linux九阴真经之九阴白骨爪残卷8(存储函数、存储过程、触发器)
    Linux九阴真经之九阴白骨爪残卷7(Mariadb的三种安装方法)
  • 原文地址:https://www.cnblogs.com/liuw-flexi/p/13425798.html
Copyright © 2011-2022 走看看