一、const作用
const的作用就是限定变量为只读,节省空间,避免不必要的内存分配,同时提高效率。
编译器通常不为普通变量分配存储空间,而是将它们保存再符号表中,这使得它成为一个编译期间的值,没有了存储于读内存的操作,使得效率也很高。
从汇编的角度看,const定义只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以const定义的只读变量再程序运行过程中只有一份备份(因为它是全局的只读变量,存在在静态区),而#define定义的宏常量在内存中有若干个备份,#define宏是在预编译阶段进行替换,而const修饰的只读变量是在编译的时候确定其值。#define宏没有类型,而const修饰的只读变量具有特定的类型。
const int J = 20; //此时并未将J放入内存中
#define K 10 //宏常量
int a = J; //此时为J分配内存,以后不再分配
int b = K; //预编译期间进行宏替换,分配内存
int c= J; //没有内存分配
int d = K; //再进行宏替换,又一次分配内存
二、如何使用const修饰
1.修饰一般变量
int const a =2; 或者 const int a = 2;
a=3; //编译器将提示error: assignment of read-only variable ‘a’
2.修饰数组
const int a[2]={1,2} ; 或者 int const a[5]={1,2};
a[1] = 5; //编译器将提示error: assignment of read-only location ‘a[1]
3.修饰指针
3.1.指向的对象只读,指针的指向可变。
int i = 1;
int j = 2 ;
const int *a = &i; 或者 int const *a = &i;
a = &j; // 编译通过
*a = 10;//编译错误
3.2.指向的对象可变,指针的指向不可变。
int i = 1;
int j = 2 ;
int *const a = &i;
a = &j; // 编译错误
*a = 10;//编译通过
3.3.指针不可改变指向,指向的内容也不可变
int i = 1;
int j = 2 ;
const int *const a;
a = &j; // 编译错误
*a = 10;//编译错误
4.修饰函数的参数
void const_test(const int *a);
5.修饰函数的返回值
const int const_test();
以上一经const,那么变量的值将本能改变。
三、使用const特别注意
#include <stdio.h>
int main(void)
{
const int a = 10;
int *p = &a;
*p = 20;
printf("%d\n",a);
}
运行结果a:20。
但是编译的时候有告警提示:
warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
int *p = &a;
也就是说我们这样做,会使得a丢弃了const修饰。这个要特别注意。
四、总结
对于不想被修改的参数或者变量,应该用const修饰。const修饰的变量只能赋值一次。
不要忽略编译器的警告。(三、特别注意中,当一个普通指针p指向变量a时,改写指针指向的内容,变量a已经丢失了const。从侧面反映const修饰的变量不是真正意义上的只读,我们写代码应该避免这种情况)
参考文献:
《c语言深度剖析》陈正冲编著