C语言中const关键字用法详解

一、const定义

const——用于限定一个变量为只读。在C语言中,用const类型限定符生命的式变量,不是常量,并且能消除存储操作(在存储时只存一次)。
声明如下:

const int MONTHS=12;//MONTHS在程序中只读不可更改,值为12

二、const用法

1、说明值常量

值常量的说明一般放在头文件或者文件的开始部分,也可以放在类中进行说明

(1)说明符号常量,表明符号代表的是一个常量,语法格式:

<类型>const<常量名>=<表达式>,<常量名>=<表达式>……

double const PI=3.14; 
const double PI=3.14;

(2)说明数组常量,语法格式:

<类型>const<数组名>[大小]={初值表}const<类型> <数组名>[大小]={初值表}double const test[3]={1,2,3};
const double test[3]={1,2,3};

2、const和指针

Const和指针的三种经典组合

(1) 常量指针——const int *p;
指针在指向有一个常量后,不能通过指针修改这个常量,但是可以指向一个新的常量,例如:

const char *pc=”ABCD”;//指针PC所指向的地址可以变,但是所指向的那个值不能变
Pc[3]=’a’;//不合法,企图修改原来指向的常量
Pc=“WERT”;//合法指向另外一个常量

const *的例子:(地址可变,地址对应的值不可变)

int b = 3, c = 5;
int const *a = &b;
cout<<*a<<endl;     // 3
//*a = 6;       	不能对*a进行修改,因为其值为const不可变
b = 6;          	//但是可以用b来修改
cout<<*a<<endl;     // 6

(2) 指针常量——char *const pc=’a’;
指针常量是指指针本身是个常量,不能在指向其他的地址。
要把指针变量中的值(也就是地址)声明为常量,采用以下语法:
<类型> *const <指针名> [=<初值>;]
这样定义的指针变量中存放的指针是个常量,称为常指针。定义后,该指针指向固定的内存单元,不能再指向其他内存单元,通过它可以修改所指单元里存放的内容。例如:

char *const pc=”ABCD”;//PC的值其实是一个地址,这就表示PC所保存的地址是不可以变的,但是这个地址对应的值是可以变的
Pc[3]=’a’;	//合法,指针指向的对象可以修改
Pc=”QWER”;	//不可以,指针的指向不可以修改

*const的例子:(地址不可变,地址对应的值可变)

int b = 3, c = 5;
int *const a = &b;
//a = &c;		这一句是错的,因为a所指向的地址是不能变的
cout<<*a<<endl;     // 3
b = 6;
cout<<*a<<endl;     // 6

(3) 指向常量的常指针——const char *const pc=’a’
指针变量中存放的指针本身和指针所指向的对象都是不可以改变的。

例如:

const char *const pc=”ASDF”;
Pc[3]=’a’;	//不合法,不能改变指针所指对象的值
Pc=”QWER”;	//不合法,不能改变指针的指向

3、const说明函数参数

const说明函数参数——用const修饰函数参数意味着传过来的实参在函数中是不能被修改的。一般情况下不需要,但是在用指针和引用传值的场合,为避免实参被修改,就用const修饰,更安全。

(1)防止修改指针指向的内容

void StringCopy(char *strDestination, const char *strSource);

其中 strSource 是输入参数,strDestination 是输出参数。给 strSource 加上 const 修饰后,如果函数体内的语句试图改动 strSource 的内容,编译器将指出错误。
(2)防止修改指针指向的地址

void swap ( int * const p1 , int * const p2 )

指针p1和指针p2指向的地址都不能修改。
(3)以上两种的结合

4、const说明函数返回值

const说明函数返回值——修饰函数的返回值,意味着该返回值不能被修改。如果传值并返回地址,const将保证该地址上的内容不会被改变。这就意味着该函数不能作为左值使用,在这种情况下,const通常也是与引用和指针一起使用的,该返回值只能被赋给加const 修饰的同类型指针。

const char *str = GetString();

5、修饰全局变量

全局变量的作用域是整个文件,我们应该尽量避免使用全局变量,因为一旦有一个函数改变了全局变量的值,它也会影响到其他引用这个变量的函数,导致除了bug后很难发现,如果一定要用全局变量,我们应该尽量的使用const修饰符进行修饰,这样防止不必要的人为修改,使用的方法与局部变量是相同的。

三、使用const的优点

(1)可以定义const常量,具有不可变性。
(2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。
(3)可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。 同宏定义一样,可以做到不变则已,一变都变!
(4)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。 还是上面的例子,如果在函数体内修改了i,编译器就会报错;
(5) 可以节省空间,避免不必要的内存分配。 例如:

#define PI 3.14159 //常量宏 
const double Pi=3.14159; //此时并未将Pi放入ROM中 ...... 
double i=Pi; //此时为Pi分配内存,以后不再分配! 
double I=PI; //编译期间进行宏替换,分配内存 
double j=Pi; //没有内存分配 
double J=PI; //再进行宏替换,又一次分配内存! 

const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干份拷贝。
(6) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

参考资料:
http://blog.csdn.net/xingjiarong/article/details/47282255
《C Primer Plus(第六版)中文版》
《C和指针》

你可能感兴趣的:(C语言,c语言,c++)