七、数组指针 && 指针数组

7.1 数组指针

数组指针 的意思,即为通过 指针 引用 数组,例如int (*p)[10],此时 p 是一个 指针变量 ,指向一个数组大小为 10 的 数组,所以int (*p)[10]即为一个数组指针。

二维数组与数组指针的关系

  • 在我们对指针进行加法(减法)运算时,它前进(后退)的步长与它指向的数据类型有关

    • p指向的数据类型是int[4],那么p+1就前进4×4=16个字节,p-1就后退16个字节,这正好是数组a所包含的每个一维数组的长度。

    • 也就是说p+1会使得指针指向二维数组的下一行,p-1会使得指针指向数组的上一行。

  • 数组名a在表达式中也会被转换为和p等价的指针。

下面我们使用指针 p 来访问二维数组中的每个元素,按照上面的定义:

  • p 指向数组a的开头,也即第0行;p+1前进一行,指向第1行。

  • *(p+1) 表示取地址上的数据,也就是整个第1行数据。注意是一行数据,是多个数据,不是第1行中的第0个元素,下面的输出结果证明了这一点:

     #include<stdio.h>
     int main(){
         int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
         int(*p)[4]=a;
         printf("%d\\n",sizeof(*(p+1)));
         return0;
     }
     输出结果: 16

  • * ( p+1)+1 表示第1行第1个元素的地址。*(p+1)单独使用时表示的是第1行数据,放在表达式中会被转换为第1行数据的首地址,也就是第1行第0个元素的地址,因为使用整行数据没有实际的含义,编译器遇到这种情况都会转换为指向该行第0个元素的指针;就像一维数组的名字,在定义时或者和sizeof、&一起使用时才表示整个数组,出现在表达式中就会被转换为指向数组第0个元素的指针。

  • *( * ( p+1 ) + 1 ) 表示第1行第1个元素的值。很明显,增加一个*表示取地址上的数据。

可以简单导出以下的等价关系:

  a+i == p+i

  a[i] == p[i] == * ( a+i ) == * ( p+i )

  a[i] [j] == p[i] [j] == * ( a [i]+j)== * ( p[ i ] +j) == * ( * (a+i)+j)== * ( * (p+i)+j)

7.2 指针数组

由于运算符优先级[]优先级大于*,若定义为int *p[10],此时该定义为一个大小为10、用来存放指针的数组,即为指针数组。

7.3 数组指针与指针数组的区别

指针数组和二维数组指针在定义时非常相似,只是括号的位置不同:

  int *(p1[5]);//指针数组,可以去掉括号直接写作 int *p1[5];

  int (*p2)[5];//二维数组指针,不能去掉括号

  指针数组和二维数组指针有着本质上的区别:指针数组是一个数组,只是每个元素保存的都是指针,以上面的p1为例,在32位环境下它占用4×5=20个字节的内存。二维数组指针是一个指针,它指向一个二维数组,以上面的p2为例,它占用4个字节的内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值