关于const限定的字符指针

本文详细解析了C++中各种指针的用法及其限制,包括单层和双层指针的不同组合形式,并探讨了const修饰符的作用及类型兼容性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

一、 可能的组合

(1) const char *p

(2) char const *p

(3) char * const *p

(4) const char **p

(5) char const **p

(6) char * const  *p

(7) char ** const p

当然还有在(5)、(6)、(7)中再插入一个const的情况,不过分析了以上7种,其它的就可类推了!

 

二、理解助记法宝:

1. 关键看const修饰谁

2. 由于没有const *的运算,若出现const *的形式,则const实际上是修饰前面的

比如:char const *p, 由于没有const *运算,则const实际上是修饰前面的char, 因此 char const *p 等价于 const char *p,也就是说上面7种情况种,(1)和(2)等价。同理,(4)和(5)等价。在(6)中,由于没有const*运算,const实际上修饰的是前面的char *,但不能在定义时转换写成const (char *) *p,因为定义在“()”中是表示函数。

三、深入理解7中组合

0. 程序在执行是为其开辟的空间皆在内存(RAM)中,而RAM里的内存单元是可读可写的;指针只是用来指定或定位要操作的数据的工具,用来读写RAM里内存单元的工作指针。若对指针不加任何限制,程序中一个指针可以指向RAM中的任意位置(出了系统敏感区,如操作系统内核所在区域)并对其指向的内存单元进行读和写操作(由RAM的可读可写属性决定);RAM里内存单元的可读可写属性不会因为对工作指针的限定而变化(见下面的第4点),而所有对指针的各种const限定说白了只是对该指针的读写权限(包括读写位置)进行了限定。

1. char *p: p是一个工作指针,可以用来对任意位置(非系统敏感区域)进行读操作和写操作,一次读写一个字节(char占一个字节存储单元)。

2. const char *p 或者 char const *p(因为没有const char *p运算,因此const修饰的还是前面的char):可以对任意位置(非系统敏感区域)进行“只读”操作。

3. char *const p (const修饰的是p):这能对“某个固定位置”进行读写操作,并且在定义p时就必须初始化(因为在后面不能执行“p=... “ 的操作,因此就不能在后面初始化,因此这能在定义是初始化)。 (”某个固定的位置“是相对于char *p来说所限定的内容)

可以总结以上3点为:char *p中的指针p通常是”万能“的工作指针,而(2)和(3)只是在(1)的基础上加了些特定的限制,这些限制在程序中并不是必须的,只是为了防止程序员的粗心大意而产生事与愿违的错误。

另外,要明白”每块内存空间都可有名字;每块内存空间内容皆可变(除非有所限制)“。比如函数里定义的char s[] = "hello",事实上在进程的栈内存里开辟了6个变量共六个字节的空间,其中6个字符变量的名字分别为:s[0]、s[1]、s[2]、s[3]、s[4]、s[5]、s[6] (内容是'\0')。

{

待验证:还有一个4字节的指针变量s。不过s是”有所限制“的,属于char * const 类型,也就是前面说的(3)这种情况,s一直指向s[0],即(*s == s[0] == 'h',可以通过*s = 'k' 来改变s所指向的s[0]的值,但不能执行(char *h = ”aaa“;  s = h; 来对s另外赋值。

}

4. 上面的(2) 和(3)只是对p进行限定,没有也不能对p所指向的空间进行限定,对于"char s[] = "hello"; const char *p = s; " 虽然不能通过 *(p+1) = 'x' 或者

p[i] = 'x' 来修改数组元素 s[0] ~ s[4] 的值,但可以通过 *(s+1) = 'x' 或者 s[i] = 'x' 来修改原数组元素的值——RAM里内存单元的可读可写属性不因对工作指针的限定而改变,而只会因对其本身的限定而改变。如const char c = ‘A’, c是RAM里一个内存单元(8字节)的名字,该内存单元的内容只可读,不可写。

5. const char **p 或者 char const **p: 涉及两个指针p 和 *p。 由于const 修饰char, 对指针p 没有任何限定,对指针*p 进行了上面情况(2)的限定。

6. char * const *p: 涉及两个指针p 和 *p。 由于const修饰前面的char *, 也就是对p所指向的内容*p进行了限定(也属于前面的情况(2))。 而对*p来说,由于不能通过 " **p = ... " 来进行另外赋值,因此属于前面的情况(3)的限定。

7. char ** const p: 涉及两个指针p 和 *p, const 修饰p, 对p进行上面情况(3)的限定,而对*p没有任何限制。

四、关于char **p、 const char **p的类型相容性问题

1. 问题

char *p1; const *p2 = p1;  //合法

char **p1; const char **p2 = p2; // 不合法,会有警告warning: initialization from incompatible pointer type

char **p1; char const **p2 = p1; // 不合法,会有警告warning: initialization form incompatible pointer type

char **p1; char * const *p2 = p1; //合法

2. 判断规则

明确const修饰的对象! 对于指针p1 和 p2,若要使得 p2 = p1 成立,则可读做

p1是指向X类型的指针,p2是指向“带有const限定”的X类型的指针“。

char *p1; const *p2 = p1; // 合法:p1是指向(char)类型的指针,p2是指向”带有const限定“的(char)类型的指针。

char **p1; const char **p2 = p1; //不合法:p1是指向(char*)类型的指针,p2是指向((const char) *)类型的指针。

char **p1; char const **p2 = p1; // 不合法:与上等价。

char **p1; char * const *p2 = p1; //合法:p1是指向(char *)类型的指针,p2是指向”带有const限定“的(char *)类型的指针。

五、其他

1. 含有const 的单层或双层指针的统一读法:

p是一个指针,是一个[“带有const限定”的] 指向 [“带有const限定”的] X类型的指针“。

2. 定义时const修饰的对象是确定的,但不能再定义时加括号,不然就和定义时用”( )“表示的函数类型想混淆了!因此定时时不能写 (char *) const *p或者 (const char) **p。

### C/C++ 中 `const` 关键字用于声明常量指针指针常量的区别及用法 #### 定义与基本概念 在 C 和 C++ 编程语言中,`const` 关键字用来表示不可变的数据。当应用于指针时,它可以有多种含义: - **常量指针 (Pointer to Constant)**:这种类型的指针指向一个其值不能被更改的对象。 ```cpp const int *ptr; ``` - **指针常量 (Constant Pointer)**:这种类型的指针本身是常量,即一旦初始化后就不能再指向其他对象。 ```cpp int *const ptr = &variable; ``` - **双重常量 (Double Const)**:同时指定指针及其所指向的内容都是常量。 ```cpp const int *const ptr = &constant_variable; ``` #### 常量指针的具体说明 对于常量指针而言,这意味着可以通过这个指针访问到的值不可以改变,但指针本身的地址是可以变化的。例如, ```cpp int value1 = 10, value2 = 20; const int *pointer_to_const = &value1; // 下面这行会报错,因为试图修改由 pointer_to_const 所指向的位置上的值 //*pointer_to_const = 30; // 这样做是允许的,因为它只是改变了指针指向的地方 pointer_to_const = &value2; ``` 这段代码展示了如何创建并操作一个指向整数常量的指针[^1]。 #### 指针常量的具体说明 另一方面,如果定义的是一个指针常量,则意味着该指针存储的实际内存位置不会发生变化;然而,通过此指针可以修改其所指向的数据(除非也应用了 `const`)。考虑以下例子: ```cpp int varA = 5, varB = 7; int *const constant_pointer = &varA; // 尝试重新分配给 constant_pointer 是非法的操作 //constant_pointer = &varB; // 错误! // 修改 constant_pointer 指向的数据却是合法的行为 *constant_pointer = 8; ``` 上述片段解释了什么是真正的指针常量以及它们的工作方式[^3]。 #### 双重常量的应用场景 最后一种情况涉及到了两个层面都带有 `const` 的限定符,使得不仅指针本身而且它所指向的目标都不能被改动。这样的设计通常出现在函数参数传递过程中以保护传入的数据不被意外篡改。 ```cpp void exampleFunction(const char *const strPtr){ //strPtr 不可变更,也不能经由 *strPtr 改动字符串内容 } ``` 这种方式确保了即使是在复杂环境中也能维持数据的一致性和安全性[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值