指向数组的指针和二维数组

1.指针的值代表其指向对象的起始地址,指针的类型代表读取该对象是从该地址开始要往前读取多少个字节(什么时候结束)
而且这段内存该如何解析(是整数还是浮点数等)
可以用sizeof(*指针)来求得指针指向类型的大小。


2对于一维数组:若int a[10],则a为该数组的首个元素的常量指针,指向a[0],可通过首地址加偏移量的方法对其它元素进行寻址。a[i]的地址应为a+i。而&a则为指向有10个整型元素数组的常量指针。&a指向的数组为(*&a)[0],(*&a)[1],......

#include<stdio.h>
#include<stdlib.h>
void main()
{
    int i;//用于计数
    int a[5]={1,2,3,4,5};
    int *pp;
    int (*ppa)[5];//指向数组有5个元素的指针
    printf("%x %x\n",a,&a);//地址相同的,但读取时什么时候结束不同
    printf("%d %d\n",sizeof(*a),sizeof(*(&a)));//输出420;一个是指向a[0],另一个是指向数组
    pp = a;
    ppa = &a;
    printf("\n");
    for(i=0;i<5;i++)
    {
        printf("%d,%x\n",a[i],a+i); 
    }
    printf("\n");

    for(i=0;i<5;i++)
    {
        printf("%d,%x\n",(*ppa)[i],(*ppa)+i);
        //ppa指向的数组为:(*ppa)[0],(*ppa)[1],(*ppa)[2],(*ppa)[3],(*ppa)[4]
        //*ppa才为指向数组a首个元素的指针
    }
    //等价于
    //printf("\n");
    //for(i=0;i<5;i++)
    //{
    //  printf("%d,%x\n",(*&a)[i],(*&a)+i); 
    //}

    getchar();
}

3.对于二维数组,其元素的引用是将二维数组退化到对应的一维数组后,再通过该一维数组首个元素的地址+偏移量来对其它元素进行寻址的。
对于int a[3][4],数组名a是指向第一行有4个元素数组的指针,则a指向的数组为(*a)[0],(*a)[1],(*a)[2],(*a)[3],对应的地址为*a+0,*a+1,*a+2,*a+3 ,因此a指向类型大小为16个字节。而(*a)指向第1行对应行数组第一个元素,地址给该行数组的首地址,即a[0](相当于一维数组的数组名),再通过加上偏移地址j得到a[0]+j得到对应的元素。因此,*a与a[0]是等价的,a与&a[0]是等价的,而且由于a指向一维数组,而a+1的实际地址为a+4*sizeof(int),指向下一行数组的首地址。

#include<stdio.h>
#include<stdlib.h>
    //*指针取出指向类型 
    //a是指向每一行的指针
    //&a指向整个二维数组的指针
    //*a指向元素
    //相同地址,即同一个地方开始,但不同类型就是不同地方结束
void main()
{
    int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
    int *p1;
    int (*p)[4];//定义指向有四个整型元素的一维数组的指针
    int(*pp)[3][4];//定义指向具有三行四列的二维数组的指针
    int i,j;//用于计数

    printf("%d,%d,%d\n",a,&a,*a);//地址相同
    printf("%d,%d,%d\n",sizeof(*a),sizeof(*&a),sizeof(**a));//指向类型大小分别为16 48 4

    printf("\n数组元素即对应的地址:\n");
    for (i=0;i<3;i++)//输出每个元素的值及其地址
    {
        for(j=0;j<4;j++)
        {
            printf("%3d,%x ",a[i][j],&a[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    p=a;
    for(j=0;j<4;j++)
    {
        printf("%3d,%x ",(*p)[j],(*p)+j);
    }
    printf("\n");
    for(j=0;j<4;j++)
    {
        printf("%3d,%x ",(*a)[j],(*a)+j);
    }
    printf("\n");
    for(j=0;j<4;j++)
    {
        printf("%3d,%x ",a[0][j],a[0]+j);//第一行的首个元素的地址为*p,*a,a[0]相当于一维数组的数组名
    }
    printf("\n");
    p=a;
    printf("\n");
    for (i=0;i<3;i++)
    {
        printf("%x,%x\n",p++,a+i);
        //p是指向数组的指针变量,p++后p=p+4*sizeof(int),
        //而a是指向第一行数组的指针常量,a+i也指向数组的常量指针地址为a+i*4*sizeof(int)
    }

3总结

1).如何理解:

如果用立体,面,线及点来代表三维数组、二维数组,一维数组、和元素,高维数组名为指向低一维数组的指针,即三维素组的数组名为指向第1层的二维数组的指针,二维数组名为指向第1行的行数组的指针,而一维数组名为指向第一个元素的指针。给出的都是首层、首行或首个元素的地址,通过首地址+偏移量的方法,可确定当前维度,注意:指针+1,相当于指向下一个同类型的数组。如a为三维函数数组名,a指向第1层的二维数组,而a+1指向第2层的二维数组。而*数组名则为指向更低一维数组的指针,即低一维数组的数组名,不断重复上述方法,将高维退化为低维,直至指向元素的指针,最后确定在对应一维所在的列。如对于三维数组a[2][2][2],要取a[0][1][1],首先a为int(*)[2][2]的指针,指向第1层的二维数组,元素包括(*a)[0][0],(*a)[0][1],(*a)[1][0](*a)[1][1]*a由相当于二维数组名,为int(*)[2],指向第1层二维数组中,指向第1行数组的指针。*a+1指向第一层第二行数组的指针,*(*a+1)int(*)[2],相当于一维数组名,指向a[0][1][]数组的第一个元素,*(*a+1)+1为对应a[0][1][1]的地址。

2).如何使用:

a[i][j][k]=*(*(*(a+i)+j)+k)

请大虾指点指点!谢谢!!

猜你喜欢

转载自blog.csdn.net/thriveluo/article/details/47294765