> For the complete documentation index, see [llms.txt](https://labspc.gitbook.io/cnippets/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://labspc.gitbook.io/cnippets/chap4.-han-shu-yu-cheng-xu-jie-gou/4.10-di-gui.md).

# 4.10 递归

Recursion

C functions may be used recursively; that is, a function may call itself either directly or indirectly.

递归是一个坎，更多有关递归的内容，可以在网上找找例子很多，在等到学数据结构的时候，你会更深刻理解递归。

递归是一个编程技巧，不是这一次就会了。只能慢慢去体会，什么场景适合递归？什么场景不适合递归？

用两个例子去体会递归

### 4.10.1 Print call myself <a href="#mjeyv" id="mjeyv"></a>

{% code title="4.10.1 print-call.c" lineNumbers="true" %}

```c
#include <stdio.h>

// 定义一个函数   unsigned int n   无符号整型

void Print(unsigned int n)
{

    if (n > 9)
    {
        Print(n / 10);
    }
    printf("%u ", n % 10); // 打印末尾   /n 进行换行  可有可无
}
// 上次测试：20231031
int main(void)
{
    unsigned int num = 0;
    scanf("%u", &num);
    // Print(num);

    Print(num);
    return 0;
}
```

{% endcode %}

```
➜  print-call ; exit;
20240120
2 0 2 4 0 1 2 0 
```

跳出循环后，才开始执行第一次 `printf()` 语句

<figure><img src="https://labspc.com/wp-content/uploads/2024/01/1705751730-word-image-336-1.png" alt=""><figcaption></figcaption></figure>

第二次打印：

<figure><img src="https://labspc.com/wp-content/uploads/2024/01/1705751732-word-image-336-2.png" alt=""><figcaption></figcaption></figure>

减少重复代码量： 例如`printf()` 只写了一遍，

再思考一下，`if`语句是用来防止 “栈溢出” （死递归 death recursion）

<figure><img src="https://labspc.com/wp-content/uploads/2024/01/1705751733-word-image-336-3.png" alt=""><figcaption></figcaption></figure>

局部变量、函数的形参、每一次函数的调用，都会在栈区申请空间。

stack overflow 栈溢出（栈区资源是有限的）

### 4.10.2 MyStrlen count character <a href="#trxzw" id="trxzw"></a>

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

{% code title="4.10.2 mystrlen-recursion.c" lineNumbers="true" %}

```c
#include <string.h>
#include <stdio.h>

// 求字符串长度
// int main() {
//  int Length = strlen("Hello");
// printf("%d", Length);
// return 0;
//}

int MyStrlen(char *str) // str：指向字符的指针
{
    // 长度是一个整数
    int Count = 0;
    while (*str != '\0')
    {
        Count++; // 计数器增1
        str++;   // 找下一个字符
    }
    //  *str == '\0'    这里  == 和 =!  的区别
    // =!条件不等才为真，为真进入循环； == 条件相等就为真，刚开始就为真，显然不正确

    return Count;
}

int main()
{

    char arr[] = "Hello";       // 定义一个数组用于存放字符串
    int Length = MyStrlen(arr); // 传的是地址 把数组arr的内容作为地址传给 MyStrlen  char *
    printf("%d", Length);
    return 0;
}
```

{% endcode %}

<figure><img src="https://labspc.com/wp-content/uploads/2024/01/1705751735-word-image-336-4.png" alt=""><figcaption></figcaption></figure>
