# 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://labspc.gitbook.io/cnippets/chap4.-han-shu-yu-cheng-xu-jie-gou/4.10-di-gui.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
