美文网首页
指针与数组

指针与数组

作者: Jowney | 来源:发表于2018-09-05 17:41 被阅读8次

    原文1
    原文2
    一、数组指针(也称行指针)

    定义: int (* p)[n];
    将二维数组赋给一指针,应这样赋值:

    int a[3][4];
    int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
     p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
     p++;       //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
    

    所以数组指针也称指向一维数组的指针,亦称行指针。
    二、指针数组

    定义 :int * p[n];
    解释:[]优先级高,先与p结合成为一个数组,再由int说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素,这样赋值是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 * p=a; 这里p表示指针数组第一个元素的值,a的首地址的值。
    如要将二维数组赋给一指针数组:
    int *p[3];
    int a[3][4];
    p++; //该语句表示p数组指向下一个数组元素。注:此数组每一个元素都是一个指针
    for(i=0;i<3;i++)
    p[i]=a[i]
    这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
    所以要分别赋值。

    三、一维数组与指针

    假如有一维数组分析如下:

      char a[3] = {'a','b','c'} ;
    
    

    该数组一共有3个元素,元素的类型为char,如果想定义一个指针指向该数组,也就是如果想把数组名a赋值给一个指针变量,那么该指针变量的类型应该是什么呢?前文说过,一个数组的数组名代表其首元素的首地址,也就是相当于&a[0],而a[0]的类型为char,因此&a[0]类型为char *,因此,可以定义如下的指针变量:

      char * p = a;//相当于char * p = &a[0]
    

    a和&a[0]代表的都是数组首元素的首地址,如果你将&a的值也打印出来,会发现该值也等于数组首元素的首地址。请注意我这里的措辞,也就是说,&a虽然在数值上也等于数组首元素首地址的值但是其类型并不是数组首元素首地址类型,也就是char * p = &a是错误的
    因为对数组名进行取地址操作,其类型为整个数组,因此,&a的类型是char (*)[3],所以正确的赋值方式如下:

      char (*p)[3] = &a;
    

    四、二维数组与数组指针
    假如有如下二维数组分析如下:

      char a[3][2];
    

    由于实际上并不存在多维数组,因此,可以将a[3][2]看成是一个具有3个一维数组的集合,每个数组有2个元素。实际上,在内存中,该数组的确是按照一维数组的形式存储的,存储顺序为(低地址在前):a[0][0]、a[0][1]、a[1][0]、a[1][1]、a[2][0]、a[2]1

    i

    也就是说,我们可以将数组分成两个维度来看,首先是第一维,将a[3][2]看成一个具有三个元素的一维数组,每个元素是一个一维数组,元素分别为:a[0]、a[1]、a[2],其中,a[0]、a[1]、a[2]又分别是一个具有两个元素的一维数组(元素类型为char)。从第二个维度看,此处可以将a[0]、a[1]、a[2]看成自己代表”第二维”数组的数组名,以a[0]为例,a[0] (数组名)代表的一维数组是一个具有两个char类型元素的数组,而a[0]是这个数组的数组名(代表数组首元素首地址),因此a[0]类型为char *,同理a[1]和a[2]类型都是char 。而a是第一维数组的数组名,代表首元素首地址,而首元素是一个具有两个char类型元素的一维数组,因此a就是一个指向具有两个char类型元素数组的数组指针,也就是char()[2]。

    也就是说,如下的赋值是正确的:

     char (*p)[2]  = a;//a为第一维数组的数组名,类型为char (*)[2]
     char * p = a[0];//a[0]维第二维数组的数组名,类型为char *
    

    同样,对a取地址操作代表整个数组的首地址,类型为数组类型(请允许我暂且这么称呼),也就是char (*)[3][2],所以如下赋值是正确的:

      char (*p)[3][2] = &a;
    

    五、三维数组与数组指针

    假设有三维数组分析如下:
    同样,为了便于理解,特意画了如下的逻辑内存图。分析方法和二维数组类似,首先,从第一维角度看过去,a[3][2][2]是一个具有三个元素a[0]、a[1]、a[2]的一维数组,只是这三个元素分别又是一个"二维"数组,a作为第一维数组的数组名,代表数组首元素的首地址,也就是一个指向一个二维数组的数组指针,其类型为char ()[2][2]。从第二维角度看过去,a[0]、a[1]、a[2]分别是第二维数组的数组名,代表第二维数组的首元素的首地址,也就是一个指向一维数组的数组指针,类型为char()[2];同理,从第三维角度看过去,a[0][0]、a[0][1]、a[1][0]、a[1][1]、a[2][0]、a[2][1]又分别是第三维数组的数组名,代表第三维数组的首元素的首地址,也就是一个指向char类型的指针,类型为char *。

    image

    由上可知,以下的赋值是正确的:

     char (*p)[3][2][2] = &a;//对数组名取地址类型为整个数组
     char (*p)[2][2]  = a; char (*p) [2]  = a[0];//或者a[1]、a[2]
     char *p = a[0][0];//或者a[0][1]、a[1][0]...
    

    相关文章

      网友评论

          本文标题:指针与数组

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