Bootstrap

C语言const浅析

 参考C Primer Plus(第6版)

目录

 在指针声明中使用const

限定指针指向的值为const

限定指针本身为const 

扩展

 在形参声明中使用const

对全局数据使用const


 

        以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 数据包含庞大的数组,就不能视而不见了。

;