<p>int p[5] 是含5个int指针的数组,int (p)[5] 是指向含5个int数组的指针;二者类型不同、内存步长不同、解引用方式不同,混用导致编译错误。</p>

为什么 int* p[5] 和 int (*p)[5] 不能混用
编译器看到这两种声明,生成的符号类型完全不同:前者是数组,后者是指针。混用会导致类型不匹配错误,比如传参时触发 cannot convert 'int*[5]' to 'int(*)[5]'。
关键差异在内存步长和解引用行为:
-
int* p[5]:每个元素是int*,p + 1移动sizeof(int*)(通常 8 字节) -
int (*p)[5]:指向整个 5 元素int数组,p + 1移动5 * sizeof(int)(通常 20 字节) - 对
p[0]解引用:int* p[5]得到的是int*,需再*才得值;int (*p)[5]的(*p)[0]直接得第一个int值
二维数组传参必须用 int (*arr)[COLS]
写成 void func(int arr[][4]) 或 void func(int** arr) 都是错的——前者在形参中退化为 int (*)[4],后者根本无法访问连续内存中的二维布局。
正确做法是显式传递列数,并用数组指针接收:
立即学习“C++免费学习笔记(深入)”;
void print2D(int (*mat)[4], int rows) {
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%d ", (*mat)[j]); // 或 mat[i][j]
}
++mat; // 移动到下一行(跳过 4 个 int)
}
}注意:mat[i][j] 能用,是因为编译器知道每行长度是 4;但若写成 int** mat,就丢失了行内连续性,mat[i][j] 会读错地址。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
用指针数组管理字符串时,"hello" 地址不能被修改
常见错误是把字符串字面量地址存进指针数组后,试图通过 *ptrArray[i] 修改内容,比如:
char* strArr[] = {"hello", "world"};
strArr[0][0] = 'H'; // 运行时报 segmentation fault原因:"hello" 存在只读数据段,strArr[0] 指向那里,写操作非法。安全做法是用字符数组初始化:
- 用
char str1[] = "hello"; char* strArr[] = {str1, str2}; - 或动态分配:
char* s = new char[6]; strcpy(s, "hello");
否则,哪怕编译通过,运行时崩溃几乎是必然的。
std::vector 替代裸指针数组前,先确认是否真需要动态尺寸
很多人一看到“多个指针”就立刻上 std::vector<int*>,但多数场景其实用不到——比如固定数量的回调函数指针、预设设备句柄表等,用 int* handlers[8] 更轻量、无分配开销、缓存友好。
只有当数量不确定、需频繁增删、或跨模块共享生命周期时,才考虑 std::vector<std::unique_ptr<T>> 或 std::vector<T*>(注意后者不管理所指对象生命周期)。
最容易被忽略的一点:数组指针(如 int (*p)[10])无法直接放进容器,因为它是类型,不是对象;若要泛化处理,得包装成结构体或用模板推导。

















