简谈const限定符
const修饰的数据类型是常量类型,常量类型的对象和变量在定义初始化后是不能被更新的。其实只用记住这一个概念,就可以明白const操作对象的方法。
1)定义const常量
最简单的:
const int a = 1;
a = 2; (错误:a为const常量,在初始化后不能再进行改变)
而且由于这个性质,如果在定义const int a时未进行初始化,会产生编译错误。因为在程序过程中不能对const常量进行修改。而由于const限定符的只读属性,可以避免对程序数据的误操作。
2)const与define
结论:const常量能节省空间,从而避免不必要的内存分配。
阐述原因:
#define A 5
const int B = 5;
int a = A;(在编译期间进行宏替换,为A分配内存)
int b = B;(为B分配内存,初次分配后不会再分配内存)
int aa = A;(A再次分配内存)
int bb = B;(B没有内存分配)
这里define给出的是一个立即数,所以define定义的常量在内存中有若干拷贝。但const常量在程序运行过程中只有一份拷贝。
编译器通常不会为普通const常量分配存储空间,而是将他们保存在符号表中,这就是使得它成为编译期间的常量,没有了存储和读内存的操作,使得效率提高。
3)指向const对象的指针
这里可以这样理解:const后面跟上int,表示const修饰的是int数据类型,即指针指向的内容是被const限定的,不能被修改。
比如:
int a = 1;
int b = 2;
const int *ptr = &a;
这里ptr是一个指向int型的const对象指针,const限定的是ptr指向的对象(int型数据),而不是ptr本身。
所以:
*ptr = 10(错误,不能直接更新ptr指向的内容)
ptr = &b(正确,因为ptr本身并不受const的限定,ptr作为指针可以指向其他内存单元)
补充一点:
普通的指针变量是能够作为左值被赋值修改的。
比如:
int *p = &a;(*p在程序运行过程中能被修改,从而影响到a中数据的改变)
所以:
一个普通指针变量作为左值时,其右值不能是一个const常量。
比如:
const int c = 3;
int *p = &c(错误。这个其实也很好理解,*p可以随意改,那c的值也会被随意改,不满足const的性质)
实际程序中,指向const的指针常常用作函数的形参。将形参定义为指向const的指针,以此来确保传递给函数的实际对象在函数中不会因为形参而被修改。
4)const指针
这个可以和3)对应理解:const后面跟上的指针变量,指针表示地址,则const指针限定了指针本身不能被更新,但指针指向的对象可以被更新(上述3)是限定数据不能更新,指针本身可以更新,正好相反)
比如:
int a = 1;
int b = 2;
int *const ptr = &a;(首先定义const指针指向a)
如果在程序运行过程中进行如下操作:
ptr = &b(错误:因为ptr是一个const指针常量,其在运行过程中不能被更新,即不能再指向其他的内存单元)
*ptr = 3;(正确:因为*ptr是指针指向的对象,其不受const的限定,能够被更新。更新后,a的值为3)
5)指向const对象的const指针
这个就是上述3)和4)的结合。const既限定了指针,又限定了指针指向的对象。
比如:
const int a = 1;
const int *const ptr = &a;
ptr一经初始化完毕后,就不能再指向其他内存单元,也不能被修改其指向内存单元(a的地址)的数据。但a自身可以被定义为普通int型,a可以进行更新。
6)关于typedef和const指针的一个误区
typedef能够用作类型替换,类似于#define。
一个误区是:
typedef string *pstring;
const pstring ptr;
上述ptr是一个什么类型。很容易想到的是:替换pstring,变为const string *ptr。则ptr是一个指向string类型的const对象,即const修饰string数据类型。
实际不然:
看const pstring ptr。在这个里面const修饰的是pstring,而pstring是一个string类型的指针。所以在程序运行过程中,const依然应该修饰一个指针,而不是一个string对象。正确的扩展应为:
strng const *ptr;
出现这个问题的原因在于:对于const常量的表示,string const s1和 const string s2,s1和s2都是等价的类型,即const限定符即可以放在类型前也可以放在类型后。
简谈const限定符的更多相关文章
- 浅谈const限定符
什么是const限定符? Const限定符是我们通常所说的常量限定符,被const修饰的对象具有常量性质,只能读,不能写. 为什么使用const限定符? 用const变量取代“魔数”,代码更容易理解和 ...
- C++const限定符
在C语言中我们使用#define宏定义的方式来处理符号常量.而在C++中有一种更好的处理符号常量的方法,那就是使用const关键字来修改变量声明和初始化.这种处理常量方式的好处不言而喻:如果程序在多处 ...
- const 限定符
1.定义const对象 const限定符把一个对象转换成一个常量 const int Bufsize = 512; 定义Bufsize 为常量并初始化为512.变量Bufsize仍然是一个左值,但是不 ...
- C++杂谈(一)const限定符与const指针
const限定符 c++有了新的const关键字,用来定义常变量,可以替C语言中的#define.关于const限定符,有以下需要注意: 1.创建后值不再改变 2.作用范围在文件内有效 3.添加ext ...
- C++ Primer 第二章 引用 指针 const限定符
1.引用: 为对象起了另外一个名字,引用类型引用另外一种类型,通过将声明符写成&d的形式来定义引用类型,其中d也就是声明的变量名(声明符就是变量名). PS:1.通过图片中编译所提示的报错信息 ...
- 指针和Const限定符
指针和Const限定符 1.指向const对象的指针 如果指针指向的是const对象,则不允许使用指针来改变其所指的const值.C++要求指向const对象的指针具有const特性. const d ...
- C++ const 限定符
C++ const 限定符 作用:把一个对象转换成一个常量 用法:const type name = value; 性质:1. 定义时必须初始化,定义后不能被修改.2. 类中的const成员变量必须通 ...
- const限定符的作用
const限定符的作用: 1.定义const常量:const可以将一个对象变成一个常量,不可被修改,所以定义的 时候必须进行初始 ...
- C++之const限定符
作者:tongqingliu 转载请注明出处: C++之const限定符 const初始化 const的特点: 用const加以限定的变量,无法改变. 由于const对象定义之后就无法改变,所以必须对 ...
随机推荐
- overflow:scroll 滚动条不显示
overflow:scroll 滚动条不显示 ::-webkit-scrollbar-thumb 可能因为 自定义的滚动条height比元素可展示内容大
- codeforces 981 C.Useful Decomposition
C. Useful Decomposition time limit per test 1 second memory limit per test 256 megabytes input stand ...
- [BZOJ4942] [NOI2017]整数
题目背景 在人类智慧的山巅,有着一台字长为1048576位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统,超级计算机 无法工作,而 ...
- [洛谷P3975][TJOI2015]弦论
题目大意:求一个字符串的第$k$大字串,$t$表示长得一样位置不同的字串是否算多个 题解:$SAM$,先求出每个位置可以到达多少个字串($Right$数组),然后在转移图上$DP$,若$t=1$,初始 ...
- [洛谷P3174][HAOI2009]毛毛虫
题目大意:给一棵树,求其中最大的“毛毛虫”,毛毛虫的定义是一条链上分出几条边 题解:把每个点的权值定义为它的度数减一,跑带权直径即可,最后答案加二 卡点:无 C++ Code: #include &l ...
- 一些实用的JQuery代码片段收集
本文将展示50个非常实用的JQuery代码片段,这些代码能够给你的JavaScript项目提供帮助.其中的一些代码段是从jQuery1.4.2才开始支持的做法,另一些则是真正有用的函数或方法,他们能够 ...
- Spring中@Resource与@Autowired、@Qualifier的用法与区别(转)
1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必 ...
- ACE_Message_Block功能简介
转载于:http://www.cnblogs.com/TianFang/archive/2006/12/30/607960.html ACE_Message_Block在Ace中用来表示消息的存放空间 ...
- 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...
- Django请求原理(二)
1,Web服务器(中间件)收到一个http请求 2,Django在URLconf里查找对应的视图(View)函数来处理http请求 3,视图函数调用相应的数据模型来存取数据.调用相应的模板向用户展示页 ...