c语言const总结

###前言:const意味着只读,凡修改了const不允许修改的东西,编译器报错

##const修饰指针
const修饰指针可以分为如下的四种情况:

int b = 5;
const int *a = &b;          //情况1
int const *a = &b;          //情况2
int* const a = &b;          //情况3
const int * const a = &b;   //情况4

而这四种情况,总结一下,其实只有两种情况:

  • const位于*的左侧,则const是修饰指针所指向的变量,即指针指向为常量
  • const位于*的右侧,const就是修饰指针本身,即指针本省是常量

本质:const在谁后面谁就不可修改,const在最前面则将其后移一位即可,二者等效

所以情况1和情况2是相同的,都是指针所指向的内容为常量(const放在变量声明符的位置无关),这种情况下不允许通过指针改变指针指向的内容

int b = 5;
const int *a = &b;
*a = 6;  //编译报错:错误:向只读位置‘*a’赋值

如果想要改变*a的值怎么办呢?有两种方法

//方法一:改变b的值
int b = 5;
const int *a = &b;
b = 6;
printf("%d", *a); //输出6


//方法二:让*a指向别处
int b = 5, c = 6;
const int *a = &b;
a = &c;
printf("%d", *a);//输出6

因为const int a是说指针指向的内容为常量,指针本身并不是常量,所以可以不初始化
const int
a; //正确

情况3为指针本身为常量,这种情况下不能对指针本身的值进行更改,即指针初始化指向哪里,在指针的整个生命中都将指向那个地址,不会改变。但是指针指向的地址的内容不是常量。所以我们应该可以理解,情况3中的指针定义时必须初始化

int b = 5, c = 6;
int *const a;  //在下面给a赋值时会出错:错误:向只读变量‘a’赋值
int *const a = &b;  //初始化
*a = 6;  //正确,允许修改值
printf("a new address is %d", a++); //编译出错:错误:令只读变量‘a’自增

至于情况4,就是情况1和情况3的合体了,既不允许修改指针的值,也不允许修改指针指向的值

##const修饰函数
如果以指针传递方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const修饰的同类型指针

##同样都可以定义常量,const与#define相比有什么不同?
const相对于#define的有点在于:

  • const常量有数据类型,而宏常量没有数据类型
  • 编译器可以对const常量进行类型安全检查,而对后者只进行字符替换,没有安全检查,而且在字符替换过程中可能会产生意想不到的错误(边际效应)