复杂类型(二)一个题目引发的博文

        前段时间有朋友给了我一道指针的习题,我当时并没有做对。并且输出的结果让我很是不解。今天仔细学复杂类型的时候,忽然灵光一现想起此道题并仔细琢磨一阵明白其中的幽微之处,遂写下此博文以记之。

题目代码如下:

int _tmain(int argc, _TCHAR* argv[])
{

    int a[5]={1,2,3,4,5};
    int *p;
    p=(int *)(&a+1);
    printf("%d\n",*(p-1));
    return 0;
}

 问:程序运行输出结果是多少? 

  我当时的回答是:1;当时的想法是&a+1 为 a[0]的地址加1,那么p所指向的是a[1],输出的时候在对p进行了减1 所以p指向a[0];

  正确的解法应该是:

   1、在解决这个题目时 我们首先要清楚对于数组a[5]来讲 a 与&a 的区别(这个题目的关键之处)。

     ok 我们先来看看a与&a所指向的空间占的字节数。

     对a来说我们都很熟悉 a指向的是数组a[0]的地址那么它所指的向空间占的字节数为4。

     对&a在这里我们要稍稍的变通一下,我们都知道下面代码中

       由 int a=6; int *p=&a; 可得到p是指向a的,那么p所指向的空间占的字节数与sizeof(a)的值是相等的。

       用代码来看一下       

int _tmain(int argc, _TCHAR* argv[])
{

    int a=6;
    int *p=&a;
    printf("%ld %ld\n",sizeof(*p),sizeof(a));

    return 0;
}

结果也验证了:
    

那么对于数组&a的类型,我们可以先假设一个指针q=&a;那么对于指针q所指向空间占的字节数应该为 sizeof(a);用代码来看看他的字节数: 

int _tmain(int argc, _TCHAR* argv[])
{

    int a[5]={1,2,3,4,5};
    printf("%ld\n",sizeof(a));

    return 0;
}

  结果:

而我们的整个数组所占用的字节数刚好为20个字节,说明了该指针q指向了我们的整个数组a;使我们想到了指针数组,那么q应该是 int (*q)[5] ,ok弄清楚了&a的类型就好办了,对与表达式&a+1 则为从a[0]的地址算起加上20个字节,刚好跳出了数组a。实际上p所指向的地址应该为p=a+5, 在输出函数中对p进行了减一 此时的p=a+4;神奇的又使p指向了数组的最后一个元素。从而输出结果为5。

 

    


 

posted @ 2014-03-29 22:48  这夏  阅读(165)  评论(0编辑  收藏  举报