你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

c++中,const的使用

[复制链接]
gaosmile 发布时间:2020-6-2 12:11
大家好晚上好,今天给大家分享的是,c++中的const的使用,在我们以前学习c语言的时候,我们已经接触了const的用法,那么在c++中,const的使用,又会有什么样的不同呢?接下来就开始我们的分享吧!每天进步一点点,日积月累你也是专家!
一、c语言中const的用法:
1、const修饰的变量是只读的,本质还是变量。

2、const修饰的局部变量在栈分配空间,这里举一个例子:

#include <stdio.h>

int main()
{
    const int c =0;
        int *p (int *)&c;
       
        printf("start\n");
       
        *p=6;
       
        printf=("c=%d\n",c);
       
        return 0;
}

最终演示结果可以看到,c的值发生了改变:

root@txp-virtual-machine:/home/txp/c++# ./a.out
start
c=6


3、const修饰的全局变量在只读存储区分配空间

4、const只在编译期有用,在运行期无用。

另外关于c语言里面常用的const几种用法,可以我之前写的文章(小声说提示一下,当时第一次写文章,排版排的差劲,还请理解!)[color=var(--weui-LINK)]超实用的const用法
二、c++中的const用法:
既然今天主题是C++中的const用法,想都不用想,c++中的const的用法和c语言里面的const用法肯定有不一样的地方,下面我们来看具体的用法:
1、当碰见const声明时在符号表中放入常量。

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

3、编译过程中若发现下面情况则给对应的常量分配存储空间
    ——对const常量使用了extern
    ——对const常量使用&操作符
   
  注意:c++编译器虽然可能为const常量分配空间
  ,但不会使用其存储空间中的值。

这里的话,还是以上面的那个例子来举例,我们现在在c++环境下来编译试试,最终结果会是什么情况:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
root@txp-virtual-machine:/home/txp/c++# ./a.out
start
c=0

这时候突然发现,c的值居然还是零,有点难以置信;其实不然,这就是我们上面说的,在c++中,在上面的编译过程中会产生一个符号表的概念(符号表是编译器在编译过程中所产生的一张表,这张表是编译器内部的数据结构),我们还是拿刚才的那个示例来分析:
微信图片_20200602121039.png
我们来分析一下,在c语言里面指针p初始化的时候,指向了c,然后在对指针p取值操作,也就是说,改变了这时候所p指向的那个地址(&c)处的内存里面的内容,原来是0,现在被改成了6;然而在我们的c++编译环境中,就不是按照这样来想的了,如上面的示意图,可以看到,在c++编译过程中会有一个符号表生成,那么当操作指针p的时候,由于c的值暂时被放到了符号表中了,所以的话,这个时候*p只是属于自己在那块内存中赋值操作而已,影响不到c的值了,下面我添加打印一下(*p)的值来说明:
#include <stdio.h>

int main()
{
    const int c =0;
  int *p =(int *)&c;
  
  printf("start\n");
  
  *p=6;
  
  printf("c=%d\n",c);
  printf("*p=%d\n",*p);
  return 0;
}

演示结果:
root@txp-virtual-machine:/home/txp/c++# ./a.out
start
c=0
*p=6

三、c++中的const与宏的区别:
1,const 常量由编译器处理;
2,编译器对 const 常量进行类型检查和作用域检查;
3,宏定义由预处理器处理,单纯的文本替换,无类型和作用域检查;
为了大家方便理解,下面我们来举个例子来说明情况,不过为了说明c++里面const修饰的变量,本质还是变量,并且只有验证一下c语言里面的const只用在编译过程中有用,在运行期没有用,这里我们先举例一个c环境的代码,然后再到c++环境中编译,做一个简单的对比,方便大家理解:
#include <stdio.h>
  void f()
  {
      #define a 3
      const int b = 4;
  }
  
  void g()
  {
     printf("a = %d\n", a);
     //printf("b = %d\n", b);
  }

int main()
{
     const int A = 1;
     const int B = 2;
     int array[A + B] = {0};
     int i = 0;
     for(i=0; i<(A + B); i++)
     {
         printf("array[%d] = %d\n", i, array);
     }
     
     f();
     g();
     
     return 0;
}

演示结果,这个是在c环境下编译的现象:
root@txp-virtual-machine:/home/txp/c++# gcc test.c
test.c: In function ‘main’:
test.c:18:6: error: variable-sized object may not be initialized
      int array[A + B] = {0};
      ^
test.c:18:6: warning: excess elements in array initializer [enabled by default]
test.c:18:6: warning: (near initialization for ‘array’) [enabled by default]

什么居然编译通过不了,不要吃惊,在刚才也说了结论。我们现在具体来看一下它的说了啥, “variable-sized object may not be initialized”意思是:可变大小的对象可能无法初始化,也就是说明在c语言中使用const修饰的变量A和B,本质上还是变量。这里另外再啰嗦一下,面试的时候,千万不要说const修饰的就是常量,在c语言里面真正比较好的常量例子,通过 enum(枚举)定义的标识符才是真正意义上的常量。
接下来我们在c++环境中编译看看:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
root@txp-virtual-machine:/home/txp/c++# ./a.out
array[0] = 0
array[1] = 0
array[2] = 0
a = 3

哈哈通过了,这也说明了,在c++中一般定义的变量类型,在其前面加了const修饰,它就真的变成了常量了;同时细心的你可能发现,怎么在哪个函数里面有一个宏定义啊;平时大家可能见的比较多的是,宏定义都是写在最前面,这里不要奇怪,因为编译在编译到这里的时候,只是把宏定义换成了"a=3",而且还要注意上面const和宏定义的区别:编译器对 const 常量进行类型检查和作用域检查。于是乎我把上面的那个g()函数里面的注释拿掉,再进行编译:
#include <stdio.h>
  void f()
  {
      #define a 3
      const int b = 4;
  }
  
  void g()
  {
     printf("a = %d\n", a);
     printf("b = %d\n", b);
  }

int main()
{
     const int A = 1;
     const int B = 2;
     int array[A + B] = {0};
     int i = 0;
     for(i=0; i<(A + B); i++)
     {
         printf("array[%d] = %d\n", i, array);
     }
     
     f();
     g();
     
     return 0;
}

编译结果:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
test.cpp: In function ‘void g()’:
test.cpp:11:25: error: ‘b’ was not declared in this scope
      printf("b = %d\n", b);

在g()函数里面找不到变量b,没有定义,这证明了上面所说的观点。
四、总结:
1,与 C 语言不通,C++ 中的 const 不是只读变量;

2,C++ 中的 const 是一个真正意义上的常量;

3,C++ 编译器可能会为 const 常量非配空间;

4,C++ 完全兼容 C 语言中 const 常量的语法特性;

收藏 评论0 发布时间:2020-6-2 12:11

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版