1. 数组与指针的本质关系
在C语言中,数组和指针的关系可以说是"剪不断理还乱"。很多初学者容易混淆这两者的概念,但实际上只要抓住几个关键点就能清晰理解。
1.1 数组名的双重身份
数组名在C语言中具有双重含义,这个特性是理解数组与指针关系的关键:
-
代表整个数组:仅在三种特殊情况下
- 数组定义时:
int arr[5]中的arr - sizeof运算符:
sizeof(arr)中的arr - 取地址操作:
&arr中的arr
- 数组定义时:
-
代表首元素地址:其他所有情况下
- 例如:
int *p = arr中的arr等价于&arr[0]
- 例如:
重要提示:当数组名作为函数参数传递时,它会退化为指针。这就是为什么在函数内部无法通过sizeof获取数组实际大小的原因。
1.2 一维数组的指针表示
一维数组的访问可以通过多种指针形式实现:
c复制int arr[5] = {1,2,3,4,5};
// 以下四种写法完全等价
arr[2] = 10;
*(arr+2) = 10;
*(2+arr) = 10;
2[arr] = 10; // 这种写法虽然合法但不推荐
这种等价性源于C语言的指针算术特性。编译器实际上将arr[i]转换为*(arr+i)的形式。
1.3 二维数组的指针解析
二维数组的指针关系更为复杂,但可以通过分层理解:
c复制int arr[2][3] = {{1,2,3},{4,5,6}};
// arr代表什么?
// arr是"数组的数组",所以arr代表第一个子数组的地址
// 即arr的类型是int (*)[3]
// 访问arr[1][1]的等价指针形式
arr[1][1] = 10;
*(*(arr+1)+1) = 10;
理解二维数组指针的关键在于:
arr是指向第一个子数组的指针*arr得到第一个子数组,此时又退化为指向该子数组首元素的指针- 因此
**arr得到第一个元素的值
2. 数组指针与指针数组
这是两个经常被混淆的概念,但它们的含义和用法截然不同。
2.1 数组指针详解
数组指针是指向数组的指针,其定义形式为:
c复制int (*p
