C的实用笔记27——数组指针(指针引用二维数组的桥梁)

1.如何通过普通指针间接访问二维数组的每个元素?合理吗?

1、第一步,如何用普通指针保存二维数组的首地址
  1. 正确的做法:将二维数组第0行第0列的元素的地址赋值给指针。背后的逻辑:&a[0][0] 、 a[0] 、 *a 三者在逻辑上是等价的,这些“指针”的类型都是int *型的
    #include <stdio.h>
    int main(int argc, char const *argv[])
    {
        int arr[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};
        int i, j;
        int *parr = &arr[0][0];			//第0行第0列的元素的地址
        return 0;
    }
    或者: int *parr = a[0];   或者   int *parr = *a

  2. 被警告的做法(也可以运行):将二维数组的名字arr赋值给指针。背后的逻辑:arr 这个“指针”的类型是 int (*)[4]类型的,与普通指针的int *类型不匹配,语句上虽然合法,但是我们要避免使用
    #include <stdio.h>
    int main(int argc, char const *argv[])
    {
        int arr[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};
        int i, j;
        int *parr = arr;
        return 0;
    }

2、一种可行的做法:回顾在一维数组中,我们可以通过指针进行间接访问数组元素,它有以下三种可行方式,但是只有一种能用在二维数组身上:

  1. 指针下标法:行不通,因为二维数组在内存中是连续存储的,用指针保存二维数组的第0行第0列的地址后,就相当于把二维数组看成一维数组,那么下标只能有一个,也就是parr[ 1 ] 是可行的,但是parr[ 1 ][ 0 ]是错的。
  2. 指针偏移后取星花:行不通,原因同上。
  3. 指针自加取星花:行得通,因为二维数组在内存中是连续存储的。
    #include <stdio.h>
    int main(int argc, char const *argv[])
    {
        int arr[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};
        int i, j;
        int *parr = &arr[0][0];
        for(i=0; i<3; i++){
            for(j=0; j<4; j++){
                printf("%d ", *parr++);		//通过一维指针自加后取星花能访问二维数组元素
            }
            putchar('\n');
        }
        return 0;
    }

3、用普通指针访问二维数组不合理:虽然说二维数组名arr是可以赋值给int *类型的指针parr,但是 parr++ 和 arr++ 的跨度不一样,没法用之前的结论:通过二维数组的父子数组名偏移的方式来间接访问二维数组的元素

2.数组指针的引入

1、数组指针的概念:数组指针本身是一个指针变量,它指向一个数组,它不是数组。如图:

 

2、数组指针的类型:指针变量有四要素,其中指针的类型十分重要。数组指针关心这个指针指向的数组中有几个元素,于是,当你定义数组指针时,中括号里面的数字不一样,代表你定义的数组指针就是不同类型的。如下:

int (*p1)[4];
int (*p2)[5];
p1 和 p2,这两个指针的类型不一样,体现在:
	1.它们能访问的内存空间不同;p1一次性能够访问4*4=16字节的内存空间;p2一次性能够访问5*4=20字节的空间
    2.它们自加后的跨度不同:   p1++后,指针p1往后移动16字节;p2++后,指针p2往后移动20字节。

3、数组指针为啥这样写?(通用的类型判别方法):

  1. 数组指针首先它得是一个指针,所以用小括号把*p括起来是为了先让修饰符*和p结合,确保p是一个指针;其次,关心的是这个指针指向的数组中有几个元素,也就是中括号里面的数字;最后,关注的是数组指针这个指针指向的数组,数组里面的元素是什么数据类型的。
    int (*p)[4];		//数组指针,指针指向的数组中有4个元素,每个元素是int类型的。
    int *p[4];			//指针数组,数组中有4个元素,每个元素是int *类型的。

  2. 适用于变量、指针、函数的类型判别方法
    1. 找到变量名,若没有变量名,找到最里面的结构
    2. 向右看,读出看到的东西,不要跳过括号
    3. 向左看,读出看到的东西,不要跳过括号
    4. 若有括号,跳出第一层括号
    5. 重复上述过程,直到读出最终的类型
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值