指针和数组

目录

区分概念:数组指针和指针数组

1.指针和一维数组

1.1一维数组元素的表示

1.2一维数组的遍历

2.指针和二维数组

2.1二维数组元素的表示

2.2二维数组的遍历

区分概念:数组指针和指针数组

数组指针:是指向一个数组的首地址的指针,其本质为指针。如:int (*p)[5]

指针数组:由若干个具有相同储存类型和数据类型的指针变量构成的集合,本质是是数组。     如:int *p[5]

1.指针和一维数组

1.1一维数组元素的表示

  当用指针指向一维数组的首地址后,一维数组的元素表示方法就有很多了,来看下面一段代码:

int s[5]={1,2,3,4,5};
int *p1=s;
//int *p2 = &s[0]; //这样也可以写

需要知道的是,指针的一次相加是以定义指针的数据宽度为单位的,而不是以字节位单位,也就是说当指针类型和指向的一维数组为同一类型时,指针+1指向的是数组的下一个元素。

printf("s[0]=%d  ",s[0]);
printf("*p1=%d  ",*p1);
printf("s[1]=%d  ",s[1]);
printf("*(p1+1)=%d  ",*(p1+1));
printf("*(s+1)=%d  ",*(s+1));

输出的结果为:

     由此得出结论:表示一维数组s的第i个元素,有下标法和指针法。假设指针变量指向数组中的首元素,则有四种表达方式,s[i]<=>p[i]<=>*(p+i)<=>*(a+i)

指针和数组常见的等价操作如下:

指针操作数组操作说明
array&array[0]元素首地址
*arrayarray[0]数组的首元素
array+i                        &array[i]数组第i个元素的地址

*(array+i)

array[i]数组的第i个元素
*array+barray[0]+b数组首元素的值加b
*(array+i)+barray[i]+b数组第i个元素的值加b
*array++(当前指向第i个元素)array[i++]先取得第i个元素的值,i再加1
*++array(当前指向第i个元素)array[++i]先将i加1,再取得第i个元素的值
*array--(当前指向第i个元素)array[i--]先取得第i个元素的值,i再减1
*--array(当前指向第i个元素)array[--i]先将i减1,再取得第i个元素的值

1.2一维数组的遍历

紧接上面的代码:

int len=0,i;
len=sizeof(s)/sizeof(int);
for(i=0;i<len;i++)
{
    printf("%d %d %d %d\n",s[i],p1[i],*(s+i),*(p1+i));
}

输出的结果为:

2.指针和二维数组

       首先要知道二维数组再内存中的储存形式:二维数组的元素连续存储,按行优先存储,存储了第一行的元素,存储第二行的,以此类推。

2.1二维数组元素的表示

        在没用用指针指向二维数组之前,二维数组元素的表示方法有:s[i][j]、 *(*(s+i)+j)、*(s[i]+j)

int s[3][3] = { {11,22,33},{44,55,66},{77,88,99} };
printf("**s=%d  ", **s);
printf("*(*s+1)=%d  ", *(*s + 1));//相当于*( * (s + 0) + 1)
printf("s[1][1]=%d  ", s[1][1]);
printf("*(*(s+1)+1)=%d  ", *( * (s + 1) + 1));
printf("*(s[1]+1)=%d  ", *(s[1] + 1));

        因为二维数组的数组名是行地址,对行指针取一个*操作,相当于对指针的降维,把操作空间是一整行的指针降维成操作空间是一个元素的指针,再取一次*操作,就可以读取到数据了。上述代码的运算结果为:

       由此可见s[i][j]<=> *(*(s+i)+j) <=>*(s[i]+j)

       当我们用指针指向二维数组时,二维数组元素的表示方法又多了很多。二维数组名为行地址,因此我们不能用一个普通的指针变量来指向二维数组,即使指向了也只能按照单个元素来操作,不能按照整行来操作,因此我们需要用到数组指针,来看下面一段代码:

int s[3][3] = { {11,22,33},{44,55,66},{77,88,99} };
int (*p)[3] = s;
printf("**p=%d  ", **p);
printf("*(*p+1)=%d  ", *(*p + 1));//相当于*( * (p + 0) + 1)
printf("p[1][1]=%d  ", p[1][1]);
printf("*(*(p+1)+1)=%d  ", *( * (p + 1) + 1));
printf("*(p[1]+1)=%d  ", *(p[1] + 1));

        代码的运行结果:

       也就是说p[i][j]<=> *(*(p+i)+j) <=>*(p[i]+j)

       联想到上面不难发现s[i][j]<=> *(*(s+i)+j) <=>*(s[i]+j)<=>p[i][j]<=> *(*(p+i)+j) <=>*(p[i]+j)

2.2二维数组的遍历

基于上述,遍历的代码不难写:

int i, j, r, c;
r = sizeof(s) / sizeof(s[0]);
c = sizeof(s[0]) / sizeof(int);
for (i = 0; i < r; i++)
{
	for (j = 0; j < c; j++)
	{
		printf("%d  %d  %d", s[i][j], *(*(s + i) + j), *(s[i] + j));
		printf("  %d  %d  %d", p[i][j], *(*(p + i) + j), *(p[i] + j));
		printf("\n");
	}	
}

代码的运行结果如下:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前进的小电灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值