<C-函数02> 2017/11/30

/*
1.递归
    函数 -->调用 
    在一个函数中调用另外一个函数
    递归 一个函数直接或者间接调用自己 -->递归

    递归 重复运算 
        优点 代码可读性  复杂问题简单化  便于理解
        缺点 内存耗费内存   递归 层次多的情况 容易造成栈溢出
       代码长度  -->内存 
    斐波那契数列  1  1  2  3  5  8  
    规律 f(n) 表示第n项    -->f(n)=f(n-1)+f(n-2)  f(1) f(2)
    函数fc_num(x)  计算数列的第n项

    把一个大的问题分解成小的问题 小的问题分成更小的问题 -->直接解决为止 

        递归  问题分解成比较小的问题 -->分到最小就解决掉

    //阶乘   1+2+3+...+100

    (1+2+3+4+...99)+100



    1*2*3*4*5*6*7*8*9*10竟然等于10!
    n!  1*2*3*....*n
       1*2*3*4*5*....*(n-1)*n-->n*(n-1)!-->n*(n-1)*(n-2)!
       (n-1)!=1*2*3*4*5*6*...(n-1)
       (n-1)!-->(n-1)*(n-2)!
       ....
       1!=1

    作业  了解下汉诺塔  用递归计算    1+2+3+4+.....+100

    递归 注意事项  1.条件 结束递归的条件  如果陷入死循环
                    2. 递归次数过多  -->栈溢出


2.函数指针  指针函数
    函数指针 -->指针   指向函数的指针
        可以通过指针调用函数 
        存函数地址 
        返回值类型 函数名(参数)
        int fPow(int x);
        具体定义   函数名换成(*p)
        int (*p)(int x);//定义   形参名字可要可不要 类型一定要保留
        int (*p)(int x)=fPow;//定义给他赋值
        怎么使用

    指针函数 -->函数   返回一个指针的函数
    
    用函数 申请内存  -->用指针接受   malloc
     strcpy   strcat


*/

#include<stdio.h>
#include<stdlib.h>
//==============函数声明====================
int funA();
int funB();
int fun(int x);
int funC(int x);
int funD(int x);
int fPow(int x);
//在堆区申请m*n的int数组  二级指针
int **getDouArr(int m, int n);

int main()
{
    int x=5;
    //scanf("%d", &x);
    //getchar();
    //printf("%d", fPow(x));//直接调用
    int(*p)(int) = fPow;
    p = fPow;//让指针指向函数
    p = &fPow;//取地址加或者不加都可以
    printf("%d", p(x));//调用的时候和函数一样调用就可以了

    int (*q)()=funB;

    getchar();
    return 0;
}
//================函数定义=====================
int funA()
{
    return 1;
}
int funB()
{
    return funA();//在funB里面调用funA()
}

int fun(int x)
{
    if (x > 0)
    {
        return x*fun(x - 1);//函数自己调用自己
    }
    else return 1;
}
int funC(int x)//写一个格式  间接调用
{
    funD(x);
    return x;
}
int funD(int x)
{
    if (x >= 0) funC(x);//间接调用自己  也算递归
    return x;
}
int fc_num(int n)  //fc_num(x)  表示这个数列的x项   第n-1项 fc_num(n-1)  第n-2项 fc_num(n-2)
{
    if (n == 1 || n == 2) return 1;
    else if (n <= 0) return 0;
    else//n>=3
    {
        //前两项之和
        return fc_num(n - 1) + fc_num(n - 2);
    }
}
int fPow(int x)//阶乘
{
    printf("现在开始计算%d的阶乘,x的地址:%p\n", x,&x);
    if (x <= 0)  return 1;
    else if (x == 1)  return 1;
    else
    {
        return x*fPow(x - 1);
    }
}
int **getDouArr(int m, int n)//返回值为指针的函数  指针函数
{
    int **p;
    p = (int**)malloc(sizeof(int*)*m);//申请m个int*
    for (int i = 0; i < m; i++)
    {
        *(p + i) = (int *)malloc(sizeof(int)*n);//每一个指针申请n个int
    }
    for (int i = 0; i < m; i++)
    {
        //*(p + i) = (int *)malloc(sizeof(int)*n);//每一个指针申请n个int
        for (int j = 0; j < n; j++)
        {
            p[i][j] = 0;
        }
    }
    return p;
}

传递参数部分:

 

#include<stdio.h>

/*
3.函数传参  (指针)
实参定义                实参                    形参定义格式
int x                    x                        int x
int *p                    p                        int *p

int arr[10]                arr                        int arr[]或者int *arr

*/
int addfun(int x)
{
    return 1;
}
//形参和实参不一定要保持一致  类型一致就行
int fun(int x, //对应x
    int *p,
    int arr[],//对应一维数组  int *arr
    int dArr[][10],//对应二维数组  行可以省略  或者使用数组指针  int(*dArr)[10]
    int *pArr[], //对应指针数组   或者使用二级指针 int **pArr
    int(*addfun)(int),//函数指针    ()里面的类型不能省 参数名可以省
    int paddfun(int)
    )
{
    addfun(1);
    //...
    return 1;
}
int main()
{
    int x;
    int *p;
    int arr[10];//一维数组
    int dArr[5][10];//二维数组
    int *pArr[10];//指针数组
    fun(x, p,
        arr,//传递的时候直接传递数组名
        dArr, pArr,
        addfun,//直接传递函数名
        addfun
        );
    getchar();
    return 0;
}

 

posted @ 2018-01-16 18:44  让优秀成为一种习惯  阅读(142)  评论(0编辑  收藏  举报