首页 > 代码库 > 第五天:C基础之递归与二维数组

第五天:C基础之递归与二维数组

写递归函数时要明确结束条件和递归体。

练习了几个递归函数:

首先是斐波那契数,前几天写过的程序,今天写的时候还是出现了问题。在判断结束条件的时候写错。写成(i==1&&i==2) 这个是有明显的逻辑错误。

 1 斐波那契#include<stdio.h> 2 int fbnq(int i) 3 { 4     if(i==1) 5         return 1; 6     if(i==2) 7         return 1; 8     int ret =  fbnq(i-1)+fbnq(i-2); 9     10     return ret;11     12 13 }14 15 int main()16 {    17     int num = 20;18     int ret = fbnq(num);19     20     printf("%d\n",ret);21 22 }
斐波那契

写汉诺塔函数时,开始没有明白,递归就是看着代码简单。想要还原过程的话还是挺抽象的。

 1 #include<stdio.h> 2 int move(int n,char src,char dest) 3 {     4     printf("%d from %c to %c \n",n,src,dest); 5      6 } 7 int hano(int n ,char src ,char dest,char mid) 8 { 9     if( n ==1)10     {11         move(n,src,dest);12         return 1;13     }14     hano(n-1,src,mid,dest);15     move(n,src,dest);16     hano(n-1,mid,dest,src);17 18 19 }20 21 int main()22 {    23     hano(5,A,C,B);    24 25 }
汉诺塔

总结下,写递归函数时,要先找到递归函数的结束条件 。然后找规律,找出上一条件时的情况。到最后逆着推导。

 1 #include<stdio.h> 2 int hello(int i[3]) 3 { 4     printf("sizeof(i) == %d\n",sizeof(i)); 5  6  7 } 8  9 int main()10 {11     int arr[3] = {5,3,7};12     hello(arr);13 14     printf("sizeof(arr) == %d\n",sizeof(arr));15 16 }


上面的代码中 ,结果为 sizeof(i) = 4 ; sizeof(arr) = 12;   当数组作为参数时,实际上是传首地址,既当作指针使用

 1 #include<stdio.h> 2 int add(int (*n)[3]) 3 { 4  5      6     int i ,j; 7     int sum =0; 8     for(i=0;i<2;i++) 9         for(j=0;j<3;j++)10             sum +=*(*(n+i)+j);11     printf("%d\n",sum);12 13 14 15 }16 int main()17 {18     int br[2][3] = {{2,3,4},{6,4,1}};19     20     int (*p)[3] = br;21     add(p);    22 23 }
View Code


二维数组要传递首地址  使用的是数组指针  (*p)[n]    如果不加括号为指针数组  *p[n]  区别两者的概念,看最后两个,如果是数组指针,那就是指针变量,它希望存数组的首地址。

下面是一个有趣的代码  如果能够理解清楚 那么这两个概念就能够掌握了。

 1 #include<stdio.h> 2  3 int main() 4 { 5         short (*s)[4][3][2]; 6         printf("%d\n",sizeof(s)); 7         printf("%d\n",sizeof(s[0])); 8         printf("%d\n",sizeof(s[0][0])); 9         printf("%d\n",sizeof(s[0][0][0]));10         printf("%d\n",sizeof(s[0][0][0][0]));11 //      printf("%d\n",sizeof(s[0][0][0][0][0]));12 13 }14 ~  

结果为 4 48 12 4 2

 1 #include<stdio.h> 2  3 int main() 4 { 5     short s[4][3][2]; 6     printf("%d\n",sizeof(s)); 7     printf("%d\n",sizeof(s[0])); 8     printf("%d\n",sizeof(s[0][0])); 9     printf("%d\n",sizeof(s[0][0][0]));10 //    printf("%d\n",sizeof(s[0][0][0][0]));11 //    printf("%d\n",sizeof(s[0][0][0][0][0]));12     13 }

输出结果为 48 12 4 2

 

下一个函数是求出整型数组的最大值,并打印出坐标

 1 #include<stdio.h> 2 int search(int (*p)[3],int *x ,int *y) 3 { 4  5     int max = 0; 6     int i,j; 7     for(i=0;i<2;i++) 8         for(j=0;j<3;j++) 9             {10                 if(*(*(p+i)+j)>max)11                     {    12                         max = *(*(p+i)+j);13                         *x=i;14                         *y=j;15                     }16             }17     return max;18 }19 20 int main()21 {22     int arr[2][3] = {{1,2,3},{5,4,1}};23     24     int (*p)[3] = arr;25     int max ;26     int x ,y;27     max = search(p,&x,&y);28     printf("%d,%d,%d\n",max,x,y);29     30 }
View Code

这个没有什么难度 ,还有升级版本的题目,在一次循环内找出最大的两位;

#include<stdio.h>int main(){    int arr[10] = {1,28,3,57,5,0,6,8,24,12};        int i;    int max = *(arr+1);    int secondmax = *(arr + 0);    int temp = 0;    for(i=2;i<10;i++)    {            if( secondmax > max)            max = secondmax;        if(*(arr+i)>max)            max = *(arr+i);        else if(*(arr+i)>secondmax)            secondmax =*(arr+i);            }    printf("%d,%d\n",secondmax,max);}
找最大的两位

这个程序还有个错误 ,还没有改,就是判断 前两个值的时候,应该是max和secondmax交换值,而不是secondmax的值把max值给覆盖了。要是刚开始secondmax是最大值,而max是第二大的值,那么结果就会出错 。至于交换值的三种方法。我前面日志有写,就不提了。

 

最后是作业。主要是增加对二维数组的了解

 1 #include<stdio.h> 2  3 int main() 4 { 5     int arr[2][3] = {{2,3,5},{3,5,6}}; 6     int brr[3] = {0}; 7     int crr[2] = {0}; 8      9     int i,j;10     for(i=0;i<3;i++)11     {12         brr[i] = *(*(arr+0)+i) + *(*(arr+1)+i);13         printf("%d ",brr[i]);14     }15     printf("\n");16     for(i=0;i<2;i++)17     {    18         for(j=0;j<3;j++)19         {20         crr[i] += *(*(arr+i)+j);21     22         }23         printf("%d ",crr[i]);24     }25 26 27 }
横竖求和
#include<stdio.h>int main(){    int arr[2][3] = {{2,3,5},{3,5,6}};    int brr[3][2] = {0};        int i ,j;    for(i=0;i<3;i++)        for(j=0;j<2;j++)            {                    *(*(brr+i)+j) = *(*(arr+j)+i);                printf("%d ",*(*(brr+i)+j));            }    }
转置二维数组

还有一个杨辉三角:

 

第五天:C基础之递归与二维数组