const
类型限定符以const类型关键字声明的对象,其值不能通过赋值来递增,递减来修改。
以下代码:
const int a = 12;//限定a的值不能修改
a = 12;//不可以
编译器会报错,但是可以初始化变量,因此下面的代码没问题:
const int a = 12;//没问题
该声明让a
成为只读变量。初始化后,就不能改变它的值。
可以用const
关键字创建不允许修改的数组:
const int days[] = {
1,2,3,4};
const
声明普通变量和数组时使用const
关键字很简单。指针则复杂一点,因为要区分是限定指针本身为const
还是限定指向的值为const
。下面的声明:
const float *pf;//pf指向一个float类型的const值
创建了pf
指向的值不能被改变,而pf
本身的值可以改变。例如,可以设置该指针指向其它const
值,相比之下,下面的声明:
float * const pt;//pt是一个const指针
创建的指针pt
本身不能改变,pt
必须指向同一地址,但是它所指向的值可以改变。下面的声明:
const * float * const ptr;
表明ptr
既不能指向别处,它所指向的值也不能改变。
还可以把const
放在第三个位置:
float const *pfc;//与const float *pfc等价
总结:
把const放在类型名后,*之前,说明该指针不能改变它所指向的值。
简而言之,const放在*左侧的任意位置,限定了指针指向的数据不能改变;
const放在*的右侧,限定了指针本身不能改变
const
关键字的常见用法是声明为函数形参的指针。例如,假设有一个函数要调用display()
显示一个数组的内容。要把数组名作为实际参数传递给该函数,但是数组名是一个地址。该函数可能会更改主调函数的数据,但是下面的原型保证了数据不会被修改:
void display(const int arry [],int limit);
顺带一提,当数组名作为实参传递时,形参可以是以下几种形式:
一维数组:
int arry[]
与下面等价:
int *arry
二维数组:
int arry[][colums];
与下面等价:
int *(arry) [colums]
因为一个中括号表明是一个指针。
const
使用全局变量是一种冒险的方法,因为这样做暴露了数据,程序的任何部分都能更改数据,但如果把数据设置为const
,就可以避免这样的危险,因此使用const
限定符声明全局变量很合理,然而,在文件间共享const
要小心,可以采用两个策略:
/*file1.c---定义了一些外部const变量*/
const double PI = 3.1415926;
const char *MONTHS [12] = {
1,2,3,4,5,6,7,8,9,10,11,12};
/*file2.c---使用定义在别处的外部const变量*/
extern const double PI;
extern const char *MONTHS[];
const
变量放在另一个头文件中,然后在其它头文件中包含该头文件:/*constant.h--定义了一些外部const变量*/
static const double PI = 3.1415926;
static const char * MONTHS = {
1,2,3,4,5,6,7,8,9,10,11,12};
/*file1.c---使用定义在别处的外部const变量*/
#include "constant.h"
/*file2.c---使用定义在别处的外部const变量*/
#include "constant.h"
这种方案必须在头文件中使用关键字static
声明全局变量。如果去掉static
,那么在file1.c
和file2.c
中包含constant.h
将导致每个文件中都有一个相同标识符的定义式声明,实际上,这种方法为每个文件提供了一个单独的数据副本,每个副本只对该文件可见,所以无法用这些数据与其它文件通讯,不过他们是完全相同的。