C语言 - const 用法
定义
const 是 C 语言中的一个关键字,需要注意的是,const 关键字是把变量变为一个只读的变量(也就是不可以作为左值),绝对不是将这个变量变为常量。也就是说经过 const 修饰的变量成为只读的变量之后,那么这个变量就只能作为右值(只能赋值给别人),绝对不能成为左值(不能接收别人的赋值)。
而 C++ 则是将 const 修饰的常量变为一个真正的常量(变量的内容不可以被修改), 这一点的区别需要注意。当 const 修饰变量的时候,就将这个常量放在符号表里面,编译的过程中发现使用了变量,那么就从符号表里面的值进行替换。
经过 const 修饰的变量,在定 义的时候,就要进行初始化。
const int a = 10; // 正确
const int a; // 错误
const 关键字最有用的地方是用来限定函数的形参。
func(const char *ptr)
{
do_something;
}
这样 ,func 函数将不会修改实参指针所指的数据,但是其他的函数却可以修改它。因此,也可以通过是否有 const 修饰来反映该参数是输入还是输出。
实际上,const 被命名为 readonly 更为合适。
使用
指向 const 的指针
首先是一个指针,但是这个指针是指向一个 const 类型的指针。一般如下:
const int *p; // 一般使用这个
或者
int const *p;
这两种定义的效果是一样的,首先 p 是一个指针,p 所指向的内容(*p)是 const int 类型的,也就是所指向的内容是不能被修改的。
简而言之,p 这个地址可以随便指,但是地址里面保存的值却是不能改变。
const 指针
首先是一个指针,只不过这个指针是 const 类型的,也就是这个指针变量的地址,只能在初始化之后,就一直指向这个地址,地址所被保存的内容是可变的。
int * const p = 地址; // 因为P 所指向的地址是不能被修改的,所以必须被初始化
首先,这个 p 是一个指针,而这个指针是指向了 int 类型的 const 指针。只不过地址是被固定,不能改变,但是地址所保存的数值确实可变的,比如:
*p = 3;
指针和内容都是不可变的
顾名思义,就是指针的地址和地址所被保存的内容都是不可变的。
const int * const p = 地址值;
int const * const p = 地址值;
可见 p 是一个指针,但是这个指针,前面有 const 进行修饰,所以,这个 p 指针就是一个指针常量,所以 p 的地址就被固定了,只能在初始化时赋值。 而对于 *p
而言,前面又有 const 进行修饰,所以 *p
就是一个常量了,也就是 p 指向地址,地址上保存的数据是一个常量,不能被改变的。
理解记忆
其实就看 const 的位置。如果 const 在指针的星号之前,那么就是指向 const 的指针,也就是 *p 的内容是常量,不能被改变。如果 const 在星号之后,那么就是 const 的指针,也就是这个指针在初始化之后就一直指向这个地址,但是这个地址的内容是可以改变的。
示例 | 星号之前 | 星号之后 | 说明 |
---|---|---|---|
const char * ptr | const char | ptr | 指针可变,但是所指的内容必须是只读的。 |
char const * ptr | char const | ptr | 同上。 |
char * const ptr | char | const ptr | 指针初始化后不可变,但该地址的内容可变。 |
const char * const ptr | const char | const ptr | 指针初始化后不可变,所指地址的内容也不可变。 |
const 与 define 区别
- const 是由编译器进行处理,执行类型检查和作用域的检查;
- define 是由预处理器进行处理,只做简单的文本替换工作而已。