文章目录

  • 函数
    • 1 函数的定义与使用
      • 1.1 函数的定义
      • 1.2 函数的参数
      • 1.3 函数的声明
      • 1.4 内联函数
    • 2 默认参数与函数重载
      • 2.1 默认参数
      • 2.2 函数重载
    • 3 函数模板
    • 4 库函数的调用
    • 5 函数的嵌套调用
    • 6 函数的递归调用

函数

1 函数的定义与使用

1.1 函数的定义

我想设计一个程序完成下面的计算,该如何设计程序最有效?

函数定义的一般形式为:

返回类型 函数名(形式参数列表)
{函数体声明部分函数体执行语句
}

(1)函数名
实现函数需要确定函数名,以便使用函数时能够按名引用。

(2)形式参数列表
形式参数列表是函数与调用者进行数据交换的途径,一般形式为:

函数可以没有形式参数,定义形式为:

(3)返回类型
返回类型可以是C++除数组之外的内置数据类型或自定义类型。

函数可以不返回数据,此时返回类型应写成void,表示没有返回值,其形式为:

没有返回值的函数,在调用处是不能按表达式来调用函数的,只能按语句形式调用函数,因为函数没有返回值也就不能参与表达式运算。

m=max(a,b); //以表达式的方式调用max函数
print( );   //以语句的形式调用print函数

当函数的返回类型不是void,表明函数有返回值。如果函数体内没有return语句,此时函数返回的值是与返回类型相同但内容却是随机的一个值。

(4)函数体
实现函数最重要的是编写函数体。函数体(function body)包含声明部分和执行语句,是一组能实现特定功能的语句序列的集合。

  • 编写函数体是为了实现函数功能。故称函数定义为函数实现,简称实现
  • 而函数头简称(函数的第一行)接口

例子:使用函数实现判断一个数是否是素数。

# include<iostream>        // 标准输入输出函数库
using namespace std;
int IsPrime(int m)  // 求素数函数
{// 枚举法求m是否为素数int i;for (i = 2; i < m - 1; i++){if (m % i == 0)return 0;   // 不是素数返回0return 1;                  // 是素数返回1}
}
int main()
{int m;cin >> m;if (IsPrime(m)) cout << "Yes" << endl;   //是素数输出Yeselse cout << "No" << endl;               // 不是素数输出Noreturn 0;
}

1.2 函数的参数

函数参数是实现函数时的重要内容,是函数接口的首要任务,围绕这个目标需要研究:

形式参数的定义与实际参数的对应关系。

函数参数的数据传递机制,包括主调函数与被调函数的双向数据传递。

形式参数

函数定义中的形式参数列表(parameters),简称形参。例如:

第1行ab就是形参。

形式参数相关说明:
1)函数定义时指定的形参,在未进行函数调用前,并不实际占用内存中的存储单元。
2)只有在发生函数调用时,形参才分配实际的内存单元,接受从主调函数传来的数据。
3)当函数调用结束后,形参占用的内存单元被自动释放

实际参数
函数调用时提供给被调函数的参数称为实际参数(arguments),简称实参。

实参必须有确定的值,因为调用函数会将它们传递给形参。实参可以是常量、变量或表达式,还可以是函数的返回值。例如:

实参相关说明:

1)实参的类型、次序和数目要与形参一致。
2)如果参数数目不一致,则出现编译错误;
3)如果参数次序不一致,则传递到被调函数中的数据就不合逻辑,难有正确的程序结果;
4)如果参数类型不一致时,则函数调用时按形参类型隐式类型转换实参;

程序通常有两种函数参数传递机制——值传递和引用传递。

值传递(pass-by-value)过程中,形参作为被调函数的内部变量来处理,即开辟内存空间以存放由主调函数复制过来的实参的值,从而成为实参的一个副本
值传递的特点是被调函数对形参的任何操作都是对内部变量进行,不会影响到主调函数的实参变量的值

值传递时,实参数据传递给形参是单向传递,即只能由实参传递给形参,而不能由形参传回给实参。

1.3 函数的声明

当要调用函数时,C++语言规定在调用一个函数之前必须有该函数的声明。

C++规定函数的定义既是函数定义,也是函数声明。换言之,只要函数调用是写在函数定义的后面,就自然有了函数声明。

声明的作用是程序向编译器提供函数的接口信息,因而多次提供接口信息是允许的,但不能提供相互矛盾、语义不一致的接口信息。

函数原型
函数原型(function prototype)的作用是提供函数调用所必须的接口信息,使编译器能够检查函数调用中可能存在的问题,有两种形式:

  • 第一种形式:

  • 第二种形式:

# include<iostream>        // 标准输入输出函数库
using namespace std;
int gcd(int m, int n);      // gcd函数原型,gcd函数声明在前
int main()
{int m, n;cin >> m >> n;cout << gcd(m, n) << endl;  // 调用时已有gcd函数声明return 0;
}
int gcd(int m, int n)     //求最大公约数,gcd函数实现在main后
{int r;while (n != 0){r = m % n;m = n;n = r;}return m;
}

函数调用
有了函数声明,就可以调用函数,有参数函数调用的形式为:

函数名(实参列表)

实参可以是常量、变量、表达式和函数调用,各实参之间用逗号(,)分隔。实参的类型、次序、个数应与形参一致。

在C++语言中,可以用以下几种方式调用函数。

1.4 内联函数

C++提供一种提高函数效率的方法,即在编译时将被调函数的代码直接嵌入到主调函数中,取消调用这个环节。这种嵌入到主调函数中的函数称为内联函数(inline function)。

内联函数的声明是在函数定义的类型前加上inline修饰符,定义形式为:

内联函数中不允许用循环语句和switch语句(复杂的语句)。(有点像中断)

内联函数的声明必须出现在内联函数第一次被调用之前。
例子:

# include<iostream>        // 标准输入输出函数库
using namespace std;
inline int fun(int a, int b)
{return a * a + b * b;
}
int main()
{int n = 5, m = 8, k;k = fun(n, m);    // 调用点嵌入a*a+b*bcout << "k=" << k << endl;return 0;
}

实线为一般函数;虚线为内联函数。

2 默认参数与函数重载

2.1 默认参数

C++允许在函数定义或函数声明时,为形参指定默认值,这样的参 数称为默认参数(default argument),一般形式为:


(1)如果在函数定义时设置了默认参数,那么就不能在函数声明 中再次设置,反之亦然。

(2)可以设置多个默认参数,设置的顺序为自右向左,换言之, 要为某个参数设置默认值,则它右边的所有参数必须都是默认参数。

(3)默认值可以是常量、全局变量,甚至是一个函数调用(调用 实参必须是常量或全局变量的表达式),不可以是局部变量。

默认参数函数的调用
默认参数本质上是编译器根据函数声明或函数定义时的默认参数设 置,对函数调用中没有给出来的实参自动用默认值表达式“补齐” 再进行编译。

2.2 函数重载

函数重载(function overloading)是在同一个域中用同一个函数名来定义多个函数,但函数参数列表应彼此有不同,或者是参数个数不同,或者是参数类型不同,或者两者均有不同。




函数重载的使用说明:
(1)重载函数的形参必须不同(个数不同或类型不同)。
(2)编译程序将根据实参和形参的类型及个数的最佳匹配来选择调用哪一个函数。
(3)不要将不同功能的函数声明为重载函数,以免出现调用结果的误解、混淆。

3 函数模板

函数模板(function template)是一个独立于类型的函数,可作为一种模式,产生函数的特定类型版本。
函数模板能建立一个通用功能的函数,以支持多种不同形参,进一步简化了重载函数的设计。
重载的情况(函数体要描写两次):

使用函数模板可以设计通用型的函数,这些函数与类型无关并且只 在需要时自动实例化,从而形成“批量型”的编程方式。
函数模板定义的语法形式为:

用TTT代表一种不确定的数据类型,然后在描述函数时用TTT代替相应的数据类型

模板形参表(template parameter list)是用一对尖括号括< >括起 来的一个或多个模板形参的列表,不允许为空,形参之间以逗号分 隔,其形式有两种。

  • 第一种形式

如上文例子。

  • 第二种形式

4 库函数的调用

所谓库函数是指事先由程序员编制好的函数。
多数情况下,基于各种理由,如保护知识产权,这些库函数仅提供二进制形式的目标代码给调用者链接,却没有提供源码形式的函数定义。

(1)在程序中添加库函数声明
多数库函数将自己的函数原型和特殊数据等放在头文件(.h)中, 所以应首先使用文件包含命令将这些头文件包含到程序中。例如欲 使用数学库函数,文件包含命令为:

#include <cmath>

从而使得程序有函数声明,例如:

y=sin(x);

调用就能够通过编译

(2)将库函数目标代码连接到程序中。

在连接时,例如使用了sin函数,就必须要有sin函数的实现代码才 能生成可执行文件,否则连接出错。要将库函数的目标代码能够连接到程序中,主要是配置好开发环境的相关参数,然后由连接器处理。

标准库函数的连接在开发环境中是默认的,一般可以不用特别设置。

5 函数的嵌套调用

在调用一个函数的过程中,又调用另一个函数,称为函数的嵌套调用,C++允许函数多层嵌套调用,只要在函数调用前有函数声明即可。


6 函数的递归调用

古之欲明明德于天下者,先治其国;欲治其国者,先齐其家;欲齐其家者,先修其身;欲修其身者,先正其心;欲正其心者,先诚其意;欲诚其意者,先致其知,致知在格物。
物格而后知至,知至而后意诚,意诚而后心正,心正而后身修,身修而后家齐,家齐而后国治,国治而后天下平。

函数直接或间接调用自己称为递归调用。C++语言允许函数递归调用,如图(a)所示为直接递归调用,如图(b)所示为间接递归调 用。

C++程序设计-西北工业大学-魏英、姜学锋、刘君瑞

【C++】(八)函数相关推荐

  1. python语言程序设计实验答案实验八函数_C++程序设计 实验8 实验报告 标准答案...

    实验编号 及实验名称 实验 8 静态成员练习:学生成绩统计 系 别 计科系 姓 名 学 号 班 级 实验地点 实验日期 实验时数 2 指导教师 同组其他成员 成 绩 一. 实验目的及要求 1. 通过在 ...

  2. 实验八——函数定义及调用总结

    1.本次课学习到的知识点: (1)学习了数字金字塔.pyramid ()函数功能,函数定义时,形参n决定数字金字塔的层数: (2)不返回结果的函数定义: (3)复数运算: c1=x1+(y1) i,c ...

  3. Swift傻傻分不清楚系列(八)函数

    本页包含内容: 函数定义与调用(Defining and Calling Functions) 函数参数与返回值(Function Parameters and Return Values) 函数参数 ...

  4. 智慧树c语言实验八函数,C君带你玩编程

    第一章 认识C语言 认识C语言 C语言的历史与特点 C语言的历史与特点 算法及其表示 算法及其表示 C程序的操作过程 C程序的操作过程 C程序的基本结构 C程序的基本结构 标识符.关键字和保留字 标识 ...

  5. Python学习日记(八) 函数

    函数的结构: 函数的返回值: 1.当函数执行时运到return关键字将不再往下执行 def func():print("hello world!")print("hell ...

  6. 【WY】数据分析 — Pandas 阶段一 :基础语法 八 —— 函数汇总

    版权声明:本文为博主原创文章,未经博主允许不得转载. 文章目录 一.通用函数 1.1 pd.cut 一.通用函数 1.1 pd.cut pandas.cut(x, bins, right=True, ...

  7. c语言入门---函数

    目录标题 一.前言 二.函数是什么 三.c语言中函数的分类 四.为什么会有库函数 五.如何使用库函数 六.为什么会有自定义函数 七.如何来创建自定义函数 八.函数的参数 1.实际参数(实参) 2.形式 ...

  8. 学习日记·C语言学习-函数

    目录 一函数的基础知识 二传值和传地址 三传地址 四函数的传出传入参数 五命令行参数(主函数参数) 六使用注意事项 七函数指针 八函数指针数组及指针复杂声明 九复杂指针的声明 十可变参数 1.函数基础 ...

  9. Programming Language Pragmatics 习题解答七(类型系统)、八(子程序和控制抽象)

    第七章介绍了类型系统,包括内部类型(record,array,recurision,file).可自定义类型.类型等价性/类型相容/类型推理的规则,类型的转换/强制/非变换类型转换,类型等价(基于名字 ...

  10. C语言指针这一篇够了(一万二千字,包含指针与数组,函数指针等详解)

    目录 零.前言 一.指针的定义 二.指针类型的意义 1.指针类型决定了指针解引用时一次访问几个字节. 2.指针类型决定了指针加减整数时的步长 三.野指针 1.未初始化的指针 2.指针的越界访问 3.指 ...

最新文章

  1. vs编译器 printf 控制台输出_【必备】推荐几款好用的C/C++ 在线编译器?
  2. 《OpenGL游戏程序设计》学习笔记---第七章图像、位图与OpenGL
  3. 深度学习方法笔记之(一):SVM的基本模型
  4. mel表达式_maya 2012 mel 表达式编辑器
  5. klearn 文本分类_使用gensim和sklearn搭建一个文本分类器
  6. fullcalendar 显示的时间间隔只有四十五分钟_【体能新视点】——女子篮球运动员比赛期间的心率、血乳酸浓度和时间运动分析...
  7. 如何让fragment每次都重新加载_带上税控在哪都能开票,如何重新安装开票软件?...
  8. 高观点下的高等数学(数学分析、线性代数)
  9. Common lisp编译成C的bin(二)
  10. 倒车雷达c语言编程,汽车倒车雷达系统的设计与实现(论文c1)
  11. maven安装教程(保姆级别)
  12. 思科交换机接口配置trunk_思科交换机配置TRUNK的主要步骤
  13. SitePoint播客#108:Kevin的最后一场演出
  14. 手机无法服务器获取信息,荒野行动获取服务器信息一直不动怎么办 获取服务器信息为0解决方法...
  15. 入门用Python进行Web爬取数据:为数据科学项目提取数据的有效方法
  16. Google Map Api 谷歌地图接口整理
  17. matlab分离实部虚部,MATLAB/simulink中,想让电流表测出的值为复数形式,有实部虚部,将powergui设置为phasors仿真,总是出错...
  18. 百度,你出来解释下什么是文本相似?
  19. 牛客网赛码网 输入输出格式 pythonC++
  20. 还记得这门古老的编程语言么,送你一份perl书单!

热门文章

  1. oracle的imp输出日志,Oracle下的exp/imp
  2. html如何制作斜线表头表格,word表格斜线-第六十五式:三种方法教会你,如何在Word中的表格制作斜线表头...
  3. Win10笔记本电脑怎么直接重置初始化
  4. 21个小故事、透过现象看本质
  5. 隐藏Excel单元格重要数值,不显示数值
  6. VS Code常用快捷键
  7. inno setup 卸载注册表_Inno Setup Compiler卸载时删除注册表
  8. 怎么用计算机算lg多少是一个数,数学lg怎么算
  9. php公网不能访问8080,linux启动tomcat外部浏览器不能访问8080端口解决方案
  10. MYSQL从简单查询到高级查询(一)