数组指针

2019-07-31  本文已影响0人  mark_x

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

指针数组

数组指针

那么什么是数组指针呢?

指针的步长

定义一个指针实际上需要给出两方面的信息,一个是指针指向的地址,对于数组而言,一般是数组的地址;二是指针的步长,也就规定了指针加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;
}

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

上一篇 下一篇

猜你喜欢

热点阅读