zoukankan      html  css  js  c++  java
  • 1.C和C++区别,以及const分析(底层const/顶层const)

    从本章起开始从0学习C++,本章主要内容:

    • 1)C和C++的基本区别
    • 2)C和C++的const区别

    1.C++C区别

    1.1 C++更强调语言的实用性,所有变量都可以在需要时再定义

    比如:

    for(int i=0;i<100;i++);

    1.2 C++不允许定义多个同名全局变量,而C却可以重复定义

    1.3 C++的register只是个兼容作用

    1.4 C++的所有标识符都必须有声明类型

    比如,C:

    f():  表示默认返回值是int,可以接受任意个int型参数的函数

    C++:

    int f() int f(void)表示都一样,没有参数,返回值为int型的函数

    int f(i): 由于i没声明类型,会报错

    1.5 结构体升级

    例如,C定义一个结构体:

    typedef student_type student;   //声明
    struct student_type{ char *name; int age; }; struct student_type student1={"Li",20}; /*或者*/ student student2={"Zhang",20};

    而在C++,只需要这么写:

    struct student_type{
    char *name;
    int age;
    };
    
    student_type student2={"Zhang",20};   //不需要strcut再次声明

    CC++const区别

    2. C中的const

    2.1 介绍

    C语言中的const只是让变量变为只读属性,其本质还是变量,不是真正意义上的常量(只有enum枚举定义的才是常量).

    注意:const变量不能被直接赋值,但是可以通过指针来修改const变量.

    由于const局部变量会存在,const全局变量会存在只读存储内存

    所以我们可以通过指针来修改const局部变量,但是修改const全局变量,会使程序崩溃.

    2.2修改const实例

    1)实例1-通过指针来修改const局部变量

    代码如下:

    #include <stdio.h>
    int main()
    {
        const int c = 0; //const局部变量
    
        int* p = (int*)&c;
        *p = 5;          //通过指针修改const变量
    
        printf("c = %d
    ", c);
        return 0;
    }

    输出结果:

     

    2)实例2-通过指针来修改const全局变量

    代码如下:

    #include <stdio.h>
    const int c = 0; //const全局变量
    int main()
    {
        int* p = (int*)&c;
        *p = 5; //修改const变量
        printf("c = %d
    ", c);
        return 0;
    }

    输出结果:

     

    由于指针修改只读存储区的数据,所以导致程序崩溃

    3. C++中的const

    3.1 介绍

    C++,const变量则是真正的常量,定义时会将其放入符号表.

    所以编译途中遇到使用const变量时,则直接从符号表中取出常量.

    只要当该const变量为全局(使用extern声明过),或者被使用&操作符,才会被分配存储空间.

    接下来,我们以一个例子来分析存储空间

    代码如下:

    #include <stdio.h>
    int main()
    {
        const int c = 0;    //const局部变量
    
        int* p = (int*)&c; //使用&操作符,会分配空间
    
        *p = 5;  
    
        printf("c = %d,*p=%d
    ", c,*p);
        return 0;
    }

    输出结果:

    为什么输出结果会有两个不同的值?

    这是因为使用&c,会从符号表中取出c的值,并将0存在一个新的分配空间地址里,所以*p修改的只是分配出来的空间地址内容,c还是常量.

    3.2 constdefine区别

    是不是感觉C++中的constdefine宏定义一样?其实不一样!

    • const常量:     由编译器处理,它会对const常量进行类型检查和作用域检查
    • define宏定义: 由预处理器处理,直接进行文本替换,不会进行各种检查

    (预处理器是执行编译器之前运行的程序,用来删除注释,宏变量转换等)

    接下来,我们以一个例子来分析constdefine

    代码如下:

    #include <stdio.h>
    void f()
    {
        #define a 3        //定义宏
        const int b = 4; //定义局部变量
    }
    
    int main()
    {  
        f();   
        printf("a=%d",a);
    
        //printf("b=%d",b);
        return 0;
    }

    输出结果:

     

    这是因为执行预处理器时,会将遇见到的所有a变为3,所以编译器看到的是printf("a=%d",3);

    而取消//printf("b=%d",b); 屏蔽后,程序则会报错,是因为b的作用域只在f()函数里有效.

    3.3 指针const

    指针const分为两种: 底层const, 顶层const

    (普通变量的const(或引用)永远是顶层const,也就是说,const int int const本质都一样)

    1)底层const(位于*左侧)

    常量指针,表示指向的对象是个常量,不能修改其内容,只能更改指针指向的地址.

    其实很好理解,比如 const int *p, 修饰*p是个const常量.而*p是指向对象的内容.所以表示指向对象的内容是常量

    但是可以通过其它方式修改内容,例如:

    int a=1,b=3;
    
    const int *p=&a;     //底层const
    
    //*p=2;              //错误,无法修改*p指向的a里面内容
    
    a=2;                 //正确,通过其它方法来修改*p的内容
    printf("%d
    ",*p);
    
    p=&b;                //正确,可以更改指针指向的地址
    printf("%d
    ",*p);

    输出结果:

    2
    3

    2)顶层const(位于*右侧)

    指针常量,表示不能更改指针指向的地址,只能修改其内容(定义时必须被初始化)

    其实很好理解,比如  int * const p, 修饰 p是个const常量.而 p是指向对象的地址.所以表示指向对象的地址是个常量

    和引用非常相似,例如:

    int a=1;
    int b=3;
    
    //int *const p;    //错误,没有被初始化
    
    int *const p=&a;   //顶层const
    
    //p=&b;            //错误,不能更改指针指向的地址
    
    *p=2;              //正确,修改a的值等于2

    3.4 顶层const变量可以替代mutable变量

    1) mutable介绍

    mutable 是为了突破 const 的限制而设置的。被 mutable 修饰的变量,将永远处于可变的状态,即使在一个 const 函数中,甚至结构体变量或者类对象为 const,其 mutable 成员也可以被修改。

    示例1:

    class Test{
        
        mutable int mval; 
    public:
        Test():mval(0) 
        {
        } 
        void setVal(int num) const 
        {
            mval=num; 
            cout<<mval<<endl;     //打印10,能在const函数中对mutable变量赋值
        } 
    }; 
    
    int main()
    {
        const Test t;
        
        t.setVal(10);     
        
    }     

    2)通过const替代后:

    class Test{
        
         int * const mval; 
    public:
        Test():mval(new int(0)) 
        {
        } 
        void setVal(int num) const 
        {
            *mval=num;             //由于mval是const类型,所以修改时不会报错
            cout<<*mval<<endl;  //打印20
        } 
    }; 
    
    int main()
    {
        const Test t;
        t.setVal(20); 
        
    }     

    3.5 volatile const

    大家都知道volatile是指对该变量操作时,不能进行优化

    1)c++,使用volatile const,编译器不会将其放入常数表,而是以只读变量的形式来定义

    例如:

     volatile const int x=1;     
     int *p= (int *)&x;   
    
     *p=2;
        
     printf("x=%d
    ",x);

    输出结果:

    x=2

    2) 当使用const时,赋予的值是volatile类型,也是以只读变量形式,因为编译器不能将该volatile类型的变量优化为一个常量

    实例:

    volatile  int x=1;    
    const int y=x;          //y的值是个volatile型
    
    int *p= (int *)&y;
       
    *p=2;
        
    printf("y=%d
    ",y);

    输出结果:

    y=2

     

     本章结束,下章来学习:  C++中的bool类型,三目运算符,引用

     

     

     

  • 相关阅读:
    CTO干点啥?
    [转] 持续集成与持续交付备忘录
    [转]概率基础和R语言
    程序自信
    [转]Neural Networks, Manifolds, and Topology
    ubuntu14 + nginx + php
    [转]http://makefiletutorial.com/
    REDIS key notification
    GO RPC
    xpcall 安全调用
  • 原文地址:https://www.cnblogs.com/lifexy/p/8436731.html
Copyright © 2011-2022 走看看