学习指针常量与常量指针,最关键的是需要用到 const 关键字。
const 是单词 constant 的缩写,翻译过来就是恒定的、不变的,也被称为 常量限定符,表示只读的意思。习惯性的使用 const,可以避免在代码中对某些不应修改的数据造成可能的改动。
在 C 语言中,常量有以下 4 种表示方法:
-
字面常量:直接使用数字、字符表示的量8 // 整型常量 3.14 // 浮点数常量 '@' // 字符常量 "abc" // 字符串常量 -
#define宏定义的标识符常量#define PINK 0xFFC0CB #define BLUE 0x0000FF #define D double #define HELLO printf("Hello, world!"); -
enum枚举常量enum weekdays { MON = 1, TUE = 2, WED = 3, THU = 4, FRI = 5, SAT = 6, SUN = 7 }; -
const修饰的只读变量const int a = 100; const char name[] = "罗大富";
const 修饰变量与数组
const 最简单的应用场景就是修饰基本数据类型,对于基本的数据类型,修饰符 const 可以用在类型说明符前,也可以用在类型说明符后,其结果是一样的,代码如下:
int const a = 100;
const int a = 100; //与上面等价
int const array[3] = {1,2,3};
const int array[3] = {1,2,3}; //与上面等价
因 const 变量不可修改,所以定义时必须初始化,并且初始化完成后,变量的值无法修改,例如,如果把以上代码中的:
const int a = 10; // 声明只读变量 a
a = 100; // 修改只读变量 a 的值
运行以上代码,就会出现报错提示:

const 修饰指针变量 - 常量指针与指针常量
const 在指针变量的修饰方面可以存在于两个位置的修饰,即指针常量和常量指针。可以根据 const 和 * 的位置关系判断 const 是修饰数据还是指针本身:
const位于*的左边,则表示指向的数据为常量,也被称为常量指针,例如:const int* p1;const位于*的右边,则表示指针为常量,其指向的地址不可改变,也被称为指针常量,例如:int* const p2。
例如:首先创建一个数组 array,然后让普通指针 pointer_1 指向该数组,此时,我们通过指针既可以修改指针的地址,也可以修改指针指向地址存储的数据:
int array[] = {1, 2, 3, 4, 5};
// 定义一个普通指针指向数组 array 的首地址
int* ptr_1 = array;
printf("ptr_1 指向的地址为:%p, 对应的值为:%d\n", ptr_1, *ptr_1);
// 通过指针修改数组元素的值
*ptr_1 = 100;
printf("通过指针修改数据后,ptr_1 指向的地址为:%p, 对应的值为:%d\n", ptr_1, *ptr_1);
// 修改指针指向的地址
ptr_1 = &array[1];
printf("通过指针修改地址后,ptr_1 指向的地址为:%p, 对应的值为:%d\n", ptr_1, *ptr_1);
然后,创建一个常量指针 pointer_2 使其指向数组 array,代码如下:
// 常量指针
const int* ptr_2 = array;
printf("ptr_2 指向的地址为:%p, 对应的值为:%d\n", ptr_2, *ptr_2);
// 通过指针修改数组元素的值
*ptr_2 = 200; // 错误使用
// 修改指针指向的地址
ptr_2 = &array[2]; // 正确使用
printf("通过指针修改地址后,ptr_2 指向的地址对应的值为:%d\n", *ptr_2);
通过上述代码可以发现:const 位于星号 * 左侧时,const 就是用来修饰指针所指向的变量,即指针指向为常量。虽然指针指向的地址对应的值不可以修改,但是可以修改其指向的地址。
接着,再创建一个指针常量 pointer_3 使其指向数组 array,代码如下:
// 指针常量
int* const ptr_3 = array;
printf("ptr_3 指向的地址为:%p, 对应的值为:%d\n", ptr_3, *ptr_3);
// 通过指针修改数组元素的值
*ptr_3 = 300; // 正确用法
printf("通过指针修改数据后,ptr_3 指向的地址为:%p\n", *ptr_3);
// 修改指针指向的地址
ptr_3 = &array[3];
通过上述代码可以发现:const 位于星号 * 的右侧,const 就是修饰指针本身,即指针本身是常量,指针存储的值不可修改,而指针存储的值是地址,所以说常量指针不可以修改地址。虽然指针的地址不可以修改,但是可以通过指针修改它所指向的变量的值。
最后,再创建一个指向常量的指针常量 pointer_4,代码如下:
// 指向常量的指针常量
const int* const pointer_4 = array;
*pointer_4 = 400; // 错误使用
pointer_4 = &array[4]; // 错误使用
pointer_4 既不可以修改其指向的地址,也不可以修改其指向的地址对应的值。
区分指针常量和常量指针的技巧
名字从左向右读,例如:
const int* pointer_2是const(常量)在左侧,*(指针)在右侧,因此,名字就是常量指针。int* const pointer_3是*(指针)在左侧,const(常量)在右侧,因此,名字就是指针常量。
在判断功能时,可以把 * 看作是解引用运算符,比较 const 与 * 谁离指针更近,例如:
const int* pointer_2是*先对 pointer_2 进行解引用操作,也就变成了该指针指向的变量,const将该指针指向的变量变成了只读的,也就是我们可以修改指针的地址,但是不能修改指针指向的变量的值;int* const pointer_3是const先把该指针变量,变成了只读的,而指针存储的值是地址,也就是说我们不可以修改指针指向的地址,但是可以修改该地址对应的值。