const
指针与内存类型的关系
1. const int *p
cpp
const int *p = &n;
在这种情况下,p
是一个指向 const int
的指针。它指向的地址可以被更改,但不能通过 p
来修改指向的值。也就是说,*p
是一个只读的变量,编译器会强制将 p
所指向的内存区域视为只读。
- 内存保护:如果
n
本身是定义在只读内存区域中的,比如定义成const int n = 5;
,那么无论是否通过指针p
访问,这个内存区域都是只读的,任何修改都会导致程序崩溃(在一些操作系统上可能触发段错误)。 - 编译器行为:即使
n
是一个普通变量,const int *p
仍然限制了对n
的修改。编译器不会允许通过p
来修改它,因为在程序逻辑上,这部分内存已经被声明为只读。
2. int * const p
cpp
int * const p = &n;
在这种情况下,p
本身是一个常量指针,意味着 p
的地址不能更改,但可以通过 p
修改其指向的值(即 *p
可写)。p
必须在定义时初始化,因为 const
限制了 p
本身的地址不能改变。
- 内存行为:这里
*p
是可写的,因为p
指向的内容(n
)没有被const
限制为只读。 - 指针的不可变性:由于
p
是const
的,内存中的p
的值(即存储的地址)在程序的生命周期内是固定的,不会被修改。
3. const int * const p
cpp
const int * const p = &n;
这种情况下,p
是一个指向 const int
的常量指针。既不能修改 p
的地址,也不能通过 p
修改它所指向的值。
- 双重限制:这种声明方式同时将
p
的指向(地址)和p
指向的内容(值)都限定为只读。 - 内存位置:如果
n
是一个const
值,那么它可能被编译器优化到只读内存区域中。这意味着任何对*p
的修改操作都会导致运行时错误(通常是段错误),因为*p
所指向的区域在物理上是不可写的。
4.加了const后指针不能修改它所指向的值
-
- 程序运行时,内存一般分为以下几个区域:
-
-
- 代码段 (Code Segment):存放程序的机器指令,是只读的。
- 数据段 (Data Segment):存储程序中的全局变量和静态变量,通常包含可修改的区域(如全局变量)和只读区域(如
const
常量)。 - 堆 (Heap):用于动态分配的内存区域,由程序员手动管理(如
malloc
、new
操作)。 - 栈 (Stack):用于存储函数的局部变量,自动管理。
-
其中,const
修饰的变量或数据通常会被放在只读的内存区域(如代码段或数据段的只读区域),从而限制其被修改的权限。
int n, m;
const int *p = &n;
*p = 5;//不能修改*p的值,错误
n = 4;
p = &m;
-
- 在这段代码中:
-
const int* p
的意思是p
是一个指向const int
的指针。- 也就是说,
p
指向的内容被认为是常量,因此无法通过p
来修改该内容,即*p
是只读的。
-
- 不能把常量指针赋值给非常量指针,反过来可以
const int * p1; int * p2:
p1 = p2;//ok
p2 =p1; //error
p2=(int*)p1; //ok,强制类型转换