第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典型问题分析  12-1.cpp

#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++编译器的角度看待引用

【编程实验】引用典型问题分析  12-2.cpp

#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标识符都是只读变量

原文地址:https://www.cnblogs.com/hoiday/p/10089340.html