0
点赞
收藏
分享

微信扫一扫

第三节-函数 (下)

weipeng2k 2022-04-24 阅读 61
c语言

本章重点


本章重点)

6.函数的声明和定义


6.1 函数的声明:

int Add (int x, int y);
int main ()
{
    ;   
}
 
int Add (int x, int y)
{
    ;
}

6.2 函数的定义:

test.h的内容

放置函数的声明

#ifndef __TEST_H__
#define __TEST_H__
//函数的声明
int Add(int x, int y);

#endif //__TEST_H__

test.c的内容

放置函数的实现

#include "test.h"
//函数Add的实现
int Add(int x, int y)
{
  return x+y;
}

#include <stdio.h>
#include "add.h"

⭐️ 函数 声明实现 分开写的好处 :


7. 函数递归


7.1 什么是递归?


7.2 递归的两个必要条件

⭐️存在限制条件,当满足这个限制条件的时候,递归便不再继续。

⭐️每次递归调用之后越来越接近这个限制条件。


7.2.1 练习1:

❓ 接受一个整型数值(无符号),按照顺序打印它的每一位。

例如 :  要求 输入 :1234 , 输出 :1 2 3 4
    
    
方法一 :循环
int main ()
{
    unsigned int num = 0;
    scanf ("%u",&num);//1234
    
    while(num)
    {
        printf("%d ",num % 10);
        num /= 10;
    }
    
    return 0;
}
打印 :4 3 2 1 不可取


    
方法二 :
    
void print (unsigned int n)
{
    if (n > 9)
    {
        print (num / 10);
    }
    printf("%d ",num % 10);
}

int main()
{
    unsigned int num = 0;
    scanf ("%u",&num);//1234
    
    print(num);
    
    return 0;
}
    

✏️解释:

1234 %10 ----> 4

1234 / 10 ---->123

.

.

.

⭐️ % 10 : 得到最后一位

⭐️ / 10 : 除掉最后一位


7.2.2 练习2:

❓编写函数不允许创建临时变量,求字符串的长度。

方法一 :
    
int main ()
{
    int len = strlen ("abc");
    printf ("%d ",len);
    
    return 0;
}

不满足条件 有临时变量。


方法二 :
    
    
int my_strlen (char* str)
{
    int count = 0;
    while (*str != \0)
    {
        count ++;
        str ++;
    }
    return count;
}

int main ()
{
    char arr[] = "abc"; // [a b c /0]
    int len = my_strlen (arr);
    printf ("%d ",len);
    
    return 0;
}

不满足条件,含有临时变量。
    
    
方法三 :
    
int my_strlen (char* str)
{
    if (*str != '\0')
        return 1 + my_strlen(str+1); //不能写成str++
    else
        return 0;
}
int main()
{
    char arr[] = "abc"; // [a b c /0]
    int len = my_strlen (arr);
    printf ("%d ",len);
    
    return 0;
}

7.3 递归与迭代

7.3.1 练习3:

❓求n的阶乘。(不考虑溢出)

一、递归实现 :

int fac (int n)
{
    if (n <= 1)
        return 1;
    else 
        return n * fac(n-1);
}


int main ()
{
    int n = 0;
    scanf ("%d",&n);
    int ret = fac(n);
    printf ("ret = %d\n", ret);
    
    return 0;
}


二、非递归实现 (迭代实现)
    
int fac (int n)
{
    int i = 0;
    for (i = 1; i <= n; i++)
    {
        ret *=i;
    }
}    
     
int main ()
{
    int n = 0;
    scanf ("%d",&n);
    int ret = fac(n);
    printf ("ret = %d\n", ret);
    
    return 0;
}
    

7.3.2 练习4:

❓求第n个斐波那契数。(不考虑溢出)

方法一:递归法

int Fib (int n)
{
    if (n <= 2)
        return 1;
    else
        return Fib(n-1) + Fib(n-2);
}

int main ()
{
    int n = 0;
    scanf ("%d",&n);
    int ret = Fib(n);
    printf ("ret = %d\n", ret);
    
    return 0;
}

✏️解释:会产生严重时间浪费

但是我们发现有问题;

  • 在使用 fib 这个函数的时候如果我们要计算第50个斐波那契数字的时候特别耗费时间。

  • 使用 factorial 函数求10000的阶乘(不考虑结果的正确性),程序会崩溃。

❓为什么呢?

  • 我们发现 fib 函数在调用的过程中很多计算其实在一直重复。

    如果我们把代码修改一下:

int count = 0;//全局变量
int fib(int n)
{
    if(n == 3)
        count++;
    if (n <= 2)         
        return 1;
    else
        return fib(n - 1) + fib(n - 2);
}

最后我们输出看看count,是一个很大很大的值。

❓那我们如何改进呢?

❓那如何解决上述的问题:

方法二 :非递归 (迭代)

int Fib (int n)
{
    int a = 1;
    int b = 1;
    int c = 0;
    
    while (n >= 3)
    {
        c = a+b;
        b = a;
        b = c;
        c--;
        // 从后向前计算
    }
    return c;
}

int main ()
{
    int n = 0;
    scanf ("%d",&n);
    int ret = Fib(n);
    printf ("ret = %d\n", ret);
    
    return 0;
}

未完待续…

举报

相关推荐

0 条评论