• 指针(二)


    上次对指针进行了初步认识,接下来,继续挖掘C语言的
    指针与一维数组:
     
    这时编译是没有问题的:
     
     
     
    编译:
     
     
     
     
    输出结果:
     
    这里面会有点绕,但很重要,先运行一段程序,再来阐述上面的观点:
    #include <stdio.h>
    
    int main(void)
    {
        int a[] = {1, 2, 3, 4, 5};
        int* p = a;
    
        printf("%p
    ", a);
        printf("%p
    ", &a);
        
        printf("%p
    ", a+1);
        printf("%p
    ", &a+1);
        return 0;
    }

    运行结果:

    结果 a+1 和 &a+1 输出不一样,这时怎么回事呢,且听我慢慢分析:

    因为a表示int*,是一个int类型的指针,所以a+1偏移的是一个元素是一个int类型,既4个字节,所以0xbff7f218 + 0x4变成了0xbff7f22c。

    &a表示指向数据变量的指针(数组指针),所以&a+1偏移的一个元素是一个数组int[5]类型,既20个字节: 所以0xbff7f218 + 0x14变成了9xbff2f22c

    记住:上面提到了数组指针,下面对其进行一个介绍,注意下面两个区别
    数组指针:
      int (*p)[5] 这里的p是一个指针,指向一个具有5个元素的数组指针
    指针数组:
      int *p[5] 这里的p是一个数组,数组中的元素类型是int*
     
    接着用程序验证一下上面指出的理论:
     
    编译一下,出错了:
     
    再改编一下:
     
    这时编译,则成功了:
     
    注意以下意图表示“数组指针”的方法:
     
    编译:
     
    理解了上面的东西,下面以一个例子,以多种方式来打印数组的元素(理解这段程序的前提,需理解上面所学到的)
    #include <stdio.h>
    
    int main(void)
    {
        int a[5] = {1, 2, 3, 4, 5};
        int i;
        int* p;
    
        for (i=0; i<5; i++)
        {
            printf("a[%d]=%d, *(a+%d)=%d
    ", i, a[i], i, *(a+i));
            printf("&a[%d]=%p, a+%d=%p
    ", i, &a[i], i, a+i);
        }
    
        //以指针的方式打印元素
        for (p=a; p<a+5; p++)
        {
            printf("address:%p, value:%d
    ", p, *p);
        }
    
        return 0;
    }

    输出结果:

     
    指针与二维数组:
     
    这里面比较绕,一一分析来理解:
    (回顾)
    对于一维数组int a[3];
    数组名a可以看成是一个常量指针,类型相当于int*,也就是一个整型指针
     
    对于二维数组int a[3][4]:
    数组名a可以看成是一个常量指针,类型相当于int (*p)[4],也就是数组指针
    而a[2]的类型是int*;a[2] + 2仍然是一个指针
    所以*(a[2] + 2)的类型就是一个int类型。
    对于上图中的表示方法有很多,理解性去记性。
     
     
    下面通过一个例子,来综合使用二维数组的用法:
    #include <stdio.h>
    
    int main(void)
    {
        int a[4][3] = {
            {1, 2, 3}, 
            {4, 5, 6},
            {7, 8, 9}, 
            {10, 11, 12}
        };
        int (*p)[3] = a;
    
        int i, j;
        //打印第一行的元素
        for (i=0, j=0; j<3; j++)
        {
            printf("%d	", *(*p+j));
        }
        putchar('
    ');
        //打印第二行的元素
        for (i=1, j=0; j<3; j++)
        {
            printf("%d	", *(p[i]+j));
        }
        putchar('
    ');
        //打印第三行的元素
        for (i=2, j=0; j<3; j++)
        {
            printf("%d	", (*(p+i))[j]);
        }
        putchar('
    ');
        //打印第四行的元素
        for (i=3, j=0; j<3; j++)
        {
            printf("%d	", *(&p[0][0]+i*3+j));
        }
        putchar('
    ');
        //打印第四行的元素,变形
        for (i=3, j=0; j<3; j++)
        {
            printf("%d	", (&p[0][0])[i*3+j]);
        }
        putchar('
    ');
    
        return 0;
    }

    运行结果:

     为了更好的理解二维数组,下面用程序来分解下:
     
    看运行结果:
    也就是:0xbff31ccc + 0xc = 0xbff31cd8
     
     
     
    好了,关于指针与数组这一块的内容就学到这,下回继续探索指针!!
  • 相关阅读:
    [CSP校内集训]hotel
    DP小技巧——悬线法
    [SDOI2015]寻宝游戏/异象石(LCA)
    [HAOI2006]旅行
    [SDOI2013]泉(搜索+hash+容斥)
    [NOIP校内集训]home
    [AHOI2014/JSOI2014]骑士游戏(SPFA的本质)
    欧拉函数模板
    开学考试题8:神奇的集合(multiset) 动态开点线段树
    开学考试题5:2017黑龙江省选
  • 原文地址:https://www.cnblogs.com/webor2006/p/3463918.html
Copyright © 2020-2023  润新知