<p> 属于类型的一部分,构成“指向 int 的指针”这一完整类型;int p, q; 中仅 p 是指针,q 是 int;声明多个指针需写为 int p, q; 或分别声明;auto 推导自动包含 ;& 要求左值, 要求指针类型;传指针进函数默认按值传递,改指向需用引用或二级指针;必须用 nullptr 而非 NULL。</p>

指针变量声明时 * 属于类型还是变量名?
它属于类型的一部分,不是变量名修饰符。写成 int* p; 容易误以为 * 绑定在 p 上,但实际是 int* 构成一个完整类型——“指向 int 的指针”。
常见错误现象:int* p, q; 让人以为 q 也是指针,其实只有 p 是,q 是普通 int。正确写法是分开声明或重复 *:int* p, *q;
- 声明多个指针时,每个变量前都要加
*,不能省略 -
int *p, *q;和int* p; int* q;等价,推荐后者更清晰 - 用
auto推导时,auto p = &x;得到的是int*类型,*自动包含在推导结果里
取地址 & 和解引用 * 混用时为什么报错?
根本原因是操作对象类型不匹配:& 要求操作左值(有内存地址的变量),* 要求操作指针类型。两者嵌套顺序或对象类型错一点就崩。
常见错误现象:*&x 没问题(先取地址再解引用,回到原值),但 &*p 在 p 为空或未初始化时会崩溃;更隐蔽的是 &(x + 1) —— x + 1 是右值,没地址,编译直接失败。
立即学习“C++免费学习笔记(深入)”;
-
&只能作用于变量、数组元素、成员等左值,不能用于字面量、表达式结果 -
*前的操作数必须是指针类型,*5或*nullptr都非法(后者运行时报错) - 函数返回局部变量地址(如
return &local;)看似用了&,实则返回悬垂指针,后续解引用行为未定义
传指针进函数却没改到原变量,哪里漏了?
大概率传的是指针的副本,而不是指针本身。C++ 默认按值传递,void f(int* p) 中修改 p(比如 p = new int(42);)只影响形参,不影响调用方的指针变量。
使用场景:想让函数修改原始指针指向(比如重分配内存并更新调用方持有的地址),必须传指针的引用或二级指针。
- 改指向:用
void f(int*& p),然后p = new int(42);才生效 - 只改所指内容:用
void f(int* p),然后*p = 42;就够了 - 用二级指针
void f(int** p)也能改指向,但要写*p = new int(42);,容易多写/少写* - 现代 C++ 更倾向用引用方式,语义更直白,且避免
nullptr传入风险
nullptr 和 NULL 能混着用吗?
能编译,但不该混。它们语义和类型不同:NULL 是宏,传统上定义为 0 或 ((void*)0),可能被当整数参与重载决议;nullptr 是独立字面量,类型是 std::nullptr_t,只匹配指针类型。
性能无差异,但兼容性和可读性差很多。尤其在函数重载中,NULL 可能意外匹配 func(int) 而非 func(char*),nullptr 则永远只走指针分支。
- 所有新代码必须用
nullptr,C++11 起就是标准做法 -
NULL在头文件里可能依赖cstddef或其他宏定义,跨平台时行为不稳 - 模板推导中
nullptr能正确推成std::nullptr_t,NULL可能推成int,引发后续错误
事情说清了就结束。指针最麻烦的从来不是语法,而是你心里有没有时刻绷着“这个值是不是有效地址”这根弦。











