指针数组和数组指针

O(∩_∩)O 兄弟们我又来了 今天又get到一个新的知识盲区了,冲冲冲!!!

4.阅读代码,用以下指针如何访问到 arr[2][2] 元素,前提是不能使
用强制类型转换。

int arr[4][3] = {1,2,3,4,5,6,7,8,9,10,11,12};
1.int *p1 = &arr[1][1]; _____________ *(p1+4)
2.int *p2 = arr[1] + 2; ____________ *(p2+3)
3.int (*parr1[3]) = &arr[1]; ____________
4.int (*parr2[3]) = arr + 2; ____________
5.int (*parr3[4][3]) = &arr; _____________

首先对题目进行分析,arr[2][2]=9;

1.第一题很简单,我们先对题目进行分析,

p1=&arr[1][1]  ,arr[1][1]=5,且p1 是个一级指针,且数组的内存时连续的我们要
偏移4个单位的内存空间,在本题中一个单位内存为sizeof(int)=4的大小

2.第二题跟第一题类似,p2=arr[1]+2=&arr[1][2] ,不懂得朋友可以去看我之前的博客,

其实这p2就是比第一题中的p1多偏移了一个单位而已,本质一样

3.大家看这题是不是有种一脸懵逼的感觉

其实这个题目有两种可能
1.int (*parr1[3])={&arr[1]};	//指针数组, &arr[1]可以近似当成 **arr 所以会有警告,(花括号很重要,不然会出错)
  4 int main(){
  5     int arr[4][3]={1,2,3,4,5,6,7,8,9,11,12};
  6     int (*parr[3])={&arr[1]}; //parr[0]里面其实是arr[1]的地址,即parr[0]=arr[1];
  7     printf("%d\n",*(parr[0]+5));
  8 
  9     return 0;
 10 }

zhizhen@zhizhen-VirtualBox:~$ gcc 1.c
1.c: 在函数‘main’中:
1.c:6:2: 警告: 从不兼容的指针类型初始化 [默认启用]
1.c:6:2: 警告: (在‘parr[0]’的初始化附近) [默认启用]
zhizhen@zhizhen-VirtualBox:~$ a.out
9
2.int (*parr1)[3] = &arr[1];	//数组指针,直接把地址作为值赋给指针parr1
  4 int main(){
  5     int arr[4][3]={1,2,3,4,5,6,7,8,9,11,12};
  6     int (*parr)[3]=&arr[1];
  7     printf("%d\n",(*parr)[0]);//parr[0][0]
  8     printf("%d\n",parr[0][5]);	//相当于偏移5个单位	
  9     printf("%d\n",parr[1][2]);	//相当于偏移3+2个单位 ,大家可以理解成一行有3个元素,偏移了一行又移动了2列
 10     return 0;
 11 }
4
9
9

4.第四题跟第三题类似,不再叙述。

5.这题跟前面两题类似

1.int (*parr3[4][3]) ={&arr};	//指针数组
  4 int main(){
  5     int arr[4][3]={1,2,3,4,5,6,7,8,9,11,12};
  6     int (*parr[4][3])={&arr};
  7     printf("%d\n",*(parr[0][0]+8));
  8     return 0;
  9 }

zhizhen@zhizhen-VirtualBox:~$ gcc 1.c
1.c: 在函数‘main’中:
1.c:6:2: 警告: 从不兼容的指针类型初始化 [默认启用]
1.c:6:2: 警告: (在‘parr[0][0]’的初始化附近) [默认启用]
zhizhen@zhizhen-VirtualBox:~$ a.out
9

2.int (*parr)[4][3]=&arr;
 4 int main(){
  5     int arr[4][3]={1,2,3,4,5,6,7,8,9,11,12};
  6 //  int brr[4][3]={11,21,31,41,51,61,71,81,91,111,121};
  7     int (*parr)[4][3]=&arr;
  8     printf("%d\n",(*parr)[2][2]);
  9     printf("%d\n",parr[0][2][2]);
 10     return 0;
 11 }

错误示例

  4 int main(){
  5     int arr[4][3]={1,2,3,4,5,6,7,8,9,11,12};
  6 //  int brr[4][3]={11,21,31,41,51,61,71,81,91,111,121};
  7     int (*parr)[4][3]=&arr;
  8     printf("%d\n",*parr[2][2]);
  9     printf("%d\n",parr[0][2][2]);
 10     return 0;
 11 }

zhizhen@zhizhen-VirtualBox:~$ gcc 1.c
zhizhen@zhizhen-VirtualBox:~$ a.out
-1532167008 //不是9哦
9

对于(*parr)[0][0]=parr[0][0][0]  这里的第一个0如果加1相当于偏移整个数组
  4 int main(){
  5     int arr[4][3]={1,2,3,4,5,6,7,8,9,11,12};
  6     int brr[4][3]={11,21,31,41,51,61,71,81,91,111,121};
  7     printf("%p\n",&arr[3][2]);
  8     printf("%p\n",&brr[0][0]);
  9     int (*parr)[4][3]=&arr;
 10     printf("%d\n",(*parr)[2][2]);
 11     printf("%d\n",parr[1][2][2]);
 12     return 0;
 13 }

zhizhen@zhizhen-VirtualBox:~$ gcc 1.c
zhizhen@zhizhen-VirtualBox:~$ a.out
0xbfcf2108	//两个数组内存相连
0xbfcf210c
9
91

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值