指针和二维数组的关系有点绕,需要细细分析。通过代码的方式,打印地址去理解。
1.定义一个指向一维数组的数据的指针
格式:数据类型 * 指针变量名称 = 数组名称[一维数组的下标]
2..定义一个指针的数组:
格式:数据类型 * 指针变量名称[指针个数]
3.定义一个指向一维数组的指针
格式:数据类型 (*指针名称)[所指向的一维数组的元素个数]
运算:指针 + 整数 == 指针中的值 + (所指向数据类型的长度 * 整数)
注意点在代码中:
void test(){// 1.定义一个指向一维数组的数据的指针
int nums[2][2] = {{1,2},{3,4}};//num[0][0],num[0][1],num[1][0],num[1][1]四个数
//int *p = nums; p是一个指向整形数的指针 nums是一个指向一维数组的指针 虽然地址相同,但是指向的类型不同
int *p = nums[0];//定义指针p指向一维数组的地址,是指向一个数据
printf("%p\n",p);//p指向的地址0x7fff5fbff780
printf("%p\n",nums);//p指向的地址0x7fff5fbff780
printf("%p\n",nums[0]);//p指向的地址0x7fff5fbff780 前面都是相同的
printf("%p\n",nums[1]);//p指向的地址0x7fff5fbff788 第二个一维数组的地址
for (int i = 0; i < 4; i++) {//因为这个2为数组的内存地址是连续的,所以可以通过指针运算打印
printf("%d ",*(p + i));//如果i < 6,当i = 5或6的时候所指向的地址是我们未知的
}
}
void test2(){
//2.定义一个指针数组
//定义指针数组的格式:
//数据类型 * 指针变量名称[指针个数]
int a = 1;
int b = 2;
int c = 3;
int *p[3] = {&a,&b,&c};
*p[0] = 10;
*p[1] = 20;
*p[2] = 30;
*(p[0] - 1) = 30;//其实是指向p[1]的地址
printf("%p,%p,%p\n",p[0],p[1],p[2]);
//0x7fff5fbff744,0x7fff5fbff740,0x7fff5fbff73c从大得地址开始分配(注意)
//跟数组先分配一整块内存地址,再从小分配不一样
printf("%d,%d,%d\n",a,b,c);
}
void test3(){
//3.定义一个指向一维数组的指针
//格式:数据类型 (*指针名称)[所指向的一维数组的元素个数]
//指针 + 整数 == 指针中的值 + (所指向数据类型的长度 * 整数)
int nums[2][2] = {{1,2},{3,4}};
int (*p)[2] = nums;
printf("%p\n",p);//地址0x7fff5fbff780
printf("%p\n",p + 1);//地址0x7fff5fbff788
printf("%d\n",*p[0]);//打印1
printf("%d\n",*p[1]);//打印3
printf("%d\n",p[0][1]);//打印2 这边不需要*操作符
printf("%p\n",nums);//地址0x7fff5fbff780
printf("%p\n",nums+1);//地址0x7fff5fbff788
printf("%p\n",nums[1]);//地址0x7fff5fbff788
}
int main(int argc, const char * argv[]) {
/*
在二维数组中当指针指向nums和nums[0]他们到底有什么不同?
相同点:对应地址都是一样的
不同点: 指针类型是不同 nums是一个指向一位数组的指针、nums[0]是一个一维数组的地址
nums + 1 = nums + sizeof(nums[0]) nums指向数组
nums[0] + 1 = nums + sizeof(int) nums[0]指向数据
sizeof(nums) 二维数组所用占用存储空间字节数
sizeof(nums) / sizeof(int) 二维数组中一共有多少个int的数据
*/
int nums[2][2] = {{1,2},{3,4}};
int *p = nums[0];
for (int i = 0; i < sizeof(nums) / sizeof(int); i++) {
printf("%d ",p[i]);//输出 1 2 3 4 道理同上面的test()函数类似
}
return 0;
}