zoukankan      html  css  js  c++  java
  • C++学习笔记(二):进化后的const

    0x01 对const关键字的误解

    const是用来修饰变量的,const是constant的缩写,是恒定不变的意思,也翻译为常量和常数等。因为这一点很多人都认为const修饰的值是常量,这是错误的,精确的来说应该是只读的变量,它只是告诉编译器该变量不能出现在复制符号左边。

    0x02 C语言中的const

    const修饰的变量是只读的,本质还是变量。

    const修饰的局部变量在栈上分配空间。

    const修饰的全局变量在只读存储区分配空间。

    const只在编译器有用,在运行期无用。

    让我们通过一段小示例来看看在C语言中const修饰变量的上述几个特性。

    #include <stdio.h>
    
    int main()
    {
        const int c = 0;
        int* p = (int*)&c;
        
        printf("Begin...
    ");
        
        *p = 5;
        
        printf("c = %d
    ", c);
        
        printf("End...
    ");
        
        return 0;
    }
    

    通过运行结果可以看到,虽然变量c使用const修饰,但是在运行的时候,依然可以使用指针修改变量c的值。

    通过上面的运行结果,我们可以看到,当将const修饰的变量定义为全局变量时,代码编译通过,但是运行却报了段错误,这就是由于const修饰的全局变量是定义在只读数据区的,因此根据只读数据区的特性,是无法对c变量的值进行修改,从而造成了段错误。

    0x03 C++中的const

    C++在C语言的基础上对const进行了进化处理,进化后的const主要拥有以下特性:

    • 当碰见const声明时在符号表中放入常量
    • 编译过程中若发现使用const修饰的常量则直接以符号表中的值替换
    • 编译过程中若发现下述情况则给对应的常量分配存储空间(C++编译器虽然可能会为const常量分配空间,但是不会使用其存储空间的值,目的是为了兼容C语言)。
      • 对const使用了extern
      • 对const使用了&操作符

    0x04 const与宏定义

    以下一段示例代码分别使用C编译器和C++编译器进行编译,结果如下:

    #include <stdio.h>
    
    void f()
    {
        #define a 3
        const int b = 4;
    }
    
    void g()
    {
        printf("a = %d
    ", a);
        //printf("b = %d
    ", b);
    }
    
    int main()
    {
        const int A = 1;
        const int B = 2;
        int array[A + B] = {0};
        int i = 0;
        
        for(i=0; i<(A + B); i++)
        {
            printf("array[%d] = %d
    ", i, array[i]);
        }
        
        f();
        g();
        
        return 0;
    }
    
    

    GCC编译器编译结果:

    VS编译器编译结果:

    通过不同编译器的编译运行结果可以得知:

    c++中的常量类似于宏定义,比如int array[A+B] = {0}在c编译器中就报错,但是在c++编译器中没问题。

    但是c++中的const常量与宏定义又是不相同的:

    • const常量是由编译器处理
    • 编译器const常量进行类型检查和作用域检查
    • 宏定义由预处理器处理,单纯的文本替换

    所以进化后的const:

    • 是一个真正意义上的常量

    • 编译器可能会为常量分配空间

    • 完全兼容C语言中const常量的语法特性。

    参考来源:http://www.dt4sw.com/

  • 相关阅读:
    docker入门
    初级排序算法1-定义排序规则
    Lambda入门
    mac编辑器vim美化
    SSM搭建
    Memcached安装教程及使用
    lombok
    立个Flag-第一天
    等高线自适应分割
    wpf软件模拟鼠标键盘操作
  • 原文地址:https://www.cnblogs.com/askta0/p/12732121.html
Copyright © 2011-2022 走看看