专栏首页Linux驱动1.C和C++区别,以及const分析(底层const/顶层const)

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再次声明

C和C++的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\n", 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\n", 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\n", c,*p);
    return 0;
}

输出结果:

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

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

3.2 const和define区别

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

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

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

接下来,我们以一个例子来分析const和define

代码如下:

#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\n",*p);

p=&b;                //正确,可以更改指针指向的地址
printf("%d\n",*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\r\n",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\r\n",y);

输出结果:

y=2

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 2.C++中的bool类型,三目运算符,引用

    在C++中,bool类型只有true(非0)和flase(0)两个值,且bool类型只占用了一个字节.

    张诺谦
  • 26.QT-模型视图之自定义委托

    由于模型负责组织数据,而视图负责显示数据,所以当用户想修改显示的数据时,就要通过视图中的委托来完成

    张诺谦
  • 61.QT-QSortFilterProxyModel代理实现排序、过滤

    在之前60.QT-QabstractTableModel模型、重写sort方法排序章节中,学习了如何用model,本章再来学习QSortFilterProxyM...

    张诺谦
  • 【正则】223-JS常用正则表达式备忘录

    正则表达式或“regex”用于匹配字符串的各个部分,下面是作者创建正则表达式的备忘单,供大家学习参考。

    pingan8787
  • JS常用正则表达式备忘录

    正则表达式或“regex”用于匹配字符串的各个部分 下面是我创建正则表达式的备忘单。

    Fundebug
  • 【专业技术第二讲】c语言中const的使用

    遇到有人为const的使用: ? 这里对const的使用做一个大致的总结。 C语言的const关键字与指针搭配使用,const是C语言中保留的一个关键字,它用来...

    程序员互动联盟
  • C++中const小结

    1、const修饰普通变量(非指针变量) const修饰变量,一般有两种写法: const TYPE value; TYPE const value; 对于一个...

    用户1215536
  • const关键字应用总结

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,通过查阅资料,将const作用归纳如下:

    C语言与CPP编程
  • const的那些事

    在我们使用c/c++的时候,或者在面试的时候,会被问道与const相关的问题,比如const修饰放在指针的哪个位置,const修饰的引用传递与值传递等等,这些究...

    公众号guangcity
  • const关键字到底该什么用

    我们都知道使用const关键字限定一个变量为只读,但它是真正意义上的只读吗?实际中又该如何使用const关键字?在解答这些问题之前,我们需要先理解const关键...

    编程珠玑

扫码关注云+社区

领取腾讯云代金券