指针数组使用
利用指针数组,将一维数组模拟出一个二维数组
#include <stdio.h> int main() { int arr1[] = { 1,2,3,4,5 }; int arr2[] = { 2,3,4,5,6 }; int arr3[] = { 3,4,5,6,7 }; //数组指针 int* arr[] = { arr1, arr2, arr3 }; //打印 int i = 0; for (i = 0; i < 3; i++) { int j = 0; for (j = 0; j < 5; j++) { printf("%d ", arr[i][j]); } printf("\n"); } return 0; }
效果展示:
这里的 arr 里面的 arr1、arr2、arr3 在内存中不一定连续,这只是模拟,但是存储就不一定是二维数组那样的在内存中连续存储了。但是 arr1、arr2、arr3 分别是连续的,因为分别是一维数组。
引申:
我们来看这段代码:
#include <stdio.h> int main() { int arr[] = { 1,2,3,4,5 }; int i = 0; int* p = arr; for (int i = 0; i < 5; i++) { printf("%p = %p\n", &arr[i], p+i); } return 0; }
效果展示:
我们可以看到,这里&arr[i] 和 p+i 取出的地址是一样的。因此我们对 p+i 解引用也就是数组的每一个元素。
我们来看代码:
#include <stdio.h> int main() { int arr[] = { 1,2,3,4,5 }; int i = 0; int* p = arr; for (int i = 0; i < 5; i++) { printf("%d ", *(p+i));//*(p+i) = arr[i] } return 0; }
效果展示:
分析:
我们 p 存的是 arr ,数组名也是首元素地址,我们是对 p+i 解引用得到的数组元素,那么我们不借用中间变量,直接对 arr+i 解引用也就是把数组的每一位元素打印出来了。编译器就是通过这样的方式对数组的每一位进行打印的。因此 arr[ i ] = *( arr+i )。
在数组传参的时候,形参部分写成指针或者数组都是一样的,都是支持的。
我们来试试看看分析是否正确
#include <stdio.h> int main() { int arr[] = { 1,2,3,4,5 }; int i = 0; //打印 for (int i = 0; i < 5; i++) { printf("%d = %d\n", arr[i], *(arr+i)); } return 0; }
效果展示:
看来我们上面的分析是正确的,我们继续分析:
我们这里是对 arr+i 解引用得到数组每一个元素的,这里用的是加法,加法是支持交换律的,那是不是就可以将arr 与 i 交换再解引用也可以得到数组每一个元素,如果可以那这就意味着 i[arr] 这种形式也是可以的。
我们用代码来验证一下:
#include <stdio.h> int main() { int arr[] = { 1,2,3,4,5 }; int i = 0; for (int i = 0; i < 5; i++) { printf("%d = %d\n", i[arr], *(i+arr)); } return 0; }
效果展示:
原来我们分析的是对的,这样也是可以的。
总结:
指针数组这里是存在等价关系的。
但是这里我们平时是不以 i[arr] 这样的方式写的,主要还是用 arr[i] 的方式写。
我们再来想二维数组
在二维数组里这都是等价的。
哈哈哈,又学到了,指针也不是那么难,我们继续坚持,肯定可以攻克它,冲冲冲!!!
************************************************本片结束***********************************************