C/C++中const详解

来源:互联网 发布:学历 知乎 编辑:程序博客网 时间:2024/06/05 13:35

作为面试必不可少的一笔,const在大一时期给了我极大的困扰。
const原是应为constant的缩写,即“不变的,恒定的”。
在函数的定义中使用const,不仅可以保护数据,而且使函数可以使用声明为const的数组。
使用关键字const声明并初始化指针,可以保证指针不会指向别处

const穿插于常量与变量之间,使得原本清晰的界限在初学者眼中变得模糊,故今天要好好扒一扒const的困扰之处

  • 可用const创建符号常量(const double PI = 3.14;),其效果类似于宏定义(#define PI 3.14)
    • 然而,#define不利于代码的维护。当 #define 的符号与该符号的使用分属不同的文件时,若某一时刻因为符号的使用而导致编译报错,那么编译错误只会提到符号被 #define 后的值,而不会提到符号
    • 但是#define还没到了被抛弃的时候,因为防止头文件的重复包含和编译版本控制还是需要#define的

const与指针

  • 常量指针(char * const p;)
    • p的值不可修改
    • 不可用非常量指针指向常量(char *q=&p;就是一个错误语句)
    • 而常量指针对象可以不是常量(const int *m=c;)
    • 同时 ,不可以改变常量指针的值(*m=6;就是一个错误语句)
    • 而常量指针却可以重新赋值(m=&c)
  • 指向常量的指针(const char * p;/char const *p;)
    • 指向的常量值不可以修改
    • 指向常量的指针不可用于修改数值
  • 指针常量
int a = 0, b=1;  int *const p1 = &a;   //p1将一直指向a,不能再指向其他变量  a =10;          *p1 = 20;             //可以,我们改变的是p1指向的对象的值,p1仍然指向的是a  

const全局变量

与全局变量不同,const全局变量的作用于默认是“文件”,而若希望const全局变量被其他文件引用,在定义const全局变量时必须将其声明为exetern并初始化,然后在其引用的文件内也要在extern一次.
++extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。++

//----------------不能被外部文件使用---------------------  // file_1.cpp  const int val_1  = 8;  // file_2.cpp  extern const int val_1;    //会报错,因为相当于定义了一个新对象而没有初始化  //----------------可以被外部文件使用---------------------  // file_1.cpp  extern const int val_2  = 8;  // file_2.cpp  extern const int val_2;  

有关const的其他内容

  • 用const创建符号常量
    • const double PI = 3.14;
  • 指向常量的指针不能用于修改数值
int array[5]={1,2,3,4,5};const int *p = array;   //p指向数组开始处//第二行代码将p声明为指向const int的指针,如此一来就不可以使用p修改其所指向的数值*p = 6;  //不允许p[2]=7;  //不允许array[0] = 8    //允许,因为array非常量

但是,我们可以让p指向其他地址,如p++;就是使p指向array[1]
- 将常量或非常量数据的地址赋给指向常量的指针是合法的
- 反之则非法——-防止用新指针改变const数据
- 只有非常量数据的地址才可以赋给普通的指针

int rates[5]={1,2,3,4,5};const int locked[4]={6,7,8,9};int *p=rates;   //合法p=locked;       //非法p=&rates[4];    //合法
  • 像show_array()这样的函数可以接受普通数组和常量数组的名称作为实参,因为两种参数均可赋给指向常量的指针
  • 但像mult_array()这样的函数不能接受常量数组的名称作为实参

当然,const还有很多其他的用法

  • 您可以使用关键字const来声明并初始化指针,以保证指针不会指向别处。关键在于const的位置
int rates[5]={1,2,3,4,5};int *const p=rates;     //p指向数组开始处p=&rates[2];            //不允许*p=9;           //可以,更改rates[0]的值#这样的指针仍然可以用于修改数据,但他只能指向最初赋给它的地址
  • 同时,可以用两个const来创建指针。这个指针既不可以更改所指向的地址,亦不可以修改所指向的数据
int rates[5]={1,2,3,4,5};int *const p=rates;p=&rates[2];        //不允许*p=9;           //不允许