本篇核心知识:指针数组与数组指针、复杂类型分析、const 与指针、运算符优先级 / 结合性、数组定义与指针访问、C 与 C++ const 差异
一、运算符优先级与结合性
概念
优先级决定表达式运算顺序,结合性决定同级运算执行方向,直接影响指针、数组表达式的正确性。
特性
-
优先级排序 :
()>[]>*> 算术运算符 > 关系运算符 > 逻辑运算符 > 赋值运算符 -
结合性
-
()、[]:左结合 -
*、&、const:右结合
-
-
影响:忽视规则会导致数组元素访问、指针解引用错误,是解题高频易错点。
代码示例
int arr[5] = {1,2,3,4,5};
int *p = arr;
// 优先级:[] > * → *(p+2) 等价于 p[2],正确访问元素
cout << *(p+2) << endl; // 输出3
相似概念比较:优先级 vs 结合性
-
优先级:决定谁先算,高优先级先执行。
-
结合性:优先级相同时,决定从哪边算(左→右 / 右→左)。
二、数组定义、初始化与指针访问
概念
数组是相同类型数据的有序集合,指针可直接操作数组地址,实现灵活访问。
特性
-
数组定义 :
类型 数组名[长度],长度为整型常量,不可用变量。 -
数组初始化
-
完整初始化:
int arr[5] = {1,2,3,4,5} -
省略长度:
int arr[] = {1,2,3}(自动匹配元素个数) -
部分初始化:剩余元素默认补 0
-
-
指针访问数组
-
数组名 = 首元素地址(常量指针,不可修改)
-
等价访问:
arr[i] == *(arr+i) == *(p+i)(p 为指向数组的指针)
-
-
数组名本质 :
const指针(*const类型),可访问修改元素,不可赋值、自增自减。
代码示例
// 定义并初始化数组
int arr[5] = {10,20,30,40,50};
// 指针指向数组首元素
int *p = arr;
// 指针访问元素
cout << p[1] << endl; // 20
cout << *(p+3) << endl; // 40
// 错误:数组名不可修改
// arr = nullptr;
三、指针数组 vs 数组指针(必考)
概念
指针数组是存指针的数组 ,数组指针是指向整个数组的指针,核心区别靠括号区分。
特性
1. 指针数组
-
定义:
类型 *数组名[长度] -
本质:数组,元素为指针
-
访问:
数组名[i](指针)、*数组名[i](指向的值)
2. 数组指针
-
定义:
类型 (*指针名)[长度] -
本质:指针,指向一个完整数组
-
访问:
(*指针名)[i](数组元素) -
特性:指针 + 1 跳过整个数组长度(数组指针特有)
代码示例
// 1. 指针数组:5个int*指针
int *pArr[5];
int a = 1, b = 2;
pArr[0] = &a;
pArr[1] = &b;
cout << *pArr[0] << endl; // 1
// 2. 数组指针:指向int[5]数组
int arr[5] = {1,2,3,4,5};
int (*p)[5] = &arr;
cout << (*p)[2] << endl; // 3
相似概念比较:指针数组 vs 数组指针
-
指针数组:数组 ,元素是指针,
[]优先级高于*。 -
数组指针:指针 ,指向数组,括号改变优先级,
()>[]。
四、复杂类型分析(做题必考)
概念
拆解多层指针、数组嵌套类型,确定变量本质、指向类型及内存大小。
特性
-
核心规则 :去掉变量名,剩余部分即类型;优先级
()>[]>*。 -
拆解方法:
-
数组:从外到内逐层降维
-
指针:逐个解引用,直到基础类型(int/char)
-
-
大小判断:指针占 4/8 字节;数组大小 = 元素个数 × 单个元素字节数。
代码示例
// 类型:指向int[2][3]的指针
int (*p)[2][3];
cout << sizeof(p) << endl; // 8字节(指针大小)
cout << sizeof(*p) << endl; // 24字节(int[2][3])
cout << sizeof(**p) << endl; // 12字节(int[3])
cout << sizeof(***p) << endl; // 4字节(int)
五、const 与指针(超级重点)
概念
const修饰指针,限制指针指向或指向内容的修改,分三种核心类型,C 与 C++ 规则有差异。
特性
1. const 基础
-
作用:修饰变量,使其只读 ,定义必须初始化,值后续不能修改。
-
等价写法:
const int a=int const a。
2. const 指针三种形式
① 指向常量的指针 (const int *p / int const *p)
-
含义:不能通过 p 修改指向的值,指针指向可改
-
用途:保护被指向数据
② 指针常量 (int *const p)
-
含义:指针指向不可改,指向的值可改
-
用途:固定指针指向
-
注释:int型指针不能指向const int型数据地址、const int型指针可以指向int型数据,但不能解析指针修改值
③ 指向常量的指针常量 (const int *const p)
- 含义:指针指向、指向的值均不可改,完全只读
3. C vs C++ 差异
-
C++:严格类型匹配,普通指针不能指向 const 变量(编译报错)
-
C:允许隐式转换,普通指针可指向 const 变量(不安全)
4. 变量初始化要求
- C++ 中
const变量 / 指针必须初始化,否则无默认值,无法使用。
代码示例
int a = 10, b = 20;
// 1. 指向常量的指针
const int *p1 = &a;
// *p1 = 100; // 错误:不能修改值
p1 = &b; // 正确:可改指向
// 2. 指针常量
int *const p2 = &a;
*p2 = 100; // 正确:可改值
// p2 = &b; // 错误:不能改指向
// 3. 指向常量的指针常量
const int *const p3 = &a;
// *p3 = 200; // 错误
// p3 = &b; // 错误
相似概念比较:三种 const 指针
-
const int *p:值只读,指向可变(保护数据)。 -
int *const p:指向只读,值可变(固定地址)。 -
const int *const p:全只读(最严格)。
六、数组复制与修改权限
概念
数组作为特殊变量,复制和修改受常量属性限制,本质为常量指针。即int * const类型,指向int,指向的数据可修改,自己不能被修改
特性
-
复制:数组整体不可直接赋值复制,需遍历元素或用内存函数。
-
修改 :数组名是
const指针,不可修改自身地址,但可修改数组内元素值。 -
权限本质 :数组具有只读地址、读写元素的权限。
代码示例
int arr1[3] = {1,2,3};
int arr2[3];
// 错误:数组不可直接赋值复制
// arr2 = arr1;
// 正确:遍历复制元素
for(int i=0; i<3; i++) arr2[i] = arr1[i];
// 正确:修改元素值
arr1[0] = 10;