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 ...
随机推荐
- Storm系列之二——Guaranteeing Message Processing
Storm保证每跳离开spout的消息都会被完全处理.本文介绍Storm是怎么保证每条消息都被完全处理并且作为用户该怎么做才能从Storm的可靠性保证受益. 1.什么叫消息被完全处理? 一个tuple ...
- Intent官方教程(1)简介和作用
Intents An Intent is a messaging object you can use to request an action from another app component. ...
- U盘安装CentOS7的最终解决方案
转载自http://www.augsky.com/599.html 终于将CentOS7装上笔记本了,过程无比艰辛,因为我发现网上大家提到的所有U盘安装CentOS7时碰到的问题几乎都被我碰到了,像什 ...
- #utf-8与gbk转换 #bytes 和str 的转换
#!/user/bin/env python # -*- coding:utf-8 -*- temp = "连接" temp_unicode = temp.decode('utf- ...
- C#在泛型类中,通过表达式树构造lambda表达式
场景 最近对爬虫的数据库架构做调整,需要将数据迁移到MongoDB上去,需要重新实现一个针对MongoDB的Dao泛型类,好吧,动手开工,当实现删除操作的时候问题来了. 我们的删除操作定义如下:voi ...
- jquery之wrap(),wrap(),unwrap()方法详解
[注]wrap():为每个匹配元素外面添加指定的HTML结构, wrapAll(): 为所有匹配元素(作为一个整体)外面添加一个指定的HTML结构 原文地址:http://www.365mini.co ...
- jenkins远程命令执行利用工具
昨天看小飞侠写的py的jenkins的脚本,昨天晚上在微信里评论今天写一个JAVA的GUI的tools. 早上花了点时间写一下: code: package com.tools; import jav ...
- 参数(条件表)灵活配置GS01/GS02/GS03
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- [SAP ABAP开发技术总结]以二进制、字符模式下载文件
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 自定义CSS博客(转)
摘自:http://www.cnblogs.com/libaoheng/archive/2012/03/19/2406836.html 前 言 一个好的阅读体验,对技术博客来说,也许算是锦上添花.入 ...