美文网首页
数组指针

数组指针

作者: mark_x | 来源:发表于2019-07-31 10:18 被阅读0次

    与指针数组相比,数组指针更难理解一点,这里简单做一下对比,并重点说明什么是数组指针。

    指针数组

    • 从命名规则来看:
      数组就是集合,指针数组就是一堆指针,就是一堆指针集合在一起。
    • 从定义规则来看:
      int *p[4];。根据结合顺序,先执行p[4],是一个数组,然后int *说明元素类型是整型指针。
      前面提到过(指向指针的指针那篇),指针数组可以用来对一个数据集合进行再分类。

    数组指针

    那么什么是数组指针呢?

    • 从命名规则来看:
      整型指针意思是指向整型变量的指针,那么类比过来,数组指针就是指向数组变量的指针。
    • 从定义规则来看:
      int (*p)[4]。根据结合顺序,先执行(*p),是一个指针,然后[4],说明指向一个有四个整型变量的一维数组数组
      实际上,写成如下形式更容易理解:
      int [4] *p; // 定义指针,指向的数据类型是int [4]
      对比
      int *p; // 定义指针, 指向的数据类型是int

    指针的步长

    定义一个指针实际上需要给出两方面的信息,一个是指针指向的地址,对于数组而言,一般是数组的地址;二是指针的步长,也就规定了指针加1时,指向的地址移动多少位。

    指针与一维数组

    1. 指向一维数组首元素的指针

    #include <stdio.h>
    
    int main()
    {
        int a[] = {1, 2, 3, 4, 5};
        int *p = a;
        
        printf("p: %p, *p: %d\n", p, *p);
        printf("p+1: %p, *(p+1): %d\n", p+1, *(p+1));
        
        return 0;
    }
    
    // 输出结果:
    p: 0060FEF8, *p:1
    p+1: 0060FEFC, *p+1:2
    

    定义了一个指针,指向数组名,也就是指向数组的首元素地址,指针+1后,指针指向的位置往后移动4位,指向一维数组的第二个元素。

    2. 指向一维数组的指针
    首先说明一个结论,指向一维数组一般是不用数组指针的,如果强行使用呢?
    对上述代码进行简单地修改,以下代码正确么?

    #include <stdio.h>
    
    int main()
    {
        int a[] = {1, 2, 3, 4, 5};
        int (*p)[5] = a;
        
        printf("p: %p, *p: %d\n", p, *p);
        printf("p+1: %p, *(p+1): %d\n", p+1, *(p+1));
        
        return 0;
    }
    

    上面的代码中,定义一个数组指针指向一维数组a。
    编译警告:warning: initialization from incompatible pointer type

    我们从指针的两个要素分析一下ap
    a是数组名,根据前面的知识,我们知道,数组名也是首元素的地址,因此“指针a”的地址是首元素的地址;那么步长呢?在数组定义中已经指明这是一个存储整型变量的一维数组,因此步长是4个字节。综上,a其实就是一个指向整型元素的指针。int b = 10; int *a = b;中的a没有区别

    把p的定义改写一下形式,int [5] (*p)。p是一个数组指针,步长为一个包含5个整型变量的一维数组,也就是20个字节。显然嘛,两边指针不匹配。

    那么,如何修改才能使得正常编译并达到我们想要的效果呢?(在此注意,对于一维数组这样写纯粹是找麻烦,这里只是说明原理)。
    如何访问数组的第二个元素“2”呢?改写成一下形式:

    #include <stdio.h>
    
    int main()
    {
        int a[] = {1, 2, 3, 4, 5};
        int (*p)[5] = &a;  
    
        printf("a[1] = %d", *(*(p+0)+1));
        
        return 0;
    }
    

    数组首元素的地址的值和数组地址的值是相等的,但是步长不同。
    &a 是整个数组的地址(地址为首元素,步长为5),所以 &a + 1 指向整个数组最后的位置

    指针与二维数组

    二维数组才是数组指针的用武之地。通过数组指针索引二维数组元素。

    #include <stdio.h>
    
    int main()
    {
        int a[3][4] = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12}
        };
        
        int (*p)[4] = a;
            // int (*p)[3][4] = &a;
    
        printf("a[1][3] = %d", *(*(p+1)+3));
            //printf("a[1][3] = %d", *(*(*(p+1)+3)));
        
        return 0;
    }
    

    当然也可以采用注释的写法(这个还不太明白。。。)

    相关文章

      网友评论

          本文标题:数组指针

          本文链接:https://www.haomeiwen.com/subject/qgwarctx.html