由于const限定符既可以放在变量类型的前面,也可以放在变量类型的后面,所以对const的用法一直都不太明了,以下是查阅资料做了个简单总结:
1. 定义const对象
const最简单的使用就是将一个对象转换成一个常量,如下:
const int i = 10;
定义i为常量并初始化为10;此时i虽然是个左值,但其值不可修改;正因为常量在定义后不可修改,所以在定义时必须对其初始化。下面的形式与上面的等价:
int const i = 10;
const对象默认为文件的局部变量,如果想在其他文件中使用它,必须显示的指定它为extern:
//file1.c
extern const int i = 10; //定义
//file2.c
extern const int i; //申明
对于非const变量默认是extern的,所以在定义的时候不用显示的使用extern。
2. 指针的const限定
const和指针结合在一起时,有3种情况:指向const对象的指针、const指针和指向const对象的const指针。
2.1 指向const对象的指针
const int *pi;
这里pi是指向一个int类型的const对象的指针;这里const限定的是pi指向的的对象的类型,而不是限定pi这个变量;也就是说对pi所指向的地址单元进行写操作是不合法的,但对pi变量进行重新赋值是合法的,如:
*pi = 10;// erro: *pi是一个常量
- 将一个const对象的地址赋值给一个非const对象的指针的不合法的,如:
const int i = 10;
int *pi = &i; //erro
const int *pii = &i; //ok
- 可以将一个非const对象的地址赋值给一个const对象的指针,如:
int i = 10;
const int *pi = &i; //ok
这样赋值之后不能通过 *pi 去修改i的值,因为pi认为它指向的是一个const对象,所以不能对其修改;但是直接修改i (i = 1),或者通过别的方式修改是可以的。
在实际的程序中,指向const对象的指针常用作函数的形参,以确保实际的对象在函数中不会被修改。
2.2 const 指针
const指针和指向const对象的指针刚好相反,其规定它指向的对象是可以修改的,但是它自身却是常量不可修改,如:
int i = 10,j = 1;
int *const pi = &i; //常量必须在定义时初始化
*pi = 1; //ok
pi = &j //erro, pi是常量不可修改
所以指针自身是const类型并不能说明它指向的对象也是const类型不可修改;指针所指向的对象的值能否修改,完全取决于该对象的类型,如上面的i是非const的int型,所以可对其修改。
2.3 指向const对象的const指针
看了上面两个,再看这个就简单了,它规定指针和指针所指向的对象均不能修改:
const int i = 10;
const int *const pi = &i;//常量定义时要初始化
此时修改 *pt 和pt 都是不合法的。
3. const 和 typedef定义的类型
当用typedef定义一个指针类型的时候,再结合const,比较迷糊人:
typedef int *pi_t;
const pi_t pi;
此时看pi是什么类型的?很容易让人觉得是这种样子的:
const int *pi;//erro
即pi是一个指向const对象的指针;这是不对的,原因在于typedef并不像#define那样直接的展开,它定义的一种类型的别名;同前面的 const int i; 和 int const i;等价一样,这里const pi_t pi;和pi_t const pi;也是等价的,所以这里pi是一个const指针,指向int类型的变量。
关于const的其他的内容,后面学习中碰到了再行补充。