重新理解指针常量,常量指针
应用
我先提一个问题:知道指针常量,常量指针存在的作用是什么吗?
先了解它们存在的作用再去理解它们,或许更轻松些。
比如配置文件读取:在许多工程中,配置文件用于存储应用程序的设置和参数。当开发在写读取配置文件接口时,需要考虑两个重要问题:
1.配置文件的存储路径,不能随意被更改。
2.配置文件的内容,不能随意被修改
那么如何确保以上两点呢?就是运用指针常量和常量指针来实现。代码如下:
const char* const CONFIG_FILE_PATH = "config.ini";
/* 代码说明如下:
1.通过使用常量指针来读取配置文件中的数据,确保配置文件的内容不被修改。
2.CONFIG_FILE_PATH是一个指针常量,它指向一个不可修改的配置文件路径。
*/
void readConfigFile(const char* const filePath) {
// 读取配置文件的内容
// ...
}
int main() {
readConfigFile(CONFIG_FILE_PATH);
return 0;
}
我的理解
通过上一个实例说明,常量指针,指针常量限制了“内容”“路径”被指针随意修改,从C语言术语来阐述应该是“值”“地址”不能被指针修改。现在我们只是了解指针常量,常量指针的运用实例。
假设你已经理解const关键字,那么下面我们正式来分析指针常量,常量指针。
指针常量(Pointer to constant)
格式:
int* const ptr;
//int *(指针) const(常量) ptr
//(指针)(常量)
上面不规范的注释能get到意思吗?先有解引用*号,后有常量(constant),就叫指针常量。
指针常量限制的是“地址”还是“值”呢?请看下面
int a = 0;
int* const ptr = &a;
//int * (const ptr) = &a;
//ptr是a的地址,const ptr就是限制地址
//注意:上述解引用*号优先级比括号高,使用括号只是为了方便理解
简单总结下,指针常量限制的是指针地址,指针常量实验1:
当我想改变b的地址,编译报错。
那可以改变b指向的地址所存储的值吗?即可以使用b改变a的值吗?指针常量实验2:
通过实验2,能够清晰的看到,b一直是a的地址,a的值被两次改变。
指针常量总结:
1.如何准确判断是指针常量 :(* const),指针(*)常量(const)
2.如何判断限制的是什么: int * (const a) = &b; (不规范,仅方便理解),限制a的指向不被指针更改,但是指向地址的值可以被更改。
常量指针(Constant Pointer)
格式:
int a = 0;
const int* ptr = &a;
//const int (* ptr) = &a;
//(* ptr)是a的值,因此const (* ptr)就是限制a的值不被改变
//注意:上述解引用*号优先级比括号高,使用括号只是为了方便理解
简单总结下,常量指针限制的是指向地址的值不能被指针更改。常量指针实验1:
常量指针实验1能够看出,a的值无法被指针修改。
常量指针实验2:
常量指针实验2能够看出,指针b指向的地址可以被改变,指向变量c,a的值没有被改变。
再谈应用
本文开始没有直接讨论指针常量,常量指针的概念,而是从工程实践运用的角度开始谈起,其实到这里已经可以结束。不过我还想分享工程实践的一个案例,让我们更明白指针常量存在的作用。
案例1:在嵌入式系统开发中,常常需要与硬件设备进行交互。通过使用指针常量来映射硬件寄存器的地址,可以方便地读取和写入寄存器的值,但同时肯定要防止开发者更改寄存器地址。例如:
volatile uint32_t* const GPIO_PORTA = (uint32_t*)0x40020000;
在这个例子中,GPIO_PORTA是一个指针常量,它指向硬件设备的寄存器地址。通过使用指针常量,可以直接访问硬件寄存器的值。
**案例2:**在一些应用中,需要定义一些常量数据表,例如查找表、配置表等。通过使用指针常量,可以将这些数据表存储在只读的内存区域,提高程序的效率和安全性。
const int* const LOOKUP_TABLE = {1, 4, 9, 16, 25};
在这个例子中,LOOKUP_TABLE是一个指针常量,它指向一个只读的整数数组。通过使用指针常量,可以确保数据表的内容不被修改。