C/C++中Static和Const的作用
一、const的作用 :
const关键字可以用于修饰变量,参数,返回值,甚至函数体。const可以提高程序的健壮性,减少程序出错。
(一)const用于定义常量和修饰变量
当定义某个变量时,用const修饰,则该变量就变为常量,其值定义后就不能再改变了,如:const int x=1;常量x的值不能再改变了。
(1)const 修饰变量,表示该变量不能被修改。
1、const char *p 表示指针p指向的内容不能改变
2、char * const p,就是将P声明为常指针,它的地址不能改变。
3、这种const指针是前两种的结合,使得指向的内容和地址都不能发生变化.
(二)const修饰函数形式参数
(1)传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)
(2)参数指针所指的内容为常量不可变
(3)参数指针本身为常量不可变(也无意义,因为char* Var也是形参)
(4)参数为引用,为了增加效率同时防止修改。修饰引用参数时:
当输入参数为用户自定义类型和抽象数据类型时,将“值传递”改为“const&传递”可以提高效率,可以比较如下的代码:
第一个函数效率较低,函数体内产生A类型的临时对象用于“值传递”参数a,而临时对象的构造、复制、析构过程都需要消耗资源和时间的,但使用第二种方式,按“引用传递”不需要产生临时对象,省了临时对象的构造、复制、析构的过程,因此效率较高。而之所以用const修饰a,是为了保证引用a不被修改。
(二)const修饰函数返回值
(1)函数按const指针 返回 ,表示该指针不能被改动,只能把该指针赋给const修饰的同类型指针变量。
(2)函数按值返回,函数会把返回值赋给外部临时变量,用const无意义!不管是内部还是非内部数据类型。
(3)函数采用引用方式返回的场合不多,只出现在类的赋值函数中,目的是为了实现链式表达。
(三)const修饰类的成员函数(函数定义体):
通常,任何不需要修改数据成员的函数都应该声明为const类型,这样,如果const成员函数修改了数据成员或者调用了其他函数修改数据成员,编译器都将报错!
编译器输出错误信息:error C2166: l-value specifies const object。
例题: 给定声明 const char * const * pp; 下列操作或说明正确的是?
A.pp++
B.(*pp)++
C.(**pp) = \\c\\;
D.以上都不对
正确答案: A
【详细解释
】:const 限定一个对象为只读属性。
分析的原则:
(1)const char p //限定变量p为只读。这样如p=2这样的赋值操作就是错误的。
(2)const char *p //p为一个指向char类型的指针,const只限定p指向的对象为只读。这样,p=&a或 p++等操作都是合法的,但如*p=4这样的操作就错了,因为企图改写这个已经被限定为只读属性的对象。 (const 限定*p,即限定p指向的内容)
(3)char *const p 限定此指针为只读,这样p=&a或 p++等操作都是不合法的。而*p=3这样的操作合法,因为并没有限定其最终对象为只读。 (const直接与p结合,因此这里只限定了指针本身p,但内容可以修改 )
(4)const char *const p 两者皆限定为只读,不能改写。 (结合方向:const char *(const p))
有了以上的对比,再来看二级指针问题:
(1)const char **p p为一个指向指针的指针,const限定其最终对象为只读,显然这最终对象也是为char类型的变量。故像**p=3这样的赋值是错误的,而像*p=? p++这样的操作合法。
(2)const char * const *p 限定最终对象和 p指向的指针为只读。这样 *p=?的操作也是错的。
(3)const char * const * const p 全部限定为只读,都不可以改写。