• const分别在C和C++语言里的含义和实现机制


    const的含义

           简单地说:const在c语言中表示只读的变量,而在c++语言中表示常量.

    C语言

    const是constant的缩写,是恒定不变的意思,也翻译为常量,但是很多人都认为被const修饰的值都是常量,其实这是不精确的.因为,精确来说应该是只读的变量,其值在编译的时候不能被使用,因为编译器在编译的时候不知道其存储的内容.或许当初这个关键字应该被替换为readonly.

    C语言中const定义的变量只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的只读变量在程序运行过程中只有一个备份(因为它是全局的只读变量,存放在静态区),而#define定义的宏变量在内存中有若干个备份.

    c++语言:

    const是C++中常用的类型修饰符,常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的.

             C++引入const的初始目的是为了取代预编译指令,消除他的缺点,同时继承它的优点.<缺点:只是简单值和代码的替代,缺乏类型的检测机制,安全性不好;优点有三:1.避免意义模糊的数字出现,清晰程序语义2.方便参数的调整和修改,3.提高程序执行效率,因为不需要为常量分配空间>

    问题出来了:为什么const能取代预定义语句?

    1.   首先,以const修饰的变量和对象具有不可变性,这是它能取代预定义语句的基础.

    2.   第二,很明显,它同样能避免意义模糊的数字定义,也可以方便地进行参数的调整与修改.

    3.   第三,c++编译器通常不为普通const常量(普通是指内置类型,不包括结构体等类型)分配存储空间,只是把它们保存在符号表中(注意:c语言中则会为const变量分配存储空间),这使得它们成为了编译期间的常量,没有了存储和读内存的操作,使得它的效率非常高,同时,也是它能取代预定义语句的重要基础.

    4.   最后,const定义也能像普通的变量定义一样,它会由编译器对它进行类型的安全检查,消除了预定义语句带来的安全隐患.

    我们使用一张表来总结const的作用:

    No.

    作用

    说明

    参考代码

    1

    可以定义const常量

     

    const int Max = 100; 

    2

    便于进行类型检查

    const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误

    void f(const int i) { .........}
          //对传入的参数进行类型检查,不匹配进行提示

    3

    可以保护被修饰的东西

    防止意外的修改,增强程序的健壮性。

    void f(const int i) { i=10;//error! }
          //如果在函数体内修改了i,编译器就会报错

    4

    可以很方便地进行参数的调整和修改

    同宏定义一样,可以做到不变则已,一变都变

     

    5

    为函数重载提供了一个参考

     

    class A
    {
               ......
      void f(int i)       {......} //一个函数
      void f(int i) const {......} //上一个函数的重载
               ......
    };

    6

    可以节省空间,避免不必要的内存分配

    const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝

    #define PI 3.14159         //常量宏
    const doulbe  Pi=3.14159;  //此时并未将Pi放入ROM中
                  ......
    double i=Pi;   //此时为Pi分配内存,以后不再分配!
    double I=PI;  //编译期间进行宏替换,分配内存
    double j=Pi;  //没有内存分配
    double J=PI;  //再进行宏替换,又一次分配内存!

    7

     提高了效率

    编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高

     

    const的实现机制

    const究竟是如何实现的呢?对于声明为const的内置类型,例如int,short,long等等,编译器会如何实现const的本意?那么对于非内置类型是否也是与内置数据类型一样处理呢,例如对于结构体类型则会怎样处理呢?下面通过几个小例子来说明这些问题: 
    C语言const示例: 


    const int i=10; 
    int *p=(int *)(&i); 
    *p=20; 
    printf("i=%d *p=%d ",i,*p); 


    猜一猜输出结果是什么? i=20 *p=20 
    C++语言const示例1: 


    const int i=10; 
    int *p=const_cast<int *>(&i); 
    *p=20; 

    cout<<"i="<<i<<"*p="<<*p<<endl; 


    输出结果是 i=10 *p=20 
    C++语言const示例2: 


    struct test{ 
    int j; 
    char tmp; 
    test() 

    j=30; 
    tmp='a'; 

    }; 
    int main(int argc, char* argv[]) 

    const struct test t1; 
    int *q=(int *)(&t1.j); 
    *q=40; 
    cout<<"j="<<t1.j<<"*q="<<*q<<endl; 
    return 0; 


    输出结果是 j=40 *q=40 

    示例结果分析 
    看到上面三组输出结果,我们可以分析两个问题:

    问题1:C语言和C++语言中的const究竟表示什么?

    问题2:const的实现机制究竟是怎样的?

     
    问题1,对于const int类型的变量i,C语言中通过指针p修改了值后,i变成了20;而在C++中,通过指针p修改了值后,i仍然是10。 
    问题2,C++语言中 const struct test的元素j通过指针q被改变了,为何const int 与 const struct test的反应机制不同? 

    针对问题1,我们知道C语言中const表示只读的变量,既然把const看成是变量,那么其在内存中就会有存储他的空间,并且可以通过指针间接的改变该内存空间的值,当通过指针p改变该内存中的值后,再获取i的值的时候,会访问该空间,得到的是被改变后的值。而C++把const看做常量,编译器会使用常数直接替换掉对i的引用,例如cout<<i; 会理解成cout<<10; 并不会去访问i的内存地址去取数据,这里有点像是C语言里的宏#define i 10。因此C++里i会输出10,而*p会输出20. 

    针对问题2,C++语言中只是对于内置数据类型做常数替换,而对于像结构体这样的非内置数据类型则不会。因为结构体类型不是内置数据类型,编译器不知道如何直接替换,因此必须要访问内存去取数据,而访问内存去取数据必然会取到被指针q改变后的值,因此会造成与C++中const int类型完全不一样的处理模式。 

    参考文章:http://blog.csdn.net/chenhuajie123/article/details/9221149

  • 相关阅读:
    Scrum立会报告+燃尽图 01
    robotframework笔记6
    robotframework笔记7
    robotframework笔记5
    loadrunner函数
    robotframework笔记4
    robotframework笔记3--如何编写好的测试用例使用机器人的框架
    robotframework笔记2
    robotframework笔记1
    eclipes的Spring注解SequenceGenerator(name="sequenceGenerator")报错的解决方式
  • 原文地址:https://www.cnblogs.com/mengchunchen/p/5295315.html
Copyright © 2020-2023  润新知