导图社区 高级编程语言程序设计-函数(上)
高级程序语言设计C函数部分知识点总结(上篇),包括初学所有函数知识点,知识全面详细,干货满满,现在不收藏,还在等什么呢。
编辑于2021-11-05 11:56:43函数 1
引入目的
逻辑更清晰
降低代码总量,方便维护
函数概述
C/C++程序基本组成单位
一个函数实现一个功能
有且仅有一个main函数,程序执行开始处
函数平行定义,嵌套调用
一个源程序文件由多个函数组成,一个程序可由多个源程序
函数分类
用户使用角度
标准函数(库函数)
系统提供(fabs/sqrt/strlen……)
使用使需要包含相应头文件
自定义函数
用户自己编写
函数形式
无参函数
调用函数无数据传递给被调用函数
getchar()
有参函数
调用函数有数据传递给被调用函数
putchar('A')
函数的定义
无参函数
定义语句
函数返回类型 函数名 ()/(void)
函数名命名规则同变量,返回类型与数据类型相同
返回类型void,表示不需要返回类型
C缺省返回值为int,C艹不支持缺省
即C艹不能直接写 fun3(...)
error:C++不支持默认int
ANSI C++要求:main函数返回值只能是int(且不支持缺省不写)
有参函数
定义语句
函数返回类型 函数名 (形式参数表)
例:int max(int x,int y)
函数参数和函数的值
形参和实参
形式参数:在被调用函数中出现
实际参数:再调用函数中出现
实际参数在原来函数中(如main函数中),且有实际值 形式参数在被调用的函数中,值需要实参赋予
形参实参有关性质
分别占用不同的内存空间,形实参名可以相同
参数传递:“单向传递”
实参的值复制一份到形参中
相当于赋值:形参=实参。所以执行后,形参值变化不影响实参值
实参可以是常量、变量、表达式,形参只能是变量
形参在使用时分配空间,函数运行结束后释放空间
形参实参数据类型必须相同,否则赋值转换(形参=实参)且warning
函数的(返回)值
调用函数中值=return后值的形式
注意:如果返回类型(被调用函数所定义的)和return类型不一样,以返回类型为准数据转换
return后面可以是变量、常量、表达式(可带括号也可不带)
若函数不需要返回值(void)
不加return语句
空return语句(return后面不加东西)
非void函数,不带return语句的报错
vs中 main函数不报错,其余函数报error
一个return只能带一个返回值
函数中可以有多个return语句(选择使用),但只能根据条件执行其中的一个,执行return后,函数调用结束(return后语句不执行)
return一定要覆盖分支/循环的全部分支/出口(否则vs有warning)
函数的重载
C不允许,只用与C艹
重载:同一作用域中多个函数使用相同名称
引入:同一功能实现,仅参数个数或类型不同,希望采用相同的函数名
实现过程
严格匹配:寻找参数个数、类型 完全一致的定义
通过系统定义的转换寻找匹配函数
通过用户定义的转换寻找匹配函数
若某一步匹配成功,则不再进行下一顺序的匹配 若某一步中发现两个及以上匹配出错
使用要求
同名函数参数个数、类型不能完全相同
返回类型和参数名不做检查
仅这两个不同认为错
若函数类型是由typedef定义的不同名称的相同类型,则会产生二义性
尽量使同名函数完成相同或相似功能,否则容易导致概念混淆
函数模板
引入原因→函数重载的不足:对于参数个数相同,类型不同,而实现过程完全相同函数,仍要分别给出各个函数的实现
建立通用函数,其返回类型及参数类型不具体指定,用虚拟类型代替
通用函数:函数模板
template <typename T>,以下所有类型都用T代替(虚拟类型)
typename可用class替代
类型定义允许多个 例如
template <typename T1 , typrname T2>
template <class T1 , class T2>
可以使不同数据类型在同一个函数中处理
内联函数
inline 返回类型 函数名(形式参数表)
使用
不单独编为一段代码,而是直接插入每一个调用处,调用时不按函数调用过程执行,而是将函数的代码放在调用处顺序执行
特征
可执行代码中无f(),仅有main(),main()代码长度增加,但没有保存及恢复现场的消耗
可执行代码长度增加,执行速度更快,适用于函数体短小且调用频繁的情况下
保存/恢复现场的代价超过函数体自身代价
不能包含分支、循环等复杂的控制语句
系统编译时会自动判断是否真正采用内联方式
写了inline最终也不一定真正成为内联函数
递归函数不能内联
递归必须要保存/恢复现场
inline添加位置
可以只在函数声明或函数定义中加,也可以同时加
inline函数及调用函数必须在同一个源程序文件中(否则编译出错)
函数的递归调用
含义:直接或间接调用本身
直接递归
间接递归
必然有条件判断是否进行下次递归调用
递归定义理解
递归指函数体中调用自己
函数返回值做本函数的参数,是嵌套(不是递归)
递归的求解过程
回推:到一个确定值为止(递归不再调用)
递推:根据回推得到的确定值求出要求的解
假设第n-1次调用已求得确定值,确定第n次调用和第n-1次调用之间存在的逻辑关系
递归函数使用
确定递归何时终止
递归函数读取
每次递归调用,借助栈记录调用层次
初始栈为空,每次递归函数被调用时在栈中增加一项,递归函数运行结束后栈中减少一项、
本次调用结束后,返回上次的调用位置,继续执行后续的语句
重复操作至栈空
不设定终止条件的递归函数 错误
运行崩溃,不同编译器有不同堆栈大小
函数的嵌套调用
C++程序执行过程
从main函数第一个执行语句开始依次执行
执行到函数调用语句,保存调用函数的一些系统信息
保存现场(进栈)
转到被调用函数的第一个执行语句开始执行
被调用函数执行完成后,返回到调用函数调用处,恢复调用前保存的系统信息
恢复现场(出栈)
嵌套执行以上步骤
特点: 嵌套层次、位置不限 先进后出(栈)
函数的调用
基本形式
无参形式:函数名()
有参函数:函数名(实参表列)
用“,”分开,要与形参表的个数、顺序、类型一致
调用方式
函数语句
函数调用+;
函数表达式
出现在某个表达式中
函数参数
作为另一个函数的参数
调用注意事项
无参函数调用时,参数位置不能写void
函数调用时,不能写返回类型
如不能写成 k=long f(),会报错 意外的类型"long"
有参函数调用时,实参不能写类型
如不能写成 k=max(int a,int b)
函数定义要写类型,调用不写
对被调用函数的说明
库函数
输入输出函数 stdio.h
数学运算函数 math.h
字符串运算函数 string.h
C语言
输入输出函数 cstdio
数学运算函数 cmath
字符串运算函数 cstring
C++
注意:cstdio和cmath这两个头文件在vs2019中可以不加
自定义函数
在调用前加以说明,位置在调用函数前/整个函数前
两种方法
返回类型 函数名(形参类型)
返回类型 函数名(形式参数 形参表)
注意事项
若被调用函数出现在调用函数之前,可以不加说明(有些编译器可能必须加)
调用函数位置
调用说明在函数外→对所有函数均适用
在函数内部→对本函数适用