C语言二维数组传参/函数指针变量/函数指针数组/转移表

二维数组传参

二维数组传参传的也是首元素的地址,不是数组。

arr[0][0]       a arr[0][1]    b
arr[1][0]       c arr[1][1]    d
arr[2][0]       e arr[2][1]     f

char arr[3][2] =  {a, b, c, d, e, f };

上面这个数组左边是下标,右边是储存的元素。

二维数组传参是怎么进行的呢?

void Print(char *p[2])
{
   for(int i = 0; i < 3; i++)
   {
       for (int j = 0; j < 2; j++)
        {
            printf("%c", *(*(p+i)+j));
        }
    }
}




int main()
{
  char arr[3][2]={a,b,c,d,e,f};
  Print(arr)//建立一个Print函数,把这个二维字符数组传参,打印这个二维数组

  return 0;
}

如图,可以把二维数组arr[3][2]看作一个一维数组的数组,这个数组里有三个元素,每一个元素都是一个一维数组,那么第一个一维数组就是arr[0],第二个是arr[1],第三个是arr[2]。arr[0]是一个一维数组,这个数组有两个元素,第一个是a,第二个是b.

二维数组传参传的是首元素的地址,在这个例子中,首元素的地址----arr[0]----的地址,arr[0]是一个一维数组,它存入的是arr[0]中首元素----arr[0][0]---的地址。二维数组的首元素是一个数组,那么它的地址就是一个数组指针,所以也要用数组指针类型接收。char *p[2] 表示接收的数组有两个元素(arr[0]中有两个元素), 指向的对象是char型的字符。* 表示p是一个指针。

p是一个数组指针,p+1跳过的就是一个数组。*(*(p+0)+0)访问arr[0][0],*(p+0)表示第一行的地址解引用,解引用后就是二维数组的第一个元素arr[0],arr[0]既是二维数组的第一个元素,也是第一行数组的数组名,作为数组名,它又是首元素的地址。所以*p+1,就是指针从arr[0][0]指向了arr[0][1],解引用,就是*(*p+1)得到了arr[0][1]的值b。

C语言二维数组传参/函数指针变量/函数指针数组/转移表_第1张图片

二维数组通过指针访问,  对指针解引用也就是    *(*(p+行变量)+列变量)  得到具体的值。

p+行变量 得到二维数组的某行的首元素地址,对地址解引用得到该行元素的名字(arr[1]/arr[2]/arr[3]),由于它们是数组,所以数组名也是它们的首元素的地址。 *(p+行变量)+列变量,通过再加列变量,指针移动找到这一行相对应的具体位置。此时还是指针,所以还要解引用才能得到最终的结果!

函数指针变量

int  (*p) (int,int) = Add ;

这是函数指针变量的声明,int 表示函数Add返回的是一个int型的值。*p表示这个函数是一个指针。(int ,int)表示Add传的两个参数是int型。

函数名也是函数的地址,所以声明时,既可以加取地址符号,也可以不加。

int Add (int x , int y)
{
   return x+y;
}



int main( )
{

  int (*p)(int, int) = Add;
  int i = 0;
  printf("%d",(*p)(2, 3));
  printf("%d",p(2,3));
  return 0;
}

通过指针访问函数,函数名就是函数的地址,这里声明以后,指针也相当于函数名,可以不用解引用,直接传参数就可以。

函数指针数组

int  ( *p[3])  (int , int  ) = { Add, Sub , Mul ,Div , Mod };

以上是函数指针数组的声明,p[3]结合表明这是个数组, int * ()  表示是一个函数指针。数组里面都是函数指针。

转移表

如下图所示,将函数放在一个数组里面,组成一个函数指针数组,然后通过指针来访问它们。

这是函数指针访问函数,与函数指针数组的结合。形成这个集合加减乘除的简单计算器。

C语言二维数组传参/函数指针变量/函数指针数组/转移表_第2张图片

你可能感兴趣的:(c语言,算法,数据结构)