zoukankan      html  css  js  c++  java
  • C++常量const

    常量折叠概念

      常量折叠表面上的效果和宏替换是一样的,只是“效果上是一样的”,而两者真正的区别在于,宏是字符常量,在预编译宏替换完成后,该宏名字会消失,所有对宏的引用已经全部被替换为它所对应的值,编译器当然没有必要维护这个符号,而常量折叠发生的情况是,对常量的引用情况全部替换为该常量的值,但是,常量名并不会消失,编译器会把它放入到符号表中,同时会为该变量分配空间,栈空间或全局空间。

    void const_test()
    {
        int i0 = 11;  
    
        const int i=0;         //定义常量i  
        int *j = (int *) &i;   //看到这里能对i进行取值,判断i必然后自己的内存空间  
        *j=1;                  //对j指向的内存进行修改  
        printf("%d
    %d
    %d
    %d
    ",&i,j,i,*j); //观看实验效果  
        const int ck = 9; //这个对照实验是为了观察,对常量ck的引用时,会产生的效果  
        int ik = ck;  
    
        int i1 = 5;           //这个对照实验是为了区别,对常量和变量的引用有什么区别  
        int i2 = i1;  
    }

    输出结果:

      0012ff7c

      0012ff7c

      0

      1

    (1)ij地址相同,*j==1,而i的值却实实在在等于0
    (2)printf("%d %d %d %d ",&i,j,i,*j) 别替换为printf("%d %d %d %d ",&i,j,0,*j) 
    (3)对可折叠的常量的引用会被替换为该常量的值,而对变量的引用就需要访问变量的内存

    const在集合中的错误使用

      const可以用于集合,但编译器不能把一个集合存放在它的符号表里,所以必须分配内存。在这种情况下,const意味着“不能改变的一块内存”。然而其值在编译时不能被使用,因为编译器在编译时不需要知道存储的内容。

      const int i[] = {1,2,3,4,5};
       int a = i[3];
       float f[i[3]];  // illegal

      在一个数组定义里,编译器必须能产生这样的移动存储数组的栈指针代码,在上面的非法定义里,编译器给出的提示是因为它不能再数组定义里找到一个常量表达式。

    const在C和C++中的区别

    const int buffsize = 10;
    char buff[buffsize];

      上面的代码在C++中可以,但在C中不行,因为buffsize占用存储的某个地方,所以C编译器不指定它在编译时的值

    const int buffsize;

      上面的代码在C中可以,因为在C中默认const为外部链接,C++默认const为内部链接,所以再C++中要写成extern const int buffsize;

     类里const和enum

      在一个类里,const恢复它在C中的一部分意思,它在每个类对象里分配存储并代表一个值,这个值一旦被初始化以后就不能改变。在一个类里使用const的意思是“在这个对象寿命周期内,这是一个常量”。然而,对这个常量来讲,每个不同的对象可以含一个不同的值。所以不能像下面这么写:

    class bob
    {
        const int nSize = 100;
        int array[nSize];
    };

      因为在类对象进行了存储空间分配,编译器不知道const的内容是什么,所以不能把它用作编译期间的常量。

      我们可以使用不带实例的无标记的enum

    class bob
    {
       enum {nSize = 100};
        
        int array[nSize];
    };
    使用enum是不会占用对象中的存储空间的,枚举常量在编译时被全部求值。枚举在类外面时,占用4个字节空间

      这样,在一个类里建立一个const时,不能给它初值。这个初始化工作必须发生在构造函数里,并且要在构造函数的某个特殊的地方。因为const必须在建立它的地方被初始化,所有在构造函数的主体里,const必须已经被初始化,否则就只有等待,直到在构造函数主体以后给它初始化,这样无法防止在构造函数主体的不同地方改变const的值。

    class fred
    {
    private:
        const int nSize;
    public:
        fred();
    };
    
    fred::fred():nSize(100){}
  • 相关阅读:
    poj 3661
    hdu 4291 && hdu 4296
    codeforces LCM Challenge
    ural 1286
    Exhange2007 专题(一)特性 部署
    Research Http error code
    Exhange2007 专题(二)通过Web service对Exhange进行二次开发
    YouTube 架构学习体会
    .net framework 4.0环境下遇到版本不同编译不通过的解决办法
    利用ASP.NET MVC2进行网站验证
  • 原文地址:https://www.cnblogs.com/xiaobingqianrui/p/8794040.html
Copyright © 2011-2022 走看看