zoukankan      html  css  js  c++  java
  • C/C++的const区别

    1、const基础知识(用法、含义、好处)

    int main()
    {
        const int a;   //a为const,常数型数
        int const b;  //b为const,常数型数
        const int *c;  //c为const,指向长整型数的指针(所指向的内存数据不能修改,但本身可以修改)
        int *const d;  //int*为const,常量指针(指针变量不能被修改,但是它所指向内存空间可以被修改)
        const int * const e;  //int*为const;e为const,指向常整形的常指针(指针和它所指向的内存空间,都不能被修改)
        
        return 0;
    }    
    

    const在 * 左边,变量为const;

    const在 * 右边,指针为const.

    int func1(const)

    初级理解:const是定义常量==》const意味着只读

    const好处

    //合理的利用const

    1、指针做函数参数,可以有效的提高代码的可读性,减少bug.

    2、清楚的分清参数的输入和输出特性

    int setTeacher_err(const Teacher *p);

    const修改形参的时候,在利用形参不能修改指针所指向 的内存空间

    2、C中的“冒牌货”

    //c语言中的const是一个冒牌货,可以被指针间接修改

    //c++中const是一个真正的常量,不能被修改

    int main()
    {
      //好像a是一个常量,但其实不是
        const int a=10;
        int *p=(int *)&a;
        printf("a=%d
    ",a);
        
        *p=11;//间接赋值,c语言会赋值成功,c++赋值不成功
        printf("a=%d
    ",a);
    
        return 0;
    } 

    c的结果:

      a=10

      a=11

    c++的结果:

      a=10

      a=10

    解释:

    c++编译器对const常量的处理:

    当碰见常量声明时,在符号表中放入常量 ==》 问题,如何解释取地址?

      编译过程中若发现使用常量则直接以符号表中的值替换。

      编译过程中若发现对const使用了extern或者&操作符,则给对应的常量和分配存储空间(兼容C)

    联想:下面的等式是否成立?

    int &a = 1(err) & const int &a = 10

    注意:c++编译器虽然可能为const常量分配空间但不会使用器存储空间中的值。

    结论:

     C语言中的const变量

      c语言中的const变量是只读变量,有自己的存储空间。

    C++中的const常量

      可能分配存储空间,也可能不分配存储空间

      当const常量为全局,并且需要在其他文件中使用,会分配存储空间。

      当使用&操作符取const常量的地址时,会分配存储空间。

      当const int &a=10;const 修饰引用时,也会分配存储空间。

     

    3、const在C和C++中的含义(笔试热点):

    ⑴C中的const,功能比较单一,较容易理解:
    作用:被修饰的内容不可更改。
    使用场合:修饰变量,函数参数,返回值等。(c++中应用场合要丰富的多)
    特点: 是运行时const,因此不能取代#define用于成为数组长度等需要编译时常量的情况。同时因为是运行时const,可以只定义而不初始化,而在运行时初始化。如 const int iConst;。 另外,在c中,const变量默认是外部链接,因此在不同的编译单元中如果有同名const变量,会引发命名冲突,编译时报错。


    ⑵c++中的const:

    a、非类成员const:

    ①const变量默认是内部连接的,因此在不同的编译单元中可以有同名的const 变量定义。

    ②编译时常量,因此可以像#define一样使用,而且因为上面一点,可以在头文件中定义const变量,包含的不同的cpp文件(编译单元)中使用而不引起命名冲突。

    ③编译器默认不为const变量分配内存,除非:1. 使用 extern 申明, 2:程序中有引用const 变量的地址。 

    ④c++中临时对象/内置变量默认具有const属性。

    b、类中的const:

    与c语言中的const一样,只是运行时常量,不能作为数组维数使用,即不能取代#define

     在类中使用下面两种方式取代#define:

      1:static const... 

      2 : enum{....}//enum 不占存储空间。

    类中的const 变量占用存储空间

    ③类中的const成员变量需要在构造函数初始化列表中初始化

    ④const 对象:在该对象生命周期内,必须保证没有任何成员变量被改变const对象只能调用const成员函数

    const成员函数: void fun() const ... 不仅能被const对象调用,也能被非const对象调用,因此,如果确认一个任何成员函数不改变任何成员变量,应该习惯性将该函数定义成const类型。

    ⑥如果一个对象被定义成const,那么该const对象“可能”会被放入到ROM当中,这在嵌入式开发当中有时非常重要。

     4、const和#define的区别

     const分配内存的时机,是编译器编译期间,与#define相同 

     C++中的const常量类似于宏定义#define

      const int c=5  等价于 #define c 5

    1) 编译器处理方式不同 define宏是在预处理阶段展开。 const常量是编译运行阶段使用。

    2) 类型和安全检查不同 define宏没有类型,不做任何类型检查,仅仅是展开。 const常量有具体的类型,在编译阶段会执行类型检查

    注意:尽量以const替换#define

    5、类成员中的const变量

    > 类中的const成员变量都要放在初始化列表之中进行
      > const数据成员
      > 引用数据成员
      > 对象数据成员(内置类)

      const成员函数
      > void print() const => const 类名 * const this
      > 在其内部是不能修改数据成员
      > 也不能调用非const成员函数
      > const对象只能调用const成员函数,必须要提供一个const版本的成员函数

    再深入探讨类的const成员和成员函数,参考:https://www.cnblogs.com/cthon/p/9178701.html

    补充:

    > 类中的static数据成员需要在类之外进行初始化

      > 被类或类创建的对象共享
      > 全局/静态区

      静态成员函数
      > 它的形参列表之中没有隐含的this指针
      > 不能调用非静态的数据成员
      > 不能调用非静态的成员函数
      > 只能调用静态的成员
      > 可以直接通过类名调用
    再深入探讨类的static成员和成员函数,参考:https://www.cnblogs.com/cthon/p/9178527.html

  • 相关阅读:
    [HDU5184] Brackets
    L2-036 网红点打卡攻略 (25 分)
    L2-017 人以群分 (25 分)
    L2-029 特立独行的幸福 (25 分)
    L2-035 完全二叉树的层序遍历 (25 分)
    L2-031 深入虎穴 (25 分)
    L2-020 功夫传人 (25 分)
    第 50 场双周赛
    L2-027 名人堂与代金券 (25 分)
    L2-024 部落 (25 分)
  • 原文地址:https://www.cnblogs.com/cthon/p/9166715.html
Copyright © 2011-2022 走看看