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\n",a); *p=11;//间接赋值,c语言会赋值成功,c++赋值不成功
printf("a=%d\n",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

C/C++的const区别的更多相关文章

  1. 2018/03/08 每日一学PHP 之 常量defind 和 const区别

    常量defind 和 const区别 什么是常量? 如字面理解的,在脚本执行期间不可改变的的量. 定义一个常量应该注意的事项? 1:常量默认大小写敏感,错误的大小写不会被识别为常量. 2:常量只能是标 ...

  2. let、var、const区别(表格比较)

    let.var.const区别(表格比较): 区别项 let var const 作用域 块级作用域 全局作用域或函数作用域 块级作用域 是否有变量提升 无 有 无 是否可重复声明 不可 可以 不可 ...

  3. (转)全局变量、extern/static/const区别与联系

    全局变量.extern/static/const区别与联系 编译单元(模块):     在IDE开发工具大行其道的今天,对于编译的一些概念很多人已经不再清楚了,很多程序员最怕的就是处理连接错误(LIN ...

  4. var、let和const区别

    var.let和const区别 变量提升问题 var声明的变量存在变量提升,而let与const声明的变量不存在变量提升,但存在暂时性死区 即在预编译阶段,js引擎扫描代码时,遇到变量声明,会把var ...

  5. readonly和const区别

    常量和只读变量的区别 const string name="Xuj"; readonly string name; 1.常量是不可改变的,只读变量只能在构造方法中才能改变其值. 2 ...

  6. var、let 及 const 区别

    var console.log(a) // undefined var a = 1 从上述代码中我们可以发现,虽然变量还没有被声明,但是我们却可以使用这个未被声明的变量,这种情况就叫做提升,并且提升的 ...

  7. PHP中的Define和Const区别

    我们经常把不经常变的值定义成常量,常量一般用全部大写来表示,前面不加美元符号,那么define和const有什么区别呢? 常量是一个简单的标识符.在脚本执行期间该值不能改变(除了所谓的魔术常量,他们其 ...

  8. C# readonly与const区别

    静态常量:是指编译器在编译时候会对常量进行解析,并将常量的值替换成初始化的那个值. 动态常量的值则是在运行的那一刻才获得的,编译器编译期间将其标示为只读常量,而不用常量的值代替,这样动态常量不必在声明 ...

  9. let const区别!

    这次做项目在申明变量的时候用到let const 总结下这两个区别 : 首先 let与const都是只在声明所在的块级作用域内有效. let声明的变量可以改变,值和类型都可以改变,没有限制.const ...

  10. javasript中var、let和const区别

    let和const都是es5,es6新版本的js语言规范出来的定义,在这以前定义一个变量只能用var.let和const都是为了弥补var的一些缺陷而新设计出来的. 简单来说是: let是修复了var ...

随机推荐

  1. Aws Dynamodb数据导出到S3

    本节将描写叙述怎样从一个或多个DynamoDB的表导出数据到S3的bucket中.在运行导出之前你须要提前创建好S3的bucket. 注意 假设你还没有使用过AWS Data Pipeline,在运行 ...

  2. gulp是用来干什么的?(概念)

    当我们在使用gulp的时候,gulp到底用来干什么呢? 编译 sass 合并优化压缩 css 校验压缩 js 优化图片 添加文件指纹(md5) 组件化头部底部(include html) 实时自动刷新 ...

  3. ffplay 播放m3u8 hls Failed to open segment of playlist 0

    用ffplay 播放m3u8文件 出现 Failed to open segment of playlist 0,Error when loading first segment 'test0.ts' ...

  4. shell脚本分析mysql慢查询日志(slow log)

    使用percona公司的pt-query-digest分析慢查询日志.分析.统计的结果的比較清晰 #!/bin/sh slowlog_path=/root/slow_query_log everysl ...

  5. Codeforces Round #267 (Div. 2) B. Fedor and New Game

    After you had helped George and Alex to move in the dorm, they went to help their friend Fedor play ...

  6. 关于global和$GLOBALS[]的一道经典面试题

    在不执行程序的情况下,你觉得的输出结果是什么? <?php $var1 = 1; $var2 = 2; function test(){ global $var1,$var2; $var2 = ...

  7. java gc小结

    java的内存结构: 1. 堆: java所有通过new新建的对象都是在堆上进行分配的; 根据不同的垃圾回收算法, 堆的结构也不相同, 如果采用的是分代垃圾回收, 那么堆就分为年轻代和年老代两部分. ...

  8. Google Chrome的快捷键

    1.Ctrl + N 打开一个新窗口           &&            Alt + F4    关闭当前窗口 2.Ctrl + T 打开一个新的标签页 && ...

  9. ORACLE 36进制和10进制,互相转换函数

    第一部分 --36转10进制 create or replace function f_36to10 (str varchar) return int  is returnValue int;   s ...

  10. 图像处理之图像增强项目---csdn去雾专栏1

    (一)高斯低通滤波去噪 高斯低通滤波器(Gaussian Low Pass Filter)是一类传递函数为高斯函数的线性平滑滤波器.又由于高斯函数是正态分布的密度函数.因此高斯低通滤波器对于去除服从正 ...