一.指针数组
指针数组是存放指针的数组,首先得是一个数组,其次数组里的元素是指针。
所以数组名先和方括号 [ ] 结合 ,然后才是指针;
具体如下图:
实例:
1. int main() 2. { 3. int a[5] = { 1,2,3,4,5 }; 4. int b[5] = { 5,6,7,8,9 }; 5. int* parr[2] = { a,b }; 6. int i = 0, j = 0; 7. for (i = 0; i < 2; i++) 8. { 9. for (j = 0; j < 5; j++) 10. { 11. printf("%d ", *(parr[i] + j)); //parr[i] 就是数组parr 中下标为i的元素 12. } //该元素为数组名,数组名是数组首元素的地址 13. printf("\n"); //加上 j 就是数组中下标为 j 的元素的地址 14. } //对其解引用就得到了该元素 15. return 0; 16. }
当然上面代码中的 printf 语句还可以写成 printf("%d ",arr[i][j]);
运行结果:
二.数组指针
是指针,该指针指向的是一个数组,其中存放的是数组的地址。
也就是说它首先得是 一个指针,然后再说明它所指向的是一个数组
具体如下图:
操作符优先级详解见:http://t.csdn.cn/mnrSk
当然数组指针一般不用于一维数组中,通常应用在二维数组及更高维的数组中
例:
1. void print(int(*parr)[5], int row,int col) 2. { 3. int i = 0, j = 0; 4. for (i = 0; i < row; i++) 5. { 6. for (j = 0; j < col; j++) 7. { 8. printf("%d ", *(*(parr+i) + j)); //*(parr+i)表示数组 arr 第i行的地址 9. } //加上j表示第i行的第j个元素的地址 10. printf("\n"); //对其解引用就找到了这个元素 11. } 12. } 13. int main() 14. { 15. int arr[2][5] = { 1,2,3,4,5,6,7,8,9,10 }; 16. print(arr, 2,5); 17. return 0; 18. }
运行结果:
三. 数组名 vs & 数组名 (arr vs &arr)
1.数组名和&数组名的值是一样的;
2.数组名和&数组名的意义不同。
请看代码:
1. int main() 2. { 3. int arr[5]={1,2,3,4,5}; 4. printf("arr=%p\n",arr); 5. printf("&arr=%p\n\n",&arr); 6. printf("arr+1=%p\n",arr+1); 7. printf("&arr+!=%p\n",&arr+1); 8. return 0; 9. }
打印结果:
这是为什么呢?
1.因为&arr 取出的是整个数组的地址,而数组的地址也是从首元素的地址开始的,数组名表示数组首元素的地址,所以打印时 arr 和 &arr 的值相同;
2.arr+1所加的其实是1个步长,步长是由数组类型决定的,arr 的类型是 int ,+1表示跳过4个字节,所以 arr 和 arr+1 相差四个字节;
3.&arr+1所加的是整个数组的长度,上方数组 arr 的长度是 20 个字节,所以&arr 和 &arr+1 相差20个字节(地址是以16进制的形式打印的,所以会呈现出这个效果)。
补充:
数组名是首元素的地址,但是有两个例外:
1.遇到sizeof时,计算的是整个数组的大小,单位是字节;
2.&数组名:数组名表示整个数组,取出的是整个数组的地址;
二维数组的数组名:
1.表示的是二维数组首元素的地址;
2.二维数组首元素的地址是第0行的地址。
四.数组指针与指针数组的辨析
例1:
例2: