C语言中,一级指针,二级指针,数组,一位数组指针,二位数组指针浅谈

最近在做linux内核中发现,有很多关于指针和数组的应用问题,细细研究,发现受益匪浅,将整个分析和收获分享出来,希望高手指正。

1.指针

    指针,顾名思义,就是指向一个内存单元的特殊数据单元,这个很好理解,如:

        int a;

        int *p;

        a = 10;

        p = &a;

        printf("a=%d,*p=%d\n",a,*p);

    上面代码中,p存储的是a变量的地址值,如果直接打印p值,发现p中显示的是一段地址值,即存储a变量的地址值。而*p表示取地址中的变量,即a的值,

上述打印中,a == *p==10 。

    而多级指针,也很好理解,即存储的变量是指针变量的地址,如:

        int **pp = &p;

    其中pp是二级指针,pp中的值存储的是指针变量p的地址在,如果打印pp的值,则存储的是p的地址值,而*pp则存储的是p指向的地址值即a的地址值,因此,

 **pp == *p==a;多级指针以此类推,并不难理解。

2.数组

    数组,是一段在内存空间连续存储的变量集合,单纯说数组,并不难理解,如

        int a[10];

        int b[10][10];

    其中,a[10]表示一维数组,b[10][10]表示的是二维数组,按照存储方式来说,所有的多维数组其实都是一维数组,是一段连续的存储空间,而数组的访问,是依靠数组名来进行的,而数组名是一种非常特殊的指针,也是本篇文章写作的重点,理解了数组与指针的关系,才敢说,自己刚刚进入了c语言的门。

3.数组与指针

     这篇文章,主要是想说数组与指针的问题,前面只是做了简单的介绍,首先,如下代码:

        int arryA[10]={0,1,2,3,4,5,6,7,8,9};

        printf("arrayA[0]=%d,*arrayA=%d,arrayA[3]=%d,*(arrayA+3)",arrayA[0],*arrayA;arrayA[3],*(arrayA+3));

     上述函数的打印结果会发现,arrayA[0]=*arrayA=0;arrayA[3]=*(arrayA+3)=3; 通过上面的程序,可以发现,数组变量名就是一个指针,而后面的[3]等价于指针移动3位。

    而对于二位数组,则情况变得复杂起来,如下代码:

        int arrayD[3][4]={{0,1,2},{3,4,5},{6,7,8},{9,10,11}};

    定义的二位数组,打印会发现 arrayD==*arrayD,这个问题一度令我非常困惑,按照指针的理解,arrayD变量中,存储的地址是arrayD的地址值,而**arrayD == 0,即二位数组的第1个元素arrayD[0][0];按照指针的理解,则会发现逻辑是如下情况arrayD --> arrayD -->arrayD[0][0],非常不好理解,但是确实是这样的,只能理解为数组变量名是一种特殊的指针。而二维数组名究竟是一级指针还是二级指针还真不能靠指针理解,只能作为一种特殊的变量理解,具体分析还在研究中。

    而对于数组与指针之间的赋值,则非常有意思,一位数组对应一级指针,二位数组对应二级指针,进行如下操作

        int * p = arrayA;

        int **pp = arrayD;

   发现,p[1]=arrayA[1],p[n]=arrayA[n];可以很好的对应,而pp[0][1]则是错误的访问,pp[0]=0,pp[1]=3;...,这个问题也十分的令人疑惑,这个其实是一个巧合,pp[0]表示的是arrayD[0]+0,而pp[1]表示的是arrayD[0]+sizeof(arrayD[]),即pp的指针向后移动了一个指针单元长度,这样直接将二位数组,赋值给二位指针是一种错误的方式,将一位数组直接赋值给一级指针如果保证指针类型与数组类型相同,也是可以的,如果不同,则也是错误的。

    这样,数组是有自己的指针定义方式的,定义如下:

        int (*pArry)[];

        int(*ppArry)[][Num];

    上述分别表示了一维数组指针和二位数组指针,指针赋值可以按照如下方式:

        pArray=arrayA;//或者pArray=&arrayA[0]

        ppArray=arrayD;//或者ppArray=&arrayD[0][0]

    这样就可以直接操作数组指针了,然而,操作数组指针中,发现并不和我们想象的那样,pArray的类型是一位数组类型,则pArray+1表示指针移动了arrayA大小的位置,如果想访问arrayA[0],并不能简单的使用pArray[0]访问,相信很多人都遇到过这种迷惑,那么该如何访问? (*pArray)[n], 这个方式是标准的访问方式,在很长的一段时间里,我完全无法理解这样的访问方式,同样,二位数组的访问也是如此(*ppArray)[0][1],在互联网上还是很少有对这个问题进行说明。

    在上面数组和指针分析后,还有一种特别有用的使用方法,如下:

        int **p;

   如果想反问*p的一位指针,则可以使用p[0],这个使用方式在树形结构中很有用。


4.应用实例


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值