参考C Primer Plus(第6版)
目录
以const关键字声明的对象,其值不能通过复制或递增、递减来修改。
以下代码 编译器会报错。
int main()
{
const int value;
value = 10;
return 0;
}
但是可以初始化const变量。
int main()
{
const int value = 10;
return 0;
}
如用const关键字创建不允许修改的数组。
int main()
{
const int week[7]= {1, 2, 3, 4, 5, 6, 7};
return 0;
}
在指针声明中使用const
指针中要区分是限定指针本身为const还是限定指针指向的值为const。
限定指针指向的值为const
创建了pf指向的值不能改变,而pf本身的值可以改变。例如可以设置该指针指向其他const值。(指向的其他值不是const好像也不报错)(因为pf指向的值为const,pf本身不是const,所以可以不初始化pf)
int main()
{
const float *pf; /* pf指向一个float类型的const值 */
return 0;
}
限定指针本身为const
创建的指针pt本身的值不能更改。pt必须指向同一个地址,但是它所指向的值可以改变(因为pt本身为const,所以必须初始化,否则编译器报错)
int main()
{
float value = 10;
float *const pt = &value; /* pt是一个const指针 */
return 0;
}
扩展
int main()
{
float value = 10;
const float * const ptr = &value; /* ptr既不能指向别处,它所指向的值也不能改变 */
return 0;
}
把const放在类型名之后、*之前,说明该指针不能用于改变它所指向的值。简而言之,const放在*左侧任意位置,限定了指针指向的数据不能改变;const放在*的右侧,限定了指针本身不能改变。
float const *pf;与const float *pf;相同
在形参声明中使用const
const的常见用法是声明为函数形参的指针。例如,假设有一个函数要调用display()显示一个数组内容。要把数组名作为实际参数传递给该函数,但是数组名是一个地址。该函数可能会更改主调函数中的数据,但是下面的原型保证了数据不会被更改:
void display(const int array[], int limit);
形参声明中const int array[ ],与const int *array相同,所以该声明表示不能更改array指向的数据。
如果要用指针更改主调函数中的数据,就不使用const关键字。例如strcat()原型如下:
char *strcpy(char *restrict, const char *restrict);
对全局数据使用const
在文件中共享const数据可以采用两个策略。
第一,遵循外部变量的常用规则,即在一个文件中使用定义式声明,在其他文件中使用引用式说明(用extern关键字)。
/* file1.c--定义了一些外部const变量 */
const double PI = 3.14159;
const char *MONTHS[12] = {"January", "February", "March", "April", "May",
"June", "July", "August","September", "October",
"November", "December"};
/* file2.c--使用定义在别处的外部const变量 */
extern const double PI;
extern const char *MONTHS[];
另一种方案是,把const变量放在一个头文件中,然后在其他文件中包含该头文件:
/* constant.h--定义了一些外部const变量 */
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--使用定义在别处的外部const变量 */
#include "constant.h"
/* file2.c--使用定义在别处的外部const变量 */
#include "constant.h"
这种方案必须在头文件中用关键字static声明全局const变量。如果去掉static,那么在 file1.c和 file2.c中包含 constant.h将导致每个文件中都有一个相同标识符的定义式声明,C标准不允许这样做(然而,有些编译器允许)。实际上,这种方案相当于给每个文件提供了一个单独的数据副本。由于每个副本只对该文件可见,所以无法用这些数据和其他文件通信。不过没关系,它们都是完全相同(每个文件都包含相同的头文件)的const数据(声明时使用了 const 关键字),这不是问题。
头文件方案的好处是,方便你偷懒,不用惦记着在一个文件中使用定义式声明,在其他文件中使用引用式声明。所有的文件都只需包含同一个头文件即可。但它的缺点是,数据是重复的。对于前面的例子而言,这不算什么问题,但是如果 const 数据包含庞大的数组,就不能视而不见了。