目录

一、函数的嵌套调用和链式访问

1.1嵌套调用

1.2链式访问

二、函数的声明和定义

2.1函数的声明

2.2函数的定义

三、函数递归

3.1什么是递归

3.2递归的两个必要条件

3.3递归与迭代


一、函数的嵌套调用和链式访问

在编程的时候我们不难发现,我们所写的代码都是由函数组成的。函数和函数之间可以根据实际的需求进行组合,也就是互相调用。

1.1嵌套调用

      在一个函数内调用另一个函数就是嵌套调用。

例:利用一个函数进行多次打印

#include<stdio.h>
//比如我们想利用一个函数打印几次void one_line(void)//因为创建这个函数就是为了打印 所以不需要传入参数也不需要传出参数
{printf("好好学习,天天向上\n");
}void five_line(void)
{int i = 0;for (i = 0; i < 5; i++){one_line();}
}int main()
{five_line();return 0;
}

函数可以嵌套调用,但是不能嵌套定义。(以下是错误的代码,函数不可以进行嵌套定义)

int main()
{int Add(int x,int y){return x+y;}return 0;
}

1.2链式访问

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

注:printf函数的返回值是打印在屏幕上字符的个数

//链式访问的经典例子
//printf函数的返回值是打印在屏幕上的字符个数
#include<stdio.h>
int main()
{printf("%d", printf("%d", printf("%d", 521)));return 0;
}

二、函数的声明和定义

2.1函数的声明

函数声明:

        (函数定义也是一种特殊的声明)

        1.告诉编辑器有一个函数叫什么,参数是什么,返回值是什么。但是具体是不是存在,函数声明决定不了。

        2.函数声明一般出现在函数的使用之前。要满足先声明后使用。

        3.函数的声明一般要放在头文件中。(注意:包含自己的头文件要用" 头文件")

2.2函数的定义

函数的定义是指函数的具体实现交待函数的功能实现。

        一般可以分三个文件来编写代码。

                主文件写代码主题。

                创建一个.c文件放置函数的实现。

                创建一个头文件进行声明函数。

注:使用这种方法调用函数时,需要使用include"头文件" 来引用头文件。

三、函数递归

3.1什么是递归

        程序调用自身编程技巧称为递归。

        函数作为一种算法在程序设计语言中广泛应用。一个过程或函数在定义或说明中有直接或间接调用自身的一种方法

        它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解

        只需少量的程序就可以描述出解题过程需要的多次重复计算,大大地减少程序的代码量。

        递归的主要思考方式在于:把大事化小。

3.2递归的两个必要条件

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

例:

        打印5201314的每一位数

#include<stdio.h>
void print(int n)//函数的定义(函数定义也是一种特殊的声明)
{if (n > 9){print(n / 10);}printf("%d ", n);
}int main()
{int n = 5201314;print(n);//自己创建一个函数对这个数进行打印return 0;
}

3.3递归与迭代

        我们先用一段代码帮助大家理解什么时候应该用递归,什么时候需要用非递归的方式去解决问题。

        求第n个斐波那契数。(1,1,2,3,5,8,13,......,n)。

        通过观察我们不难看出一些规律:

                1  -----  (n<=2)

                n=(n-1)+(n-2)  ----- (n>2)

        由此,我们通过递归的方式可以写成

#include<stdio.h>int fib(int n)
{if (n <= 2){return 1;}elsereturn fib(n - 1) + fib(n - 2);
}int main()
{int n = 0;scanf("%d", &n);int ret = fib(n);printf("%d\n", ret);return 0;
}

如果我们仔细观察这段代码和代码逻辑,我们会发现一个问题。例如我们算的是10那么通过下图我们可以看出,一但我们要求的数比较大,那么在求它的过程运算量也是非常大的,这样就很可能会报错:stack overflow(栈溢出)。系统分配给程序的栈空间是有限的,但是如果出现了死循环,或者(死递归),这样有可能导致一 直开辟栈空间,最终产生栈空间耗尽的情况,这样的现象我们称为 栈溢出。

 那么可以换种思路,采用非递归的方法进行计算。

#include<stdio.h>int fib(int n)
{int a = 1;int b = 1;int c = 1;while (n >=3){c = a + b;a = b;b = c;n--;}return c;
}int main()
{int n = 0;scanf("%d", &n);int ret = fib(n);printf("%d\n", ret);return 0;
}

        换为非递归的方法问题就解决了,我们正常的做法就是使用非递归的方法,虽然递归会使解决事情的效率更高一下,但是也是需要分清情况的。

当我们用递归写代码 如果没有任何问题 那么就可以用递归的方式。如果用递归的方式写,有明显的缺陷比如栈溢出 那么就应该用非递归的方式。

        最后提醒大家:递归虽好,可好酒莫贪杯哦~

C语言——函数(下)相关推荐

  1. linux父进程中显示子进程pid,请教linux下c语言函数fork父进程打印子进程的PID

    请教linux下c语言函数fork父进程打印子进程的PID 关注:296  答案:2  信息版本:手机版 解决时间 2019-01-14 04:55 雨不眠的下 2019-01-13 12:23 用于 ...

  2. C语言函数大全--f开头的函数(下)

    C语言函数大全 本篇介绍C语言中f开头的函数(下) 21. floor,floorf,floorl 21.1 函数说明 函数声明 函数功能 double floor (double x); 获取小于或 ...

  3. c语言添加输入函数吗,C语言scanf()函数下支持中文输入吗?

    C语言scanf()函数下支持中文输入吗? C语言scanf()函数下支持中文输入吗? 如果我编写一个程序,要求是先输入姓,再输入名,然后按照常姓名的方式排列出来,如果我需要输入中文该怎么办? 搜索更 ...

  4. C语言函数大全--g开头的函数(下)

    C语言函数大全 本篇介绍C语言函数大全–g开头的函数(下) 17. getmodename 17.1 函数说明 函数声明 函数功能 char * getmodename(int mode_name); ...

  5. c语言exit在哪个头文件_C语言函数执行成功时,返回1和返回0,究竟哪个好?

    基本上,没有人会将大段的C语言代码全部塞入 main() 函数,更好的做法是按照复用率高,耦合性低的原则,尽可能的将代码拆分不同的功能模块,并封装成函数.C语言代码的组合千变万化,因此函数的功能可能会 ...

  6. go语言----函数 结构体 接口 多态

    函数 Go语言 函数是反过来声明 变量类型和  函数返回值 一.一个返回值 package main import "fmt"func max(a int,b int) int { ...

  7. head在c语言中的作用,阅读以下说明和C语言函数,将应填入(n)处的字句写在对应栏内。【说明】 函数sort (NODE *head)的功能 - 赏学吧...

    阅读以下说明和C语言函数,将应填入(n)处的字句写在对应栏内. [说明] 函数sort (NODE *head)的功能是:用冒泡排序法对单链表中的元素进行非递减排序.对于两个相邻结点中的元素,若较小的 ...

  8. C语言函数指针 和 OC-Block

    C语言函数指针 和 OC-Block 一. C语言函数指针 关于函数指针的知识详细可参考: http://www.cnblogs.com/mjios/archive/2013/03/19/296703 ...

  9. 【C 语言】C 语言 函数 详解 ( 函数本质 | 顺序点 | 可变参数 | 函数调用 | 函数活动记录 | 函数设计 ) [ C语言核心概念 ]

    相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...

最新文章

  1. elasticsearch best_fields most_fields cross_fields从内在实现看区别——本质就是前两者是以field为中心,后者是词条为中心...
  2. 虚拟服务器设置upnp,TP-Link路由器如何设置UPNP开启【设置步骤】
  3. STM32 UART2程序--端口重映射
  4. 十大经典排序算法之希尔排序及其优化
  5. MariaDb数据库管理系统的学习(一)安装示意图
  6. master分支删除文件_Git分支基础简介;创建分支;合并分支;删除分支;
  7. 项目拖太久的巨大风险
  8. Kali Linux 网络扫描秘籍 第六章 拒绝服务(二)
  9. Matploblib work5
  10. 怎样彻底删除系统服务项
  11. Touch事件分发源码解析
  12. 人体姿态识别 tensorflow版本
  13. 2.运筹学上课复盘 之 单纯性法的原理 + 两阶段法 + 解的类型
  14. VS创建和使用C++动态链接库教程
  15. wps画 ui 原型图
  16. 二叉树由遍历确定一棵树
  17. vim 文件保存退出 文件相关操作汇总
  18. 智能汽车里究竟“藏”有多少传感器?
  19. 在houdini里,怎么手动设置输出物体的红绿蓝通道,便于nuke调节使用(基础篇)
  20. 三、以太网协议栈uIP移植

热门文章

  1. Miniconda安装TensorFlow并导入Pycharm
  2. RK987蓝牙机械键盘win和alt键互换
  3. 学习笔记day07_HTML
  4. 【浏览器兼容性】如何隐藏微软的ie和edge浏览器密码输入框的小眼睛
  5. 居家办公小能手,分享提高工作效率的4款办公软件
  6. java 数据挖掘包,什么是Java数据挖掘,JDM?
  7. C语言谭浩强第三版第十二章例题及课后题:位运算
  8. Linux平台总线驱动设备模型
  9. css3绘制的钢琴代码
  10. ArcGIS Pro(ArcMap)中利用自带地理处理工具实现线图层批量裁剪面图层