浪子归家|C语言的const关键词的三种用法

以const关键字声明的对象 , 其值不能通过赋值或递增、递减来修改 。 在ANSI兼容的编译器中 , 以下代码:
const int nochange;/* qualifies m as being constant */nochange = 12;/* not allowed*/编译器会报错 。 但是 , 可以初始化const变量 。 因此 , 下面的代码没问题:
const int nochange = 12;/* ok */该声明让nochange成为只读变量 。 初始化后 , 就不能再改变它的值 。 可以用const关键字创建不允许修改的数组:
const int days1[12] = {31,28,31,30,31,30,31,31,30,31,30,31};在指针和形参声明中使用const声明普通变量和数组时使用const关键字很简单 。 指针则复杂一些 , 因为要区分是限定指针本身为const还是限定指针指向的值为const 。 下面的声明:
const float * pf;/* pf points to a constant float value */创建的pf指向不能被改变的值 , 而pf本身的值可以改变 。 例如 , 可以设置该指针指向其他const值 。 相比之下 , 下面的声明:
float * const pt;/* pt is a const pointer */创建的指针pt本身的值不能更改 。 pt必须指向同一个地址 , 但是它所指向的值可以改变 。 下面的声明:
const float * const ptr;表明ptr既不能指向别处 , 它所指向的值也不能改变 。 还可以把const放在第3个位置:
float const * pfc;// same as const float * pfc;如注释所示 , 把const放在类型名之后、*之前 , 说明该指针不能用于改变它所指向的值 。 简而言之 , const放在*左侧任意位置 , 限定了指针指向的数据不能改变;const放在*的右侧 , 限定了指针本身不能改变 。
const关键字的常见用法是声明为函数形参的指针 。 例如 , 假设有一个函数要调用display()显示一个数组的内容 。 要把数组名作为实际参数传递给该函数 , 但是数组名是一个地址 。 该函数可能会更改主调函数中的数据 , 但是下面的原型保证了数据不会被更改:
void display(const int array[], int limit);在函数原型和函数头 , 形参声明const int array[]与const int * array相同 , 所以该声明表明不能更改array指向的数据 。
ANSI-C库遵循这种做法 。 如果一个指针仅用于给函数访问值 , 应将其声明为一个指向const限定类型的指针 。 如果要用指针更改主调函数中的数据 , 就不使用const关键字 。 例如 , ANSI C中的strcat()原型如下:
char *strcat(char * restrict s1, const char * restrict s2);回忆一下 , strcat()函数在第1个字符串的末尾添加第2个字符串的副本 。 这更改了第1个字符串 , 但是未更改第2个字符串 。 上面的声明体现了这一点 。
对全局数据使用const前面讲过 , 使用全局变量是一种冒险的方法 , 因为这样做暴露了数据 , 程序的任何部分都能更改数据 。 如果把数据设置为const , 就可避免这样的危险 , 因此用const限定符声明全局数据很合理 。 可以创建const变量、const数组和const结构(结构是一种复合数据类型 , 将在下一章介绍) 。
【浪子归家|C语言的const关键词的三种用法】然而 , 在文件间共享const数据要小心 。 可以采用两个策略 。 第一 , 遵循外部变量的常用规则 , 即在一个文件中使用定义式声明 , 在其他文件中使用引用式声明(用extern关键字):
/* file1.c -- defines some global constants */const double PI = 3.14159;const char * MONTHS[12] ={"January", "February", "March", "April", "May", "June", "July","August", "September", "October", "November", "December"};/* file2.c -- use global constants defined elsewhere */extern const double PI;extern const * MONTHS[];The second approach is to place the constants in an =include= file. Here, you must take the additional step of using the static external storage class:/* constant.h -- defines some global constants */static const double PI = 3.14159;static const char * MONTHS[12] ={"January", "February", "March", "April", "May", "June", "July","August", "September", "October", "November", "December"};/* file1.c -- use global constants defined elsewhere */#include "constant.h"/* file2.c -- use global constants defined elsewhere */#include "constant.h"


推荐阅读