指针篇之一 宝藏与藏宝图

来源:互联网 发布:php socket的使用 编辑:程序博客网 时间:2024/05/17 08:40

    很多电影里都有这样的情节:某人得到一大笔宝藏后,绘制了一张藏宝图,为争夺这张藏宝图,引发了一系列故事。从这个老套桥段里,可以总结出一些隐含的东西:

    1.  为什么要有藏宝图?因为宝藏体积重量大,不方便随身携带;而藏宝图轻巧可携带。

    2.  得到藏宝图,基本就能得到宝藏。所以藏宝图≈宝藏。

    3.  藏宝图只是一张纸,做为载体的纸一文不值。它的价值完全体现在纸上所画的图。

    4.  藏宝图是一张纸,但一张白纸却不是藏宝图,必须画有宝藏的位置才行。

    通过藏宝图代替宝藏,这种间接方式有很多好处,于是在软件开发中也发明了类似手段,即指针。指针相当于藏宝图,提供间接访问目标内存的手段,宝藏就是指针所指的内存块。无论谁得到藏宝图后第一件事必然是按图索骥去寻找宝藏。有了指针也要马上想到:这张指针藏宝图指向的宝藏在哪里?这应该形成条件反射。比如:

    int *pA;

    int A=0x1000;

    pA = &A;

    printf(“val A=%d\n”, *pA);

    pA为指针变量,其值为&A,假设为0x2000,这个值代表某内存单元的地址,也常表述为“指针pA指向地址为0x2000的内存”,而*pA代表通过指针变量访问地址为0x2000的内存单元,即变量A,得到里面的值0x1000。藏宝图(即指针pA)上标明了宝藏地址(0x2000),通过*pA就可以访问到0x2000里的内容,得到宝藏(0x1000)

   

  1,指针与指针指向的内存

    指针的值是指针变量本身存储的数值,这个值将被编译器作为另一块内存的首地址。指针所指向的内存区就是从指针所指向的那个内存地址开始,长度为sizeof(指针所指向的内存块的类型)的一个内存块。“指针的值是XX”就代表该指针指向了以XX为首地址的一块内存区域;反过来想让一个指针指向某内存块,就要把该内存块首地址赋予该指针。

     使用指针,对其中隐含的两个概念:”the pointer and the memory pointed by the pointer”,一定要区分清楚。可以参考藏宝图与宝藏,从二者的区别和联系去理解一些问题。比如:

1)两者的长度(区别开宝藏和藏宝图本身的属性)

    指针占多大的内存?用函数sizeof(指针型)测一下就知道。无论指向什么类型,32位平台指针都占据4字节。不要把指针本身占据的内存长度和指针所指向内存的类型长度混淆。小测试:

  int a, b, c ,d ,e, f;

  struct pixsel

  {

    int R;

    int G;

    int B;

  }

  a = sizeof(char *);

  b = sizeof(char );

  c = sizeof(float);

  d = sizeof(float *);

  e = sizeof(struct pixel);

  f = sizeof(struct pixel *);

  a, b, c, d, e, f值是多少?答案:4, 1, 4, 4, 12, 4

    这个题目侧面考验了”pointer itself and the memory pointed by the pointer”两者的区别。

2)不指向实际内存的指针(皮之不存,毛将焉附)

    下段程序中指针的应用发生了什么错误?

    void main(void)

    {

      int *a;

      *a =20;

       printf(“%s\n”, a);

      *a =40;

      printf(%d\n”, a);

    }

    指针定义int *a后,指针自身有了,但指向的内存却没有,指针定义不完整。从寻找宝藏的角度理解,好比买了一张纸,却没有把宝藏所在地画在上面,那就是一张废纸。检查指针与指针指向的内存,这根弦对初学者很重要,要记住:指针本身和它的指向是不同的概念,不要给张白纸就当藏宝图哦微笑

3中间桥梁——地址

    更进一步,在藏宝图与宝藏的关系里,实际有三个元素(白纸/信息/宝藏),只是通常我们把白纸&信息合称为藏宝图。在指针与指针指向的内存之间,实际也有一个隐含的桥梁,即指针里所保存的地址值。

    空白的纸和宝藏之间没有关系,因为真正指向宝藏的是宝藏埋藏点的信息,但这个地点信息必须依附于一个载体而存在,这个载体就是那张白纸。同样一个空指针和目标内存块之间,想要有映射关系也需要一个中间桥梁,那就是目标内存块的地址,只有把这个地址放到指针容器里,联系才真正建立,指针才成为有效指针。这种依附关系好比下图:

 

     A.指针是一个变量,B.保存的内容是地址,C.地址指向某内存对象,综合就是C89的定义:指针是一个保存对象地址的变量。变量/(变量中保存的地址)/(地址所指向的内存),三者共同组成了指针体系。

    对比其他普通变量,比如整型变量,它也是由一个变量和其中所保存的整型数共同组成,只是相比而言,它里面所保存的只是一个单纯整型数,这个数没有别的意义。而指针变量里所保存的地址则代表另一块内存,这块额外的内存才是指针真正的特殊之处。