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\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区别的更多相关文章
- 2018/03/08 每日一学PHP 之 常量defind 和 const区别
常量defind 和 const区别 什么是常量? 如字面理解的,在脚本执行期间不可改变的的量. 定义一个常量应该注意的事项? 1:常量默认大小写敏感,错误的大小写不会被识别为常量. 2:常量只能是标 ...
- let、var、const区别(表格比较)
let.var.const区别(表格比较): 区别项 let var const 作用域 块级作用域 全局作用域或函数作用域 块级作用域 是否有变量提升 无 有 无 是否可重复声明 不可 可以 不可 ...
- (转)全局变量、extern/static/const区别与联系
全局变量.extern/static/const区别与联系 编译单元(模块): 在IDE开发工具大行其道的今天,对于编译的一些概念很多人已经不再清楚了,很多程序员最怕的就是处理连接错误(LIN ...
- var、let和const区别
var.let和const区别 变量提升问题 var声明的变量存在变量提升,而let与const声明的变量不存在变量提升,但存在暂时性死区 即在预编译阶段,js引擎扫描代码时,遇到变量声明,会把var ...
- readonly和const区别
常量和只读变量的区别 const string name="Xuj"; readonly string name; 1.常量是不可改变的,只读变量只能在构造方法中才能改变其值. 2 ...
- var、let 及 const 区别
var console.log(a) // undefined var a = 1 从上述代码中我们可以发现,虽然变量还没有被声明,但是我们却可以使用这个未被声明的变量,这种情况就叫做提升,并且提升的 ...
- PHP中的Define和Const区别
我们经常把不经常变的值定义成常量,常量一般用全部大写来表示,前面不加美元符号,那么define和const有什么区别呢? 常量是一个简单的标识符.在脚本执行期间该值不能改变(除了所谓的魔术常量,他们其 ...
- C# readonly与const区别
静态常量:是指编译器在编译时候会对常量进行解析,并将常量的值替换成初始化的那个值. 动态常量的值则是在运行的那一刻才获得的,编译器编译期间将其标示为只读常量,而不用常量的值代替,这样动态常量不必在声明 ...
- let const区别!
这次做项目在申明变量的时候用到let const 总结下这两个区别 : 首先 let与const都是只在声明所在的块级作用域内有效. let声明的变量可以改变,值和类型都可以改变,没有限制.const ...
- javasript中var、let和const区别
let和const都是es5,es6新版本的js语言规范出来的定义,在这以前定义一个变量只能用var.let和const都是为了弥补var的一些缺陷而新设计出来的. 简单来说是: let是修复了var ...
随机推荐
- Mybatis分页插件-PageHelper的使用
转载:http://blog.csdn.net/u012728960/article/details/50791343 Mybatis分页插件-PageHelper的使用 怎样配置mybatis这里就 ...
- 通过jstl判断是否给value 赋值
<input type="text" name="saler.password" id="password" value=" ...
- uva 1378 - A Funny Stone Game sg博弈
题意:David 玩一个石子游戏. 游戏中,有n堆石子,被编号为0..n-1.两名玩家轮流取石子. 每一轮游戏.每名玩家选取3堆石子i,j,k(i<j,j<=k,且至少有一枚石子在第i堆石 ...
- iOS 私有库的使用
最近项目说要用私有库 主要过程 创建两个库: 索引库 组件库 组件库 用git操作 比如更新代码 push 打tag等 索引库 存放组件的描述信息 也就是 .spec文件 这个文件和 ...
- 通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? .Net Web开发技术栈
通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? 什么是.NET?什么是.NET Framework?本文将从上往下,循序渐进的介绍一系列相关.NET的概念 ...
- 线程安全使用(四) [.NET] 简单接入微信公众号开发:实现自动回复 [C#]C#中字符串的操作 自行实现比dotcore/dotnet更方便更高性能的对象二进制序列化 自已动手做高性能消息队列 自行实现高性能MVC WebAPI 面试题随笔 字符串反转
线程安全使用(四) 这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来. 这里主要讲解下CancellationT ...
- Linux(centos 6.5) 调用java脚本以及定时运行的脚本实例及配置文件具体解释
Linux(centos 6.5) 调用java脚本以及定时运行的脚本实例 一.调用java程序脚本(默认已经搭建好了Java环境) 1.jdk 安装路径 /usr/jdk/jdk1.7/-- 2.j ...
- 关于arr.map()问题
最近看map实现原理, Array.prototype._map = function(fn, context) { console.log(fn, context) var temp = []; i ...
- C语言,简单计算器【上】
由于工作需要最近在研究PHP扩展,无可避免的涉及到了C语言.从出了学校以后C语言在实际工作中还没有用到过,所以必须要先进行一点复习工作.个人认为对于熟悉一样东西说最好的方法是上手实践.于是便想起了当时 ...
- EEPlat 主子表和对象引用配置实例
本次实例以常见的订单维护,来介绍下平台内类似主子表结构的配置方法. 订单包含订单头和订单明细.订单头包含简单信息:订单编号.订单状态.客户. 交付日期.订单日期.备注等.订单明细包含:订单产品.定单数 ...