当前课程知识点:高级语言程序设计 >  函数 >  7.3 函数的调用 >  函数的调用

返回《高级语言程序设计》慕课在线视频课程列表

函数的调用在线视频

函数的调用

下一节:函数参数的传递

返回《高级语言程序设计》慕课在线视频列表

函数的调用课程教案、知识点、字幕

大家好 本讲介绍函数的调用形式

上一讲我们学习了函数的定义

现在我们可以定义如下4个函数

求阶乘的函数

判断整数是否是素数的函数

求两个整数和的函数

还有求两个数幂的函数

但是这4个函数

并不是单独可运行的程序

在C语言中 有main()的程序才能运行

库函数和自定义函数

必须被main()直接或间接调用才能发挥作用

怎样使用自定义函数

先让我们回顾一下库函数的调用形式

这是函数的调用出现在表达式中

这是独立的函数调用语句

这是函数的调用作为函数的参数

自定义函数的调用形式

类似于库函数的调用形式

函数的调用需要考虑主调函数

向被调函数传递参数的问题

在定义这个函数的时候

圆括号中的变量名称

我们称它为形式参数

定义时

我们并不知道这个参数的值具体是多少

形参只能是变量

但是在调用这个函数的时候

我们需要指定形参的值究竟是多少

所以在函数调用语句当中

指定的参数应该是实际的参数

也简称为实参

实参可以是变量

可以是常量

也可以是表达式

那么C语言是如何来执行这个调用过程的

因为任何c语言程序

都是从main函数开始执行的

当执行到这条函数调用语句sum=add(a,b)的时候

首先要进行现场保护

也就是要将函数的返回地址保存下来

还要为被调函数的形参x和y分配内存

形参变量在函数调用前不占用内存

只有在被调用时才分配内存单元

在完成这项工作之后

就要进行参数的传递

也就是把实参的值复制一份给形参

例如这里是把a的值赋给x

然后再把实参b的值赋给y

注意 这个参数传递是一个单向传递的过程

就是将实参的值传给形参

由于形参和实参是不共用存储单元的

因此形参和实参的名字可以同名

并且形参值的变化是不会影响到实参值变化的

实参与形参的个数

类型 顺序都要一一对应

并且各参数间用逗号隔开

那么在完成了参数传递以后

程序的控制权就交给了被调函数

从而去执行被调函数函数体内的语句

在执行到被调函数的这条return(z)语句的时候

就从子函数退出

返回到主调函数中

当从这个函数退出返回主调函数的时候

首先要根据栈中保存的函数返回地址

返回到本次函数调用的地方

同时把函数值返回给主调函数

就是把这个函数的返回值赋值给了这个sum变量

同时把控制权还给了主函数

注意 一个函数最多只能返回一个值

但可以有一条以上的return语句

执行到哪一条return语句

哪一个就起作用

结束该函数的运行

在把控制权还给主函数之前

还要收回分配给这个子函数的所有局部变量

包括形参x和y的内存

包括变量z的内存

释放这些内存

就是说我们不能再去访问这些内存中的数据了

在完成这些工作之后

就要继续执行主函数后面尚未执行的语句

直到主函数结束为止

在一个函数中调用另一个函数需要具备如下条件

被调用函数必须是已经定义的函数

如果使用库函数

应该在本文件开头加相应的#include指令

如果使用自己定义的函数

而该函数定义的位置在调用语句后面

那么应该作函数原型声明

大家来看实例

这是我们自己定义的add函数

该函数的定义位置在调用它的语句后面

这是add函数调用语句

那么我们在程序的开头

就要加上这样一条语句

这条语句就是函数原型声明语句

注意在自定义函数的头部 末尾加上一个分号

就是函数的原型声明语句

如果是将自定义的函数放在主函数的前面

主函数里有调用语句

被调用函数的定义出现在调用语句之前

可以不做函数原型的声明

因为函数的定义

已经使得编译系统能正确识别函数

并检查函数的调用是否合法

请大家注意函数定义与函数原型声明的区别

函数原型的末尾是一个分号

它是一条语句

而函数定义的函数头部

后面是没有分号的

应该是一对花括号

是函数体的定界符

花括号里面是函数体

函数原型的主要作用就是告诉编译器

被调函数要从主调函数接收

几个什么类型的参数

并且让编译器检查函数定义中

声明的参数类型和数量

与函数原型中声明的参数类型和数量

以及它们的返回值的类型是否匹配

现在我们要编写一个任务较多的程序

在main函数里输入两个正整数

完成下面的任务

求两个正整数的和

求两个正整数的幂

求这两个正整数的组合数

还要判断这两个正整数是否是素数

如果把所有的代码都写在主函数里

主函数结构不够简洁明了

我们可以通过调用子函数来完成

这是自定义的4个子函数

求阶乘的函数

判断整数m是否是素数的函数

求两个数的和的函数

还有求两个数幂的函数

是不是把所有函数的定义都放在主函数的前面

就可以不用这样麻烦的去写它们的函数原型了

答案显然是否定的

主要有这样几条原因

首先 就是你这样做了 就是假定

只有主函数才会调用其他函数

显然这是不切实际的

因为实际上其他函数之间也会发生相互调用

如果你把所有函数的定义

都放在主函数的前面的话

那么你就必须仔细的斟酌

这些函数它们之间的顺序应该是什么样的

假如有两个函数发生了相互调用

例如a函数调用了b函数

而b函数 反过来又调用了a函数

那么在这种情况下

无论你先定义哪一个函数

都会发生函数的调用

出现在函数定义之前的情况

因此那编译器都会给出相应的错误提示

或者是警告

其实不仅如此

还有更麻烦的问题就是

当程序达到一定的规模

在一个源程序文件中

不能放置所有的函数的时候

就需要用函数原型来告诉编译器

这个函数是在其他某个文件中定义的

因此在函数的开头给出所有的函数原型

是一种良好的编程习惯

这是我们自己定义的4个函数的原型声明

在写函数的原型声明语句时

形参名是可以省略的

只写形参的类型

对于编译系统而言

只关心形参的个数和形参的类型

而不必考虑具体的形参名

一般统一在文件的开头

对所有自定义的函数做函数原型的声明

请看一个完整的源代码

这是函数原型声明语句

这是4个子函数的定义

在主函数里调用这4个子函数

这是函数的调用出现在表达式中

这是函数的调用作为函数的参数

这是独立的函数调用语句

自定义函数的调用形式

类似于库函数的调用形式

本讲的内容就是这些

谢谢大家

高级语言程序设计课程列表:

程序设计和C语言

-1.1 计算机程序和计算机语言

--计算机程序和计算机语言

--致敬先辈:伟大的C语言之父——丹尼斯·里奇 程序员

-1.2 C程序的构成

--C程序的构成

--当前主流程序设计语言各自都有什么优势?

-1.3 C语言编辑、编译、运行(VC++2010学习版)

--C语言编辑、编译、运行(VC++2010学习版)

-练习题

顺序结构程序设计

-2.1 变量的定义和使用

--变量的定义和使用

-2.2 数据类型

--数据类型简介

--整型数据

--实型数据

-2.3 格式输出和格式输入

--格式输出printf函数

--格式输入scanf函数

--单个字符的输入输出

-2.4 运算符和表达式

--运算符和表达式

-2.5 结构化程序设计入门

--结构化程序设计入门

-练习题

选择结构程序设计

-3.1 为什么要用选择结构解决问题

--为什么要用选择结构解决问题

-3.2 如何正确表示选择结构中的条件

--如何正确表示选择结构中的条件

-3.3 用if语句及if语句嵌套实现选择结构

--用if语句及if语句嵌套实现选择结构

-3.4 用switch语句实现选择结构

--用switch语句实现选择结构

-练习

循环结构程序设计

-4.1 循环的引入

-- 为什么要用循环结构解决问题

-4.1 循环的引入--作业

-4.2 用while语句实现循环

--用while语句实现循环

-4.3 用do-while语句实现循环

-- 用do-while语句实现循环

-4.4 用for语句实现循环

-- 用for语句实现循环

-4.4 用for语句实现循环--作业

-4.5 何时需要用循环的嵌套

--何时需要用循环的嵌套

-4.6 如何提前终止循环和提前结束本次循环

--如何提前终止循环和提前结束本次循环

-习题--作业

数组

-5.1 数组类型的引入

--数组类型的引入

-5.2 一维数组的定义和初始化

--一维数组的定义和初始化

-5.3 一维数组的使用

--一维数组的使用

-5.4 二维数组的定义和初始化

--二维数组的定义和初始化

-5.5 二维数组的使用

--二维数组的使用

-习题--作业

指针

-6.1 什么是指针

--什么是指针

-6.2 指针类型及相关概念

--指针类型及相关概念

-6.3 指针变量的定义、赋值与使用

--指针变量的定义、赋值与使用

-6.4 指针的运算

--指针的运算

-6.5 指针与一维数组

--指针与一维数组

-6.6 指针的指针

--指针的指针

-6.7 指针与二维数组

--指针与二维数组

-习题--作业

函数

-7.1 为什么要自定义函数

--为什么要自定义函数

-7.2 函数的定义

--函数的定义

-7.3 函数的调用

--函数的调用

-7.4 函数参数的传递

--函数参数的传递

-7.5 函数的嵌套调用和递归调用

--函数的嵌套调用和递归调用

-7.6 变量的作用域和存储类型

--变量的作用域和存储类型

-习题--作业

字符串

-8.1 字符串的存储及输入输出

--字符串的存储及输入输出

-8.2 系统字符串处理函数

--系统字符串处理函数

-8.3 自定义字符串处理函数

--自定义字符串处理函数

-习题--作业

结构体和共用体

-9.1 结构体类型的定义

--结构体类型的定义

-9.2 结构体变量及指针变量的定义及使用

--结构体类型变量和指针变量的定义和使用

-9.3 结构体变量和指针变量作函数的参数

--用结构体变量和指向结构体的指针作函数参数

-9.4 结构体数组的定义和使用

--结构体数组的定义和使用

-9.5 共用体类型和枚举类型

--共用体和枚举类型

-习题--作业

动态内存分配

-动态内存分配--习题

文件

-习题--作业

函数的调用笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。