const 不再迷茫
博客地址:http://blog.csdn.net/jiangxinnju
github:https://github.com/jiangxincode
首先说明一下const在C和C++中的主要用法,被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。它可以修饰变量、函数的参数、返回值,甚至函数的定义体。
const修饰变量
const修饰变量通常用于定义符号常量。我们过去一般使用宏定义的方式定义符号常量,比如:
#define PI3.1415926
其实我们也可以使用const方式定义符号常量,下面的语句与上面宏定义的方式达到的效果相似。
const double PI3.1415926
那两者有什么区别呢?在使用宏定义的方式时,首先在预处理过程中将源程序中的常量名全部替换成对应的字面常量,然后对替换过的源程序进行编译。相比较之下const方式不涉及预处理过程,它只在编译工程中起作用。因为宏定义方式定义的符号常量没有类型,所以不能进行严格的类型检查,而const则可以,并且有些调试工具可以对const常量进行调试,而不能对宏常量进行调试。但这也不是说宏常量就比const常量差,比如你能够利用const常量实现下面的宏定义功能么?
#ifndefJIANGXIN_H
#defineJIANGXIN_H
#endef
而且由于历史原因,实际上使用宏常量的情况远远大于const常量,特别是在纯C编程环境中。不过在C++编程环境中,我还是推荐你使用const,因为这更加安全。同时时刻记住一句话,const常量作用与编译期,宏常量作用于预编译期,当你遇到一些令人迷惑的问题时想想这句话,或许能够有所收获。
现在举几个例子:
const int m = 0; //其实我们通常把const符号常量叫做const常量,以便和宏常量区分
typedef char * pStr; //新的类型pStr,代表一个指向char的指针类型。
char string[4] = "abc";
const char *p1 = string;//p1是一个指针,指向一个const
char类型
p1++; //正确,p1本身不是常量,它指向一个常量
const pStr p2 = string; //p2是一个常量指针,这个指针指向一个char类型变量
p2++; //错误,p2是一个常量指针
char *const p3 = string; //p3同p2相同,是一个常量指针
char const* p4 = string; //p4同p1相同,是一个指向const
char的指针,只能用于C中,在C++中只能使用const
char *p4 = string;
const修饰函数形参
函数形参主要包括传值型参数,传指针型参数,传引用型参数。
对于传指针和传引用型参数,如果我们怕在该函数中错误的改变实参的值,一般都会加上const来修饰形参。
对于传值型参数,我们一般不会使用const修饰,因为完全没有必要,你是不是用const,都不能改变实参的值,因为传值型形参是在栈中分配的,函数调用之后一定会销毁。例如:void
Fun(int n)和void Fun(const int n)没有任何区别,而且还是代码更加晦涩,所以不推荐。但是有一种情况需要考虑,如果你需要传递一个比较复杂的类类型,但是你又不需要改变该类的对象,这时你可以将传值改为传指针或者引用,同时用const修饰。这样的话就避免了构造临时对象的开销。比如加入A是一个很复杂的类类型,这是使用void
Fun(const A &a)要比void Fun(A a)效率更高。
用const修饰函数的返回值
函数的返回值与形参类似,也包括返回值类型,返回指针类型,返回引用类型。
对于返回值类型为指针或者引用的情况,如果我们不希望其被修改,可以使用const对返回值进行限定。此时该返回值const修饰的同类型const指针(返回值为指针)或者同类型的const变量(返回值为引用,且该值为基本类型或者定义了拷贝构造函数、拷贝赋值运算符的类型)。如对于:
const char * Fun(void);
如下语句将出现编译错误:
char *str = Fun();//cannotconvert from 'const char *' to 'char *';
正确的用法是:
const char *str= Fun();
如果返回值类型为值类型,由于函数会把返回值复制到外部函数的存储单元中,加const修饰没有任何价值,所以不要把函数int
Fun(void) 写成const int Fun(void)。但是在某些情况下将值类型改为引用类型或者指针类型可以提高效率,可用不用const就看你要不要改变它们了。
const修饰成员函数
const关键字可以放在函数声明的尾部,表示该类成员不修改对象。注意const只能修饰类的成员函数,不能修饰普通函数,无论是C还是C++。
const 不再迷茫的更多相关文章
- let和const的区别
es6语法中新增了 let和const 不再只是有var 1. let的用法 let是用来声明变量的,它和var的用法差不多,但是let所声明的变量只在它的代码块内有效,像for循环里用let会更好点 ...
- winform总结2> Action<> ,Action,func<>,委托相关的理解
1,他们是什么: Action 封装一个方法,该方法不具有参数并且不返回值. Action<> 封装一个方法,该方法具有最多16个参数并且不返回值. func<> 封装一个具有 ...
- 游记——noip2016
2016.11.18 (day 0) 呆在家. 悠闲地呆在家.. 明后天可能出现的错误: 1)没打freopen.打了ctime: 2)对拍程序忘记怎么写了...忘记随机化种子怎么写了: 3)不知道厕 ...
- 【转】一名大学生的PHP进阶之路
我是一名河南某职业学院的学生,比较喜欢PHP开发 的 工作,自己也曾经自学过php,but如果没有老师教还真是难以坚持啊,在这里给大家说一下寒假在麦子的学习感受,首先说麦子每一堂课程都给了特别详细的 ...
- [Android Pro] Android Support 包里究竟有什么
reference to : http://www.2cto.com/kf/201411/350928.html 随着 Android 5.0 Lollipop 的发布,Android 又为我们提供了 ...
- 报名|「OneAPM x DaoCloud」技术公开课:Docker性能监控!
如今,越来越多的公司开始 Docker 了,「三分之二的公司在尝试了 Docker 后最终使用了它」,也就是说 Docker 的转化率达到了 67%,同时转化时长也控制在 60 天内. 既然 Dock ...
- [Effective Modern C++] Item 1. Understand template type deduction - 了解模板类型推断
条款一 了解模板类型推断 基本情况 首先定义函数模板和函数调用的形式如下,在编译期间,编译器推断T和ParamType的类型,两者基本不相同,因为ParamType常常包含const.引用等修饰符 t ...
- EC读书笔记系列之14:条款26、27、28、29、30、31
条款26 尽可能延后变量定义式的出现时间(Lazy evaluation) 记住: ★尽可能延后变量定义式的出现.这样做可增加程序的清晰度并改善程序效率 ----------------------- ...
- 如何让HTML的编写更具结构性
首先声明,我不是搞技术的,很多词汇写的不够专业,但作为一枚菜鸟,我站在菜鸟的角度,来讲述我在学习技术的过程中所遇到的问题,和解决的方案. 入门HTML还算简单,无非是先写好固定的三对开闭标签结构:ht ...
随机推荐
- Java发送邮件,所遇到的常见需求
明天要做关于发送邮件的接口,虽然我之前已用Java Mail做过许多关于邮件的发送.但同事说有点难点,虽我还不知难点在哪,还是要复习下.凡事预则立,不预则废嘛~ 所需的包: Java Mail : 目 ...
- SqlSever基础 cast 将getdate返回的时间转换成字符串
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
- getbyclass
其实以前我偷偷学习正则表达式的时候,写过一个getbyclass的方法,最近翻了翻到处都是错,或者好多重复的,没有用的 代码,于是显得没事我就把这个精简了一下,其实这个方法现在我觉得也是有问题的,问题 ...
- Cheatsheet: 2013 09.10 ~ 09.21
.NET Lucene.Net – Custom Synonym Analyzer Using FiddlerCore to Capture Streaming Audio Immutable col ...
- 0(Mark)(随时添加) ubuntu的一些 终端 命令整理
MARK 1 查看cpu信息cat /proc/cpiinfo 2 查看ubuntu版本:cat /etc/issue 3 查看系统是32位还是64位方法1:#查看long的位数,返回32或64 ge ...
- Maven开发基础总结(Maven自启动,Maven打war包,Maven热部署)
学习内容: 1.不依赖外部Tomcat,自己启动方式部署 2.Maven打war包,远程部署到centOS 3.Maven热部署(不关闭Tomcat部署应用) 做maven开发前提: 1.编码UT ...
- 数据引用Data References
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- [Effective Java]第九章 异常
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- C library function - tmpfile()
Description The C library function FILE *tmpfile(void) creates a temporary file in binary update mod ...
- Zeller公式推导及C#代码示例(待完善)
Zeller公式用于计算给定日期是星期几. 该方法可以用数论知识进行证明. 假设给定日期Date为Year-Month-Day,求解该日期是星期几的问题实际上就是以之前某个确定星期几的日期作为参考点, ...