C++第12课--经典问题分析(一)

本文学习自 狄泰软件学院 唐佐林老师的 C++课程


提炼:
const常量

  1. const常量判别准则1 – 用字面量初始化的const常量是常量,进符号表
  2. const常量判别准则2 – 使用其他变量初始化的const常量仍然是只读变量
  3. const常量判别准则3 – 被volatile修饰的const 常量为只读变量
  4. const常量判别准则4 – 在编译期间不能确定初始值的const标识符,都是只读变量

const 引用

  1. const引用类型判别准则1 – const引用类型与初始化变量类型相同时,const引用变量成为只读变量,原变量属性不变。
  2. const引用类型判别准则2 – const引用类型与初始化变量类型不同时,生成一个新的只读变量
  3. const引用类型判别准则3 – 当使用常量对 const引用进行初始化时,C++编译器会为常量分配存储空间,并将引用名作为该空间别名

实验1:

  1. const常量判别准则1 – 用字面量初始化的const常量是常量,进符号表
  2. 当使用常量对 const引用进行初始化时,C++编译器会为常量分配存储空间,并将引用名作为该空间别名

实验2:

  1. const常量判别准则3 – 被volatile修饰的const 常量为只读变量
  2. 以前都是直接暴力类型转换:int* p = (int*)&y; 在C++中优先使用新型类型转换
  3. 被const修饰的只读变量。& 取址后 地址也具有只读属性

实验3:

  1. const常量判别准则2 – 使用其他变量初始化的const常量仍然是只读变量
  2. const常量判别准则3 – 被volatile修饰的const 常量为只读变量
  3. const常量判别准则4 – 在编译期间不能确定初始值的const标识符,都是只读变量

实验4:用不同类型的变量初始化const引用标识符,将生成一个新的只读变量

实验5:C++不支持引用数组

  1. C++中不支持引用数组!!! 因为在C语言中 数组中的每个元素在内存中是顺序存放的,也就是说他们的地址是递增的。所以C++中也要继承这个特性,然而唯有 “引用数组” 破坏了这个特性,“引用数组”中的元素在内存中是不一定顺序存放的,所以C++不支持 “引用数组” !!!

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

扫描二维码关注公众号,回复: 8928326 查看本文章

实验1:

  1. const常量判别准则1 – 用字面量初始化的const常量是常量,进符号表

  2. 当使用常量对 const引用进行初始化时,C++编译器会为常量分配存储空间,并将引用名作为该空间别名

     #include <stdio.h>
     
     int main()
     {
         const int x = 1; //用字面量初始化 const常量--> 常量 进符号表
    
     /*
     引用就是变量的别名 也就是 一段内存空间的别名,即C++编译器为 x常量分配的但没有使用的空间的别名
     当使用常量对 const引用进行初始化时,C++编译器会为常量分配存储空间,并将引用名作为该空间别名
     使用常量对const引用初始化后将生成一个只读变量
     */
         const int& rx = x;
         
      //消除只读变量的只读属性,nrx 和 rx 代表同一个空间的别名,只是nrx 可以自由使用该空间。
         int& nrx = const_cast<int&>(rx);
     
     nrx = 5;
     
     printf("x = %d\n", x);
     printf("rx = %d\n", rx);
     printf("nrx = %d\n", nrx);
     printf("&x = %p\n", &x);
     printf("&rx = %p\n", &rx);
     printf("&nrx = %p\n", &nrx);
     
     return 0;
     }
    
     
     mhr@ubuntu:~/work/c++$ g++ 12-1.cpp
     mhr@ubuntu:~/work/c++$ 
     mhr@ubuntu:~/work/c++$ ./a.out 
     x = 1
     rx = 5
     nrx = 5
     &x = 0x7ffcf93daea4
     &rx = 0x7ffcf93daea4
     &nrx = 0x7ffcf93daea4
     mhr@ubuntu:~/work/c++$ 
    

实验2:

  1. const常量判别准则3 – 被volatile修饰的const 常量为只读变量

  2. 以前都是直接暴力类型转换:int* p = (int*)&y; 在C++中优先使用新型类型转换

  3. 被const修饰的只读变量。& 取址后 地址也具有只读属性

     #include <stdio.h>
     
     int main()
     {
         volatile const int y = 2; // 只读变量
    
     /*
     y 被const修饰,是只读变量。&y 取址 也具有只读属性,此处去除只读属性 并强制转换为 int*
     以前都是直接暴力类型转换:int* p = (int*)&y; 在C++中优先使用新型类型转换
     */
     int* p = const_cast<int*>(&y); 
     
     *p = 6;
     
     printf("y = %d\n", y);
     printf("p = %p\n", p);//指向一个合法的地址
    
     
     return 0;
     }
    
     mhr@ubuntu:~/work/c++$ g++ 12-1.cpp
     mhr@ubuntu:~/work/c++$ ./a.out 
     y = 6
     p = 0x7fff511cbf2c
     mhr@ubuntu:~/work/c++$ 
    

实验3:

  1. const常量判别准则2 – 使用其他变量初始化的const常量仍然是只读变量

  2. const常量判别准则3 – 被volatile修饰的const 常量为只读变量

  3. const常量判别准则4 – 在编译期间不能确定初始值的const标识符,都是只读变量

     #include <stdio.h>
     
     int main()
     {
         volatile const int y = 2; //只读变量
         const int z = y; //只读变量
         int* p  = const_cast<int*>(&z);
         
     *p = 7;
     
     printf("z = %d\n", z);
     printf("p = %p\n", p);
     
     return 0;
     }
    
     mhr@ubuntu:~/work/c++$ 
     mhr@ubuntu:~/work/c++$ g++ 12-1.cpp
     mhr@ubuntu:~/work/c++$ 
     mhr@ubuntu:~/work/c++$ ./a.out 
     z = 7
     p = 0x7fffa9bf0e5c
     mhr@ubuntu:~/work/c++$ 
    

实验4:用不同类型的变量初始化const引用标识符,将生成一个新的只读变量

#include <stdio.h>

int main()
{
    
    char c = 'c';
    char& rc = c;
    const int& trc = c;//生成一个新的只读变量
    
    rc = 'a';
    
    printf("c = %c\n", c);
    printf("rc = %c\n", rc);
    printf("trc = %c\n", trc);
    
    return 0;
}

mhr@ubuntu:~/work/c++$ 
mhr@ubuntu:~/work/c++$ g++ 12-1.cpp
mhr@ubuntu:~/work/c++$ 
mhr@ubuntu:~/work/c++$ ./a.out 
c = a
rc = a
trc = c
mhr@ubuntu:~/work/c++$ 

在这里插入图片描述

在这里插入图片描述

引用必须在定义的时候初始化,之后无法代表其他变量,所以引用的本质是指针常量 type* const name

在这里插入图片描述

在这里插入图片描述

实验5 :站在编译器角度看引用

#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 sv = {a, b, *pc};
    int& array[] = {a, b, *pc}; //error &array[1] - &array[0] = ?  Expected ==> 4
    
    printf("&sv.x = %p\n", &sv.x);
    printf("&sv.y = %p\n", &sv.y);
    printf("&sv.z = %p\n", &sv.z);
    
    delete pc;
    
    return 0;
}


mhr@ubuntu:~/work/c++$ g++ 12-2.cpp
12-2.cpp: In function ‘int main()’:
12-2.cpp:17:16: error: declaration of ‘array’ as array of references
     int& array[] = {a, b, *pc}; // &array[1] - &array[0] = ?  Expected ==> 4
                ^
mhr@ubuntu:~/work/c++$ 

C++中不支持引用数组!!! 因为在C语言中 数组中的每个元素在内存中是顺序存放的,也就是说他们的地址是递增的。所以C++中也要继承这个特性,然而唯有 “引用数组” 破坏了这个特性,“引用数组”中的元素在内存中是不一定顺序存放的,所以C++不支持 “引用数组” !!!


在这里插入图片描述

发布了207 篇原创文章 · 获赞 100 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/LinuxArmbiggod/article/details/104094918