C语言超全面讲解函数的使用方法下

 更新时间:2022年04月22日 16:35:42   作者:马桶上看算法  
函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数,由于篇幅过大,分为两篇讲解,下面开始下篇

C语言超全面讲解函数的使用方法上

一、函数的嵌套调用

在定义函数时,一个函数内不能再定义另一个函数,即不能嵌套定义,但可以嵌套调用函数,即在调用一个函数的过程中,又调用另一个函数。

⚠️注意:

  • 函数可以嵌套调用但是不可以嵌套定义。
  • 每一个函数都应该在大括号的外面独立存在。

代码示例:

根据这张图可以清楚的看到,three_line() 函数内部嵌套了一个 new_line() 函数。

当前代码打印了3个haha。

二、函数的链式访问

函数的链式访问就是把一个函数的返回值作为另一个函数的参数。

当前代码,strlen()函数是作为printf()打印函数的参数,把自己的返回值3返回给了printf()函数,所以最终打印结果是:3。

下面代码的打印结果是什么?

#include<stdio.h>
int main()
{
    printf("%d", printf("%d", printf("%d", 43)));
    return 0;
}

 输出结果:

代码分析:  

 ⚠️注意:printf()函数的返回值是打印字符的个数。

当得知了printf()函数的返回值是打印字符的个数后,可以做出一下分析。

三、函数递归

递归的优缺点

程序调用自身的编程技巧称为递归。可以直接或间接的调用,本质是把复杂的问题转化为一个规模小的问题。递归一般只需少量的代码就可描绘出多次重复计算。递归的主要思考方式:大事化小

必要条件

  • 存在限制条件,当满足这个限制条件的时候,递归便不再继续。
  • 每次递归调用之后越来越接近这个限制条

使用场景

1. 能够要求转化为新的问题,且二者解决方法相同,所处理的对象存在规律变化。

2. 非递归比较麻烦,而递归很简单。

3. 有模板或是公式可以直接套用,不会出现明显问题。

函数递归的细节说明 

1. 每级递归都有自己的变量,可能名称相同,但是值不同。

递归调用时,系统自动保留当前函数的参数变量。

每次调用系统都会为函数开辟相应的空间。

2. 每次调用都要返回值,递归执行结束后,控制权传回到上一级函数。

调用结束后,系统释放本次调用所开辟的空间,

程序返回到上一次的调用点,同时获得初进该级调用的参数。

每级递归必须逐级返回,不可跳跃或间断。

3. 函数中递归语句之前的代码,按被调函数的顺序执行,

递归之后的代码,与被调函数相反的顺序执行。

举例说明

接受一个整型值(无符号),按照顺序打印它的每一位。例如,输入:1234,输出:1 2 3 4

代码示例:

#include<stdio.h>
void print(unsigned int n)
{
    if (n > 9)
    {
        print(n / 10);
    }
    printf("%d ", n % 10);
}
int main()
{
    unsigned int num = 0;
    scanf("%u", &num);
    //print函数可以打印参数部分数字的每一位
    print(num);
    //函数递归 - 自己调用自己
    return 0;
}

输出结果:

代码分析:

对两个必要条件的理解

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

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

如果是递归,两个限制条件必定满足。

四、递归练习

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

题目要求不允许创建临时变量,当前代码不符合要求。

#include<stdio.h>
#include<string.h>
int my_strlen(char* str)
{
	int count = 0; // 临时变量
	//printf("%c\n", *s);
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
int main() 
{
	//求字符串的长度
	char arr[] = "haha";
	int len = strlen(arr);
	printf("%d\n", len);
	return 0;
}

符合要求的写法: 

#include<stdio.h>
#include<string.h>
int my_strlen(char* str) 
{
	if (*str == '\0') 
	{
		return 0;
	}
	else 
	{
		return 1 + my_strlen(str + 1);
	}
}
int main() 
{
	//求字符串的长度
	char arr[] = "haha";
	//arr是数组名,数组名是数组首元素的地址
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

代码分析:

运行结果:

到此这篇关于C语言超全面讲解函数的使用方法下的文章就介绍到这了,更多相关C语言函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 求子数组最大和的实例代码

    求子数组最大和的实例代码

    求子数组最大和的实例代码,需要的朋友可以参考一下
    2013-03-03
  • C++精要分析lambda表达式的使用

    C++精要分析lambda表达式的使用

    Lambda表达式是现代C++在C ++ 11和更高版本中的一个新的语法糖 ,在C++11、C++14、C++17和C++20中Lambda表达的内容还在不断更新。 lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法
    2022-05-05
  • C++字符串输入缓冲区机制详解

    C++字符串输入缓冲区机制详解

    缓冲区是用来存放流中的数据,本文详细的介绍了C++字符串输入缓冲区机制,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-10-10
  • 一文教你快速了解C语言中的作用域和常量

    一文教你快速了解C语言中的作用域和常量

    作用域(scope)是程序设计概念,通常来说一段程序代码中所用到的名字并不总是有效/可用,下面这篇文章主要给大家介绍了关于如何快速了解C语言中的作用域和常量的相关资料,需要的朋友可以参考下
    2023-06-06
  • C++中的memset用法详解

    C++中的memset用法详解

    memset是一个初始化函数,作用是将某一块内存中的全部设置为指定的值,本文给大家介绍C++中的memset用法,感兴趣的朋友跟随小编一起看看吧
    2023-02-02
  • C++之预处理功能详解

    C++之预处理功能详解

    预处理器是 C++ 编译器提供的一个工具,允许程序员在编译之前对源代码文件做出修改,本文将给大家通过代码示例详细介绍C++的预处理功能,需要的朋友可以参考下
    2023-05-05
  • C语言巧用二分查找实现猜数游戏

    C语言巧用二分查找实现猜数游戏

    二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列,本篇文章教你用二分查找编写猜数字游戏
    2022-02-02
  • Linux下C语言修改进程名称的方法

    Linux下C语言修改进程名称的方法

    这篇文章主要介绍了Linux下C语言修改进程名称的方法,涉及Linux下使用C语言操作进程的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • C++实现LeetCode(80.有序数组中去除重复项之二)

    C++实现LeetCode(80.有序数组中去除重复项之二)

    这篇文章主要介绍了C++实现LeetCode(80.有序数组中去除重复项之二),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • c++中inline的用法分析

    c++中inline的用法分析

    本篇文章是对c++中inline的用法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05

最新评论