关于数组指针,指针数组 函数的指针域指针函数老是弄不清楚,在这里对其区别和用法做个总结

数组指针与指针数组:
一 数组指针:
    数组指针int (*p)[n]又称为行指针,一维数组的指针,专门用来处理二维数组 int arry[m][n],因为其列数固定,可用数组指针操作其行索引。
    用法:先定义二维数组       int arry[m][n];
       再定义数组指针       (*p)[n];
       将数组指针指向二维数组:    p=arry;//或者定义时为(*p)[n]=arry
       操作行指针:        p++;           p+1执行arry[1][0]这一行的首地址
二 指针数组:
  *p[n]就是一个数组其每个元素为指针。通常用来处理列数不固定的许多数组。其中n通常不注明,让编译器去计算用法:
  首先定义一系列数组:int a[m],b[n],c[k]
  再定义指针数组并初始化:int*p[]={a,b,c};
  操作数组: p[1]就是数组a的首地址@a[0]

三:二维数组与行列指针:a[m][n]通常把二维指针看成一个行列式,虽然它在内存中的排序却是和一维指针一样的,但就对CPU的访问速度是不一样的,原因是由于cache,同样的二维数组遍历访问一遍,按行访问的速度更快,是因为多级cache,是按cache line(行)缓存的,即二维数组在内存中的排列形式是按行来的

http://blog.csdn.net/haussuden/article/details/5965304

3.1 数组名与行指针:是整个数组的首地址,同时也指向第一行元素,指首行一整行,并不是指某个具体元素.即a是一个行指针,它每加1,所指地址移动二维数组的一行a=a+0指向第0行,a+1指向第一行元素,行指针还可以这样定义(*p)[n]

3.2列指针:对行指针取值(前加*或后加[])就成了列指针,此时它还是个指针,如*(a+1)=*(a+1) +0=a[1]=a[1]+0指向第二行第一个元素。

3.3操作某个元素:对列指针取值就是操作某个元素,如 a[m][n]=*(*(a+m)+n),**a=a[0][0],**(a+1)=a[1][0]

行指针:指的是一整行,不指向具体元素。

列指针:指的是一行中某个具体元素。

可以将列指针理解为行指针的具体元素,行指针理解为列指针的地址。

那么两个概念之间的具体转换是:

*行指针----列指针

&列指针----行指针

用法:用二维指针指向二维数组数组名(行指针),用列指针的首地址a[m]接收指针函数返回的指针,用列指针调用。

关于函数的返回值是否设计成指针:通常情况下,函数的返回值不要写成指针,而将想得到的结果的指针写到参数中直接带回;如果写成指针返回:只适用于暂时利用下结果而不需要保存,或者在函数调用后再通过内存拷贝的方法保存结果。

#include <stdio.h>
#include <stdlib.h>
char* test(unsigned char n);
int main()
{
//    char a[4][20],**pb=a;
     char *pb[20]={0};

    pb[0] =test(1);
    printf("%s\n",pb[0]);
    pb[1]=test(2);
    printf("%s\n",pb[1]);
    pb[2]=test(3);
    printf("%s\n",pb[2]);
    pb[3]=test(4);
    printf("%s\n",pb[3]);
    while(1);
    return 0;
}
char* test(unsigned char n)
{
    char* p;//=(void *)0;
    switch(n)
    {
        case 1:p="zhansan";break;
        case 2:p="lisi";break;
        case 3:p="wangmazi";break;
        case 4:p="赵五";break;
    }
    return p;

}
比如要表示数组中i行j列一个元素:
   *(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]
  
优先级:()>[]>*

然后来说指针函数与函数指针
三 函数指针是指向函数的指针(*p)(int a,uchar b),和指向变量的指针一样,函数指针可以指向函数的首地址。但是要注意的是函数指针指向的函数必须参数的类型个数相同,返回值类型也相同
 用法:
  1 定义具有相同类型的一些函数。 int plus(int a,int b);int subb(int a,int b).
  2 定义函数指针 int(*p)(int a,int b)
  3 指针指向函数 p= plus;  //函数名已经代表了首地址。
  4 运用指针 int(*p)(5,3).
四 指针函数是指一个函数的返回值是一个指针    int *p(int a,uchar b).主要应用:一个函数只能返回一个结果,如果要修改多个值就要用到指针函数,需要注意的是返回的指针必须用同种类型的指针来接收

五 函数的指针数组 void (*pfunction[])(void)
其实就是一个数组,只不过数组里面的每一个元素都为函数名(通常这些函数不带参数)
功能:多用于函数的循环操作,例如不同的显示函数。为函数的指针数组赋值有两种方法 一 为静态定义 二是动态赋值

1. 静态定义  在定义函数指针数组的时候,已经确定了每个成员所对应的函数。例如:  void (*INTARRAY[])(void) =
{Stop,Run,Jump};调用:INTARRY[0]()实际上就是 void stop(void)

2 动态赋值:先定义一个新的函数指针的数据类型typedef void (*INTFUN)(void); //此类型的函数指针指向的是无参、无返回值的函数。  

      再用该类型定义一个函数的指针数组:INTFUN INTARRAY[32];//定义一个函数指针数组,其每个成员为INTFUN类型的函数指针                         最后为函数指针数组的每个元素赋值INTARRAY[10] = INT_TIMER0;//为其赋值  

      最后调用:INTARRAY[10](); //调用函数指针数组的第10个成员指向的函数
    用法:
1 先定义一些函数 void function1(void) void function2(void)... void functionn(void)
2 在定义一个函数的指针 void (*function)(void) //通常不带参数和返回值这样符合函数指针要求参数返回值严格一致的要求)
3 定义一个指向函数的指针数组并给数组赋值
const void (*pfunction[])(void)={function1,function2...functionn}
4 调用 for(i=0;i++;i<n){\
function=pfunction[i];
function();
}