<p>声明指针应写为int p;,因int是完整类型;错误写法int* p, q;中q非指针;必须用&取地址赋值,不可直接赋值变量;const位置决定修饰对象;优先初始化为nullptr而非野指针。</p>

怎么声明一个指针变量
声明指针,核心是 * 的位置——它属于类型的一部分,不是变量名的修饰。写成 int* p; 比 int *p; 更准确,因为 int* 是一个完整类型,p 是这个类型的变量。
常见错误是以为 * 绑定变量名,结果写出 int* p, q;,以为 q 也是指针,其实 q 是 int 类型。要声明多个指针,得写成 int* p, *q; 或分开声明。
-
int x = 42;→ 基础变量 -
int* p = &x;→ 正确:声明指针并初始化为x的地址 -
int* p; p = &x;→ 合法但不推荐:未初始化就声明,容易误用野指针 - 不要写
int * p = &x;(空格无害但易误导),更别写int* p = x;(类型不匹配,编译报错cannot convert 'int' to 'int*')
赋值时为什么必须用取地址符 &
指针存的是地址,不是值。想让指针指向某个变量,就得用 & 拿到它的内存地址。直接赋值变量本身(比如 p = x;)会导致类型错误或隐式转换失败。
例外情况只有两个:空指针(p = nullptr;)和另一个同类型指针(p = q;)。其他任何“值→指针”的赋值都需警惕。
立即学习“C++免费学习笔记(深入)”;
-
int x = 10; int* p = &x;→ 正确 -
int* p = 1000;→ 错误:整数不能直接当地址(C++11 起禁止隐式转换) -
int* p = reinterpret_cast<int>(1000);</int>→ 极少数底层场景才用,通常意味着设计出问题 - 数组名在多数上下文中自动退化为指针,所以
int arr[5]; int* p = arr;合法(等价于&arr[0])
const 修饰指针时的三种写法区别
const 放的位置决定它管的是“指针本身”还是“指针所指的内容”,初学者极易混淆。记住口诀:“const 紧贴谁,谁就不能改”。
-
int* const p = &x;→ 指针不可变(不能指向别处),但可改*p -
const int* p = &x;或int const* p = &x;→ 所指内容不可变(不能通过p改x),但指针可重定向 -
const int* const p = &x;→ 两者都不可变 - 函数参数中常用
const int* p表示“只读数据”,避免意外修改传入的数组或缓冲区
初始化为空指针比野指针安全得多
未初始化的指针(野指针)值是随机的,解引用它(*p)会触发未定义行为——程序可能崩溃、静默出错、甚至暂时正常运行,埋下严重隐患。而 nullptr 是明确的空值,解引用立刻崩溃(便于调试),且能参与条件判断。
- 永远优先用
int* p = nullptr;,而不是int* p; - 不要用
int* p = NULL;(NULL在 C++ 中本质是0或0L,类型模糊,nullptr是类型安全的) - 类成员指针也应在构造函数初始化列表中设为
nullptr,而非依赖默认初始化 - 函数返回指针时,失败应返回
nullptr,调用方必须检查:if (p != nullptr) { ... }
指针真正的复杂点不在语法,而在生命周期管理——谁分配、谁释放、作用域是否覆盖、是否被提前释放后又解引用。这些没法靠声明和赋值解决,得靠 RAII 或智能指针兜底。但至少,从声明开始就写对、初始化就设好,能避开一大半低级坑。










