解引用指针修改目标值需确保指针有效、非const且指向可写内存;结构体用->修改成员;const位置决定指针或值是否可变;数组和迭代器通过下标或偏移修改,须防越界与多线程竞态。

用 * 解引用指针修改目标值
直接通过解引用操作符 * 访问并赋值,是最常见也最直接的方式。前提是该指针已正确初始化、指向可写内存(比如堆或栈上的非 const 变量),且未被声明为 const int* 这类只读指向类型。
- 如果指针是
int* p = &x;,那么*p = 42;就等价于x = 42; - 若指针指向堆内存:
int* p = new int(10); *p = 20;—— 此时修改的是动态分配的值 - 错误示例:
const int x = 5; int* p = const_cast<int>(&x); *p = 10;</int>—— 行为未定义,即使编译通过也不应这么做 - 空指针解引用:
int* p = nullptr; *p = 1;—— 程序崩溃(SIGSEGV / access violation)
修改指针所指对象的成员(结构体/类)
当指针指向一个结构体或类实例时,用 -> 操作符修改其非 const 成员,本质仍是解引用 + 成员访问,只是语法更简洁。
-
struct Point { int x, y; }; Point* p = new Point{1, 2}; p->x = 10;等价于(*p).x = 10; - 若成员本身是指针(如
char* name;),则p->name = "hello";修改的是该成员变量的值(即指针地址),不是它所指内容;要改字符串内容需strcpy(p->name, "world"); - 注意 const 限定:若声明为
const Point* p;,则p->x = 5;编译失败;而Point* const p;仅禁止改变指针本身,仍可修改所指对象
避免踩坑:const 位置决定谁不可变
很多人混淆 const int* p 和 int* const p 的含义,导致编译报错或误以为能修改实际不能改的值。
-
const int* p或int const* p:指针可变,指向的值不可变 →*p = 5;错误,p = &y;允许 -
int* const p = &x;:指针不可变(必须初始化),指向的值可变 →*p = 5;正确,p = &y;错误 -
const int* const p = &x;:两者都不可变 - 用
auto推导时尤其要注意:auto p = &x;得到的是int*,但auto p = &cx;(cx是const int)得到的是const int*
数组指针与下标访问修改元素
数组名退化为指针后,可通过指针算术加下标或偏移方式修改特定位置的值,底层仍是解引用。
-
int arr[3] = {1,2,3}; int* p = arr; p[1] = 99;→ 修改arr[1],等价于*(p + 1) = 99; - 注意越界:
p[10] = 0;不报错但行为未定义,可能覆盖相邻变量或触发内存保护 - 对
std::vector迭代器同样适用:auto it = vec.begin(); *(it + 2) = 7;,前提是it + 2在有效范围内
实际写的时候,最常出问题的不是语法不会用,而是没确认指针是否有效、是否带 const 限定、以及是否在多线程里无保护地修改了共享对象。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











