指针数组和指向指针的指针
  这两个词次听起来挺新颖的,到底是什么意思呢?
  由于指针本身也是变量,所以它们也可以像其他变量一样存储在数组中。这一点很容易理解。
#include<stdio.h>
#include<string.h>
void main()
{
int i;
char b[]={"wustrive_2008"};
char *a[1];
*a=b; for(i=0;i<strlen(b);i++) printf("%c",*(a[0]+i)); printf("/n");
}
  运行结果:wustrive_2008
  这里库函数strlen,strlen为string类的标准库函数,所以要包含#include。
  下面我们来自己写一个strlen函数,我们把上面的例子该成这样:
#include<stdio.h>
int strlen(char *s)
{
char *p=s;
while(*p!='/0')
p++;
return p-s;
}
void main()
{
int i;
char b[]={"wustrive_2008"}; char *a[1];
*a=b; for(i=0;i<strlen(b);
i++) printf("%c",*(a[0]+i)); printf("/n");
}
  这个运行结果和上个例子一样,不一样的只是我们自己实现了strlen函数,我们再编程时使用的库函数,都是语言的开发者或者系统为我们写好了的函数,其实我们也可以自己写。
  这个例子很好的演示了指针数组的用法,指针数组a的值a[1]是一个指针,指向字符数组第一个字符。
  指针的指针也很好理解,是一个指针里放的是另一个指针的地址,而另一个指针可能指向一个变量的地址,还可能指向另一个指针。
  指针和多维数组
  看两个定义语句:int a[5][10]; int *b[5];
  从语法角度讲,a[3][4]和b[3][4]都是对一个int对象的合法引用。但a是一个真正的二维数组,它分配了50个int类型长度的存储空间。但b定义仅仅分配了5个指针,并且没有初始化,它们必须进行显示的初始化,假设b的每个元素都指向一个有10个元素的数组,那么编译器要为它分配50个int类型长度的存储空间以及5个指针存储空间。指针数组的一个重要优点在于,数组的每一行长度可以不同,也是说,b的每个元素不必都指向一个有10个元素的向量。
  指向函数的指针:
  在C语言中,函数虽然不是变量,但可以定义指向函数的指针。这种类型的指针可以被赋值,存放在数组中,传递给函数以及作为函数的返回值等。
  如果下面的语句为一个函数的参数,表示什么意思:
  int (p)(void ,void *)
  它表明p是一个指向函数的指针,该函数具有两个void类型的参数,其返回值类型为int。语句if((p)(v[i],v[left])<0)中,p的使用和其声明是一致的,p是一个指向函数的指针,p代表一个函数。如果写成这样:int p(void ,void )则表明p是一个函数,该函数返回一个int类型的指针。
  下面来看两个声明:
  int *f(); //f是一个函数,它返回一个指向int类型的指针
  int (*pf)(); //pf是一个指向函数的指针,该函数返回一个int类型的对象。