有一个二维数组,我们需要把里面的元素都打印出来
#include <stdio.h>
int main()
{
int arr[3][4] = {{11,22,33,44},{12,13,15,16},{22,66,77,88}};
int i,j;
int *p;
p = &arr[0][0];
// p = arr;
for(i = 0; i < 3; i++){
for(j = 0; j < 4; j++){
printf("%d\n", *p++);
}
}
return 0;
}
这样是能打印出所有元素的,但是里面的 p = &arr[0][0] 能不能改成 p = arr 呢?
答案是可以,但是有警告,元素是能全部打印出来的;
为什么会有警告呢,因为 p++ 是里面一个元素一个元素的字节偏移,arr++是一个数组一个数组的字节偏移;
换算就是,p++ 是四个字节,四个字节的偏移,arr++是16个字节,16个字节的偏移。
但是为什么 printf("%d\n",*p++); 能打印出所有元素呢?
移动 *p, 也就是*arr, arr是二维数组,操作的是二维数组的首地址,也就是{11,22,33,44} ,*arr的时候,操作的是{11,22,33,44}的首地址,也就是11的首地址。所以结果是正确的。
为了消除警告,这时候就需要定义一个数组指针了;让它指向一个数组。
数组指针的定义如下:
int arr[3][4] = {{11,22,33,44},{12,13,15,16},{22,66,77,88}};
// 数组指针
int (*p)[4];
p = arr;
#include <stdio.h>
int main()
{
int arr[3][4] = {{11,22,33,44},{12,13,15,16},{22,66,77,88}};
int i,j;
int *p;
//p = &arr[0][0];
//p = arr;
// 数组指针,定义一个指针,指向一个数组
// 数组指针才是真正等同于二维数组名
int (*p2)[4];
p2 = arr;
//printf("p2=%p\n", p2);
//printf("p2++%p\n", ++p2); // 这里打印会发现地址是16个字节16个字节的偏移
for(i = 0; i < 3; i++){
for(j = 0; j < 4; j++){
//printf("%d\n", *p++);
printf("%d\n", *(*(p2 + i) + j));
}
}
return 0;
}
为什么说数组指针才是真正等同于二维数组名呢?
因为二维数组名就等同于首地址,移动也是移里面的一维数组。