数组指针在一维数组和二维数组中应用

数组指针:指向数组整个元素的指针,不是指向数组首元素的地址的,但指针的值等于数组首元素的地址,本质是指针,要仔细理解下。

指针的数组:是一个数组,什么样的数组呢?装着指针的数组。

然后,需要明确一个优先级顺序:()>[]>*,所以:

(*p)[n]:根据优先级,先看括号内,则p是一个指针,这个指针指向一个一维数组,数组长度为n,这是“数组的指针”,即数组指针;

*p[n]:根据优先级,先看[],则p是一个数组,再结合*,这个数组的元素是指针类型,共n个元素,这是“指针的数组”,即指针数组。

首先看个例子:

数组指针指向一维数组

int arr[5]={12345};

int (*p1)[5] = &arr;

/*下面是错误的*/

int (*p2)[5] = arr;

不难看出,在上面的示例代码中,&arr 是指整个数组的首地址,而 arr 是指数组首元素的首地址(arr=&arr[0]),虽然所表示的意义不同,但二者之间的值却是相同的。那么问题出来了,既然值是相同的,为什么语句“int(*p1)[5]=&arr”是正确的,而语句“int(*p2)[5]=arr”却在有些编译器下运行时会提示错误信息呢(如在 Microsoft Visual Studio 2010 中提示的错误信息为“a value of type"int*"cannot be used to initialize an entity of type"int(*)[5]"”)?

其实原因很简单,在 C 语言中,赋值符号“=”号两边的数据类型必须是相同的,如果不同,则需要显示或隐式类型转换。在这里,
p1 和 p2 都是数组指针,指向的是整个数组。p1 这个定义的“=”号两边的数据类型完全一致,而 p2 这个定义的“=”号两边的数据类型就不一致了(左边的类型是指向整个数组的指针,而右边的数据类型是指向单个字符的指针),因此会提示错误信息。

数组指针指向二维数组也是类似的:

int(*p)[10];

//()的优先级高,()先将p生命为指针,定义了一个指向长度为10 的整型数组的指针

//p+i是指指针移动了i个长度为10 的数组,若p指向了第一个数组,则p+i指向第i+1个数组

int   a[10][10];

p=a; //p指向a[10]

p++ ; //p指向a[1],移动单位是行或者一个长度为10 的数组,10个元素为一行,数组指针也叫行指针

 

另一个概念,指针数组 *p[n]

指针数组:是数组——装着指针的数组。

看下面的例子进行理解:

#include "stdio.h"

int main()

{

          int a = 1;

          int b = 2;

          int *p[2];

          p[0] = &a;

          p[1] = &b;

 

          printf("%p\n", p[0]); //a的地址

          printf("%p\n", &a); //a的地址

          printf("%p\n", p[1]); //b的地址

          printf("%p\n", &b); //b的地址

          printf("%d\n", *p[0]); //p[0]表示a的地址,则*p[0]表示a的值

         printf("%d\n", *p[1]); //p[1]表示b的地址,则*p[1]表示b的值

         return 0;

}

从上面可以看出,指针数组的每个元素都是一个指针,跟定义的普通指针一样使用

 

数组指针 (*p)[n]例子

#include "stdio.h"

int main()

{

          //一维数组

          int a[5] = { 1, 2, 3, 4, 5 };

          //步长为5的数组指针,即数组里有5个元素

          int (*p)[5];

          //把数组a的地址赋给p,则p为数组a的地址,则*p表示数组a本身

          p = &a;

 

          //%p输出地址, %d输出十进制

          //C中,在几乎所有使用数组的表达式中,数组名的值是个指针常量,也就是数组第一个元素的地址,它的类型取决于数组元素的类型。

          printf("%p\n", a); //输出数组名,一般用数组的首元素地址来标识一个数组,则输出数组首元素地址

          printf("%p\n", p); //根据上面,p为数组a的地址,值等于数组a首元素的地址

          printf("%p\n", *p); //*p表示数组a本身,一般用数组的首元素地址来标识一个数组

          printf("%p\n", &a[0]); //a[0]的地址

          printf("%p\n", &a[1]); //a[1]的地址

          printf("%p\n", p[0]); //数组首元素的地址

          printf("%d\n", **p); //*p为数组a本身,即为数组a首元素地址,则*(*p)为值,当*p为数组首元素地址时,**p表示首元素的值1

          printf("%d\n", *p[0]); //根据优先级,p[0] 表示首元素地址,则*p[0]表示首元素本身,即首元素的值1

          printf("%d\n", *p[1]); //表示a[5],数组已经越界,指向最后一个元素的下一个元素的地址,实际不存在

          printf("%d\n", *(p[1]-1)); //数组最后一个元素的值

          //将二维数组赋给指针

          int b[3][4];

          int(*pp)[4]; //定义一个数组指针,指向含4个元素的一维数组

          pp = b; //将该二维数组的首地址赋给pp,也就是b[0]&b[0],二维数组中pp=bpp=&b[0]是等价的

          pp++; //pp=pp+1,该语句执行过后pp的指向从行b[0][]变为了行b[1][]pp=&b[1]

          return 0;

}

执行结果:

lwl@lwl:~/test$ ./test
0x7ffc95d481b0
0x7ffc95d481b0
0x7ffc95d481b0
0x7ffc95d481b0
0x7ffc95d481b4
0x7ffc95d481b0
1
1
1600061541
5
 

总结:

1.数组指针是一个指针变量,可以等价于一个二维数组,数组指针是一个指针变量,在数值上,p是指向二维数组整个元素的地址, *p,p[0]都指向二维数组首元素地址,在内存中存储地址,二维数组整个元素的地址和二维数组首元素的地址都是同一个位置,它们的值是相同的。

2.数组指针指向的是整个数组元素地址,不管是指向一维数组还是二维数组,都是指向整个数组的。数组指针在一维数组中优点多余,没必要使用,在c/c++里可以专门用来指向二维数组。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值