zoukankan      html  css  js  c++  java
  • 第12课 经典问题解析一

    1. 关于const的疑问

    (1)const常量的判别准则

      ①只有用字面量初始化的const常量才会进入符号表,如const int i = 1;

      ②使用其它变量初始化的const常量仍然是只读变量。如const int a = b;//a为只读变量

      ③被volatile修饰的const常量不会进入符号表,如volatile const int i = 1;//这时会为i分配内存,且i每次都是从内存中取值加const只是说明i不能作为左值

      ▲在编译期间不能直接确定初始值的const标识符,都被作为只读变量处理。

    (2)const引用的类型与初始化变量的类型

      ①当用变量来初始化与const引用时,如果两者类型相同,则初始化变量成为只读变量

      ②当用变量来初始化与const引用时,如果两者类型不同,则将生成一个新的变量,即引用的是另一个新变量,而不是原来的用来初始化引用的那个变量。

    【编程实验】const典型问题分析

    #include <stdio.h>
    
    int main()
    {
        //实验1:初始化变量的类型与引用类型相同时
        const int x = 1;
        const int& rx = x;//x与rx的类型相同,所以rx为只读变量,不能作为左值
                          //但本质上还是变量,引用x的内存值(而不是符号表中的值)
    
        int& nrx = const_cast<int&>(rx);//转为普通引用
    
        nrx = 5;  //nrx与rx都引用了x的内存值
    
        printf("x = %d
    ", x);     //1,从符号表中读取
        printf("rx = %d
    ", rx);   //5,从内存中读取
        printf("nrx = %d
    ", nrx); //5,从内存中读取
    
        printf("&x = %d
    ", &x);
        printf("&rx = %d
    ",&rx);
        printf("&nrx = %d
    ",&nrx); //x、rx、nrx地址相同
    
        //实验2:初始化变量的类型与引用类型不同时
        char c = 'c';
        char& rc =c;
        const int& trc = c;//c与trc类型不一致,则会生成一个新的变量,然后trc引用这个新的变量
        
        rc = 'a';
    
        printf("c = %c
    ", c);  //c
        printf("rc = %c
    ",rc); //c
        printf("trc = %c
    ",trc);//a
    
        printf("&c = %p
    ", &c); 
        printf("&rc = %p
    ",&rc); //rc与c的地址相同
        printf("&trc = %p
    ",&trc);//trc是一个新的地址
    
        //实验3:volatlie
        volatile const int y = 2; //volatile修饰,分为y分配内存
        int* p = const_cast<int*>(&y);//因y被const修饰,不能作为左值
    
        *p = 6; //因y不能作为左值,用来代替y = 6;这样的写法
    
        printf("y = %d
    ", y);//6,volatile指示y得从内存中读取
        printf("p = %p
    ", p);//y的地址
    
        const int z = y; //用变量初始化const常量,z不会进入符号表,z分配内存
    
        p = const_cast<int*>(&z);
        
        *p = 7;
    
        printf("z = %d
    ", z);//7,因z没进入符号表
        printf("p = %p
    ", p);//z的地址
    
        return 0;
    }

    2. 关于引用的疑问

    (1)指针与引用的不同

     

    指针

    引用

    初始化

    值是一个内存地址,不需要初始化

    必须在定义时初始化,之后无法代表其它变量

    访问内存

    通过指针可以访问对应内存地址中的值

    对引用的操作(赋值,取地址等)都会传递到其代表的变量上。

    const修饰

    被const修饰成常量或只读变量。 如const int* p;//p

    const引用,表示其代表的变量具有只读属性。如,const int& a等价于const int* const a;

    (2)从使用C++语言的角度来看,引用与指针没有任何关系。引用是变量的新名字,操作引用就是操作对应的变量。当进行C++编程时,直接站在使用的角度看待引用,与指针毫无关系,引用就是变量的别名

    (3)从C++编译器的角度来看,在编译器内部,使用指针常量来实现“引用”。因此,“引用”在定义时必须初始化。当对C++代码进行调试分析时,一些特殊情况,可以考虑站在C++编译器的角度看待引用。

    【编程实验】引用典型问题分析

    #include <stdio.h>
    
    int a = 1;
    
    struct SV
    {
        int& x;
        int& y;
        int& z;
    };
    
    int main()
    {
        int b = 2;
        int* pc = new int(3);
        
        //将sv各成员初始化为变量a,b,*pc等内存的引用
        SV sv = {a, b, *pc};
        printf("&sv.x = %p
    ", &sv.x);//变量a的地址,全局区
        printf("&sv.y = %p
    ", &sv.y); //变量b的地址,栈
        printf("&sv.z = %p
    ",&sv.z);   //new出来的地址,堆
    
        //在C++中没有“引用数组”的概念,请看如下分析
        //对于数组而言,其内存是连续分布的。当进行&array[1] - &array[0]
        //表示前后两个元素的地址相差的值,应等于sizeof(元素的类型)。
        //但如果允许定义“引用数组”的话,如下面语句,&array[1]表示第1个元素
        //的地址,即元素b的地址(&b),而&array[0]表示&a,显然这两个地址是不连续的。
        //所以int& array[]={a, b, *pc};//这样的定义是错误的,C++里不支持“引用数组”
    
        return 0;
    }

    3. 小结

    (1)指针是一个变量,而引用是一个变量的新名字

    (2)const引用能够生成新的只读变量

    (3)在编译器内部使用指针常量实现“引用”

    (4)编译时不能直接确定初始值的const标识符都是只读变量

  • 相关阅读:
    程序人生系列之新闻发布系统 1217
    $("expr","expr")
    jQuery 插件开发by:ioryioryzhan
    jQuery插件开发全解析 by gaojiewyh
    前端水好深
    网页设计师一定要知道的网站资源
    jQuery end()方法 by keneks
    前端书籍 by 小精灵
    emacs命令速查 摘
    jquery要怎么写才能速度最快? by 大白
  • 原文地址:https://www.cnblogs.com/5iedu/p/5375549.html
Copyright © 2011-2022 走看看