c/c++ 指针数组 和 数组指针

看这个标题都要晕了,我们不妨把他拆开来理解,比较容易

指针数组:对象是一个数组,数组元素的类型是指针

指针数组的定义方式:

类型名 *数组名[数组长度];

如:

int *p[8];

数组指针:对象是一个指针,指针的类型是一个数组

数组指针的定义方式:

类型名 (*数组名)[数组长度];

如:

int (*p)[8];

无论是使用指针数组或是数组指针,都可以达到我们想要的效果,

下面我们就来比较一下两种对象操作数组的方式:

#include <stdio.h>

void main(int argc,char *argv[])
{
    int arr[4][4]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
    int (*p1)[4];
    int *p2[4];
    int i,j,k;

    p1=arr;

    printf("使用数组指针的方式访问二维数组arr
");

    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            printf("arr[%d][%d]=%d	",i,j,*(*(p1+i)+j));
        }
        printf("
");
    }

    printf("
使用指针数组的方式访问二维数组arr
");
    
    for(k=0;k<4;k++)
        p2[k]=arr[k];
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            printf("arr[%d][%d]=%d	",i,j,*(p2[i]+j));
        }
        printf("
");
    }

    return ;
}

输出结果都是0-15,说明访问方式都是正确的,下面我们来分析一下 数组指针 的访问元素的方式:

访问方式:  *(*(p1+i)+j)

根据运算符优先级,将这个运算过程拆开来分析

(p1+i) -> *(p1+i)  -> *(p1+i) +j-> *(*(p1+i)+j)

我们将它分为四个部分:

1. p1是指向数组的指针,数组的长度是4,也就是说,p1+1的话,内存地址实际是加了4(32位系统)位,这样的话,

  使用(p1+i)就可以找到数组中每个元素的地址

2. 使用取值运算将第一步的运算结果取值,开始我在这里疑惑了好久,开始我认为 *(p1+1) 的结果是等于4,对地址进行取值嘛,理所应当,

  然而结果并不是这样,*(p1+i)的结果是仍然是一个指针,为什么呢,因为我们的数组元素也是一个数组,也就是说,我们使用p1+i得到的也是一个数组指针,这样就理解通了吧,

  *(p1+i)得到的是二层数组的首地址

3.得到了二层数组的首地址之后,我们再加上偏移量i,就得到数据在数组中的地址了

4.得到了数据地址,使用取值符就可以得到真实数据了

看懂了数组指针,指针数组也就迎刃而解了

原文地址:https://www.cnblogs.com/trenail/p/3375709.html