第6讲函数与程序结构
2013-2函数和程序结构资料

(2)函数原型
?问题
函数定义在main()之前太臃肿!
C++引入了 函数原形 概念 函数原形 是对函数的引用性声明 函数由 先定义再调用 变成:main()前先 声明,然后在main()中调用,最后在 main()后面,给出函数定义 函数原型使函数的声明和使用分离开来,使 程序书写格式清楚,重点突出,便于程序扩 充。
5 返回地址 funcB ( ) 调用函数funcA运行状态 n 5 12 bb aa 6 返回地址 funcA ( ) 调用函数main运行状态 12 b a 6 参数 main ( ) 返回地址 操作系统运行状态 栈底
函数调用的返回
栈区 1.系统先分配一个临时空间( 寄存器) 把返 …… 回值保存在临时变量空间中 2 临时变量赋值给接收返回值的变量 5 3. 恢复主调函数的运行状态,释放栈空间 (栈顶指针下移) 返回地址 4. 根据返回地址,回到主调函数 调用函数funcA运行状态 5. 释放临时空间 5
函数调用时栈的建立过程
void funcA ( int, int ); void funcB ( int ); void main ( ) { int a=6, b=12; funcA (a, b); } void funcA ( int aa, int bb ) { int n = 5; … funcB (n); } void funcB ( int s ) { int x; …} x s 栈区 …… 栈顶
《C语言函数》PPT课件

#include <stdio.h>
int sum(int a, int b)
{
a=a+b;
b=a+b;
函数被调用之前,形参和子函数中的变量
return(a);
不占内存,调用结束返回,形参所占的内存被收回.
}
实参和形参传递的是”值传递”,
void main() {
即单向传递, 只与参数相对位置有关,而与 变量名无关
void printMessage() {
printf(“Hello, world.\n”); printStar(); }
void main() {
printStar(); printMessage(); }
-
12
C语言程序设计
第 6 章 模块化程序设计--函数
函数的调用
一、函数调用一般形式
一般形式: 函数名(实参列表)
3.实参可以是常量、变量或表达式.
z=c(=x>( ya)>?bx) :?ya; :b;
因为传递过来的是具体数值.
retruertnu(rzn)(;c);
4.实参和形参类型必须一致(或可以安全转换).
} void main()
5.C语言中,实参和形参传递的是”按值传递”, {
即单向传递, 只与参数相对位置有关,而与
按生存期局部变量全局变量自动变量静态变量寄存器变量形式参数变量动态存储静态存储自动变量形式参数寄存器变量静态局部变量全局变量按变量的存放位置动态存储区静态存储区自动变量形式参数静态局部变量全局变量寄存器寄存器变量c语言程序设计模块化程序设计函数202137chenli33自定义的函数有两种
模块化程序设计
C语言课件第六章函数

printf(“Max=%d”,a);
}
合 iTemp的作用域。 iTemp 肥 ⒉register存储类型
工 作用域和生存期和auto相同,
差别在于,如果CPU内部的寄存
业 器空闲,则使用寄存器作为变量 大 的存储单元,以提高速度。主要
用于循环变量。
学
⒊static(静态)存储类型
作用域:在定义的复合语句内引用,出了复合语句不可见。
定义!
学
⒉函数的定义
格式: type 函数名(参数说明表) int max(int x ,int y)
{ 内部说明语句 ;
如果函数有{ 返回值,应含
功能语句 ; 有return语句。int z ;
Xuan shanli
}
z=x>=y? x : y ;
说明:
合 ⑴函数不能嵌套定义,但可以嵌套引r用et,ur包n (括z引) ;用自己。
关于返回值的几点说明:
⑴函数可以通过一个return语句返回一个值,也可以不返回值,
此时应在定义函数时用void类型加以说明。
⑵函数中可以出现多个return语句,遇到一个return 语句,则
返回值,且返回调用函数,继续执行。
⑶返回值的类型应与函数的类型一致,如不一致,以函数类型
Xuan shanli
fun( );
a
printf(“a=%d,b=%d\n”,a,b);
}
合
void fun(void) {
b
肥
int c;
工
c=a; a=b; b=c; }
业
大
学
外部变量的副作用
Xuan shanli
#include <stdio.h>
C语言函数篇讲解ppt课件

b函数结束
精选版课件ppt
20
main( ) { int x,y,sum;
x=5; y=6; sum=add(x,y); printf(“%d”,sum); }
add(int a ,int b) { int z;
z=a+fun(b); return z; } 运行结果:
41
精选版课件ppt
汉诺塔问题 ( Hanoi)
数调用任意多次。 4. 从用户角度看,函数分为两种:
① 标准函数:即库函数,由系统提供。
② 用户自定义函数:用户自己定义的。 5. 从函数形式看,函数分为两种:
①无参函数。
②有参函数。
精选版课件ppt
3
6.2 函数定义的一般形式
一 函数定义的一般形式
列表
类型标识符 函数名(类型1 形参1,类型2 形参2,…) { 声明部分 语句 }
二 说明:
1.所有函数在定义时都是互相独立的,即不能嵌套定义; 2.类型标识符:说明了函数返回值的类型,当返回值为
int时,可省略不写; 3.函数名:遵循标识符的命名规则;同一个函数中函数名
必须唯一;
精选版课件ppt
4
4.形参:只能是变量,每个形参前要有类型名;当定义的 函数没有形参时叫作“无参函数” ;
a 10 20 b
alter(a, b);
printf(“a=%d,b=%d\n”,a,b); x 1200 }
210 y
alter(int x, int y) { int t;
t=x; x=y; y=t; }
总结:形参的值发生 改变,并不能 影响实参。
精选版课件ppt
9
三 函数的返回值
第六章 函数

第六章 函数
算法实现部份
} 函数定义包含函数说明部分和函数体。
Page 9
6.2 函数的定义
函数定义的一般形式
第六章 函数
函数说明部分“类型说明符 函数名(带类型说明的形式参数表列)”称 为函数头,又称为函数原型,是函数进行交互的接口。函数名是用户 标识符,用来唯一标识一个函数。带类型说明的形式参数表列说明了 函数形参的类型及形参变量名,用逗号分开。类型说明符定义函数的 类型,函数类型是函数返回值的类型,可以是基本数据类型,也可以
Page 27
6.5 变量的作用域与生存期
变量的属性 变量的属性包括操作属性和存储属性。
第六章 函数
变量类型决定了变量的取值范围、占用存储单元数量等操作属性。变 量的存储属性决定了变量的作用域和变量的生存期。变量的作用域指 变量的作用范围,按照变量的作用域可把变量分为全局变量和局部变
Page 5
6.1 概述
函数分类 1.从用户角度分类 从用户角度,函数可分为库函数和用户自定义函数。
第六章 函数
库函数是由C编译系统提供,用户可直接使用而无须定义的函数。C 语言把一些常用功能预先编写为函数,放在函数库中。
用户自定义函数是由用户根据自己的需要编写的具有独立功能的函数
。
Page 6
表示;函数类型是函数实现功能后结果的类型。
函数体是函数功能的实现,实现函数功能的程度段书应写在“{ }”内 。
Page 3
6.1 概述
函数概述 2.函数声明
第六章 函数
函数声明的作用是通知编译系统被调函数的有关信息(函数类型、名 称、参数类型及数量),以便函数调用时,编译系统能够正确识别该 函数,确保函数调用正确进行。
程序与递归-组合-抽象与构造

(square 10)
名字的使用
(square (+ 2 8))
(square (square 3))
(square (square (+ 2 5)))
(define (SumOfSquare x y) (+ (square x) (square y))
1. 程序的作用和本质 1.1 怎样设计并实现一个计算系统?
如何设计实现一个基本计算系统?
首先,设计并实现系统可以执行的基本动作(可实现的),例如
“与”动作 “或”动作
已知的基本事实是:
“非”动作 “异或”动作 那么,复杂的动作呢?
“加减乘除运算都可转换为加法运算来实现” “加法运算又可以转换为逻辑运算来实现”
(define circumference (* 2 pi radius)) (* circmference 20)
程序与递归:组合-抽象与构造 3. 程序构造示例(II)
程序构造示例(II)
----组合、抽象与构造 ----命名新运算符和构造中使用新运
算符及执行中以过程替换新运算符 ----带有条件的运算组合式
先代入,后求值
代入阶段 求值阶段
3. 程序构造示例(II) 3.4 有条件的运算如何表达?
带有条件的运算组合式
(cond ( <p1> <e1>) ( <p2> <e2>) ... ( <pn> <en>) )
(define (abs x) (cond ((> x 0) x) ((= x 0) 0)
次的系统
程序 复杂动作 = 基本动作的各种方式的组合 (V1 + V2) x (V3 V4) V5
第六章函数和程序结构

6.2 库函数
C 程序中调用库函数需要两步: 1.使用include命令指出关于库函数的相关定义和说明。 include命令必须以“#”开头,系统提供的头文件以.h作为文件后 缀 , 文 件 名 用 一 队 尖 括 号 <> 或 一 对 双 撇 号 ” ” 括 起 来 。 # include开头的程序行不是C语句,末尾不加“;”号。 2.调用标准库函数 调用库函数的形式为: 函数名(参数表) (1)表达式中调用:函数是表达式的一个运算对象。 如 y = z*sin(x)+0.5; (2)作为独立语句:可看作表达式语句 如 printf(“%d\n”,a);
6.3 函数定义
C语言中定义函数的一般形式为: 函数返回值类型名 函数名(类型名 形参1,类型名 形参2…) /* 头部 */ { 说明部分 /* 函数体*/ 语句部分 } return语句的形式如下: return 表达式; 或 return (表达式);或 return ; return的作用:退出函数,并带回函数值。
6.5 调用函数和被调函数的数据传递
C语言中,调用函数和被调函数之间的数据传递有三种方式: (1)实参和形参之间数据传递 (2)return 语句把函数值返回调用函数。 (3)通过全局变量。(全局变量在本章稍后讨论) C语言中实参和形参之间数据传递的方式叫“值传递”,数据只能 从实参单向传递给形参。函数调用时,首先计算实参表达式的值,求出 的值分别赋给对应的形参,进入函数体执行,形参本身就是局部于函数 的变量,调用时接收实参的值。函数内部对形参的赋值与实参变量毫无 关系。实参变量的值不会被改变。实参与形参传递值时,隐含着可能的 转换。如转换不能进行,编译时产生类型错误。 C的函数调用机制很简单,值传递是C语言实参形参结合的唯一方 法,续章节中,我们会看到数组名和指针做函数参数的情形,它们进行 实参形参结合的方式离不开值传递这个本质。
第六章 子程序和函数PPT课件

在子程序中还可以调用子程序,也可以调用它自身(递归调用)。
子程序的输入
在QBASIC环境下,无论在哪个编辑窗口,只 要在新一行键入子程序的初始行,如:SUB Star(n AS INTEGER),按回车键;如果已经输 入主程序,将窗口Split,在其中的一个窗口中 的主程序后键入子程序(该窗口中的主程序会 自动清除,而且存盘后另一窗口主程序的前面 加DECLARE SUB 子程序名);通过View菜 单的SUBs…菜单项选择或激活要编辑的子菜 单或主程序。
IF (x > y) THEN fmax% = x: EXIT FUNCTION
ELSE fmax% = y: EXIT FUNCTION
END IF END FUNCTION
模块化的函数
FUNCTION函数的结构形式如下: FUNCTION〈函数名〉[〈形参表列〉][〈STATIC〉] … LET〈函数名〉=〈表达式〉 … END FUNCTION
DECLARE FUNCTION fmax% (x AS INTEGER, y AS INTEGER) REM main program DIM a AS INTEGER, b AS INTEGER, max AS INTEGER INPUT "Plese input a,b="; a, b PRINT "a="; a, "b="; b max = fmax%(a, b) PRINT "The max is:"; max END FUNCTION fmax% (x AS INTEGER, y AS INTEGER)
abxy 21.2 12.1 0 0
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第六讲函数和程序结构6.1 概述一、问题提出前面的程序中,都用到了主函数“main”及C语言提供的输入输出库函数scanf和printf等函数,目前除了调用库函数实现某些功能外,所有的练习中程序功能均在主函数中完成,当问题有一定规模和复杂度时不可避免地会出现如下问题:①程序越来越长,难于理解且可读性下降。
②重复代码增多,某段程序可能被执行多次。
③某一问题中的代码,无法在其他同类问题中再用,必须重复原来设计编码的过程。
④程序各部分之间联系复杂、保特重用代码段的一致性等原因导致程序调试难度加大。
二、函数机制的引入由于以上问题,所以需要一种机制,能够有效地分解复杂的描述,控制程序规模和复杂性,C语言中,这种机制就是函数。
使用函数,把一段处理过程抽象出来,作为程序中独立的函数实体,这样通过函数之间的调用就可以完成复杂的处理任务了。
函数机制的本质是封装一段操作,对其他模块隐藏函数内部的实现过程,只提供调用方法,即接口参数和返回值。
被抽象成函数的程序段通常是功能独立、具有独立逻辑意义的程序段和重复出现的代码段。
三、函数机制的提供的好处①函数可以被多次调用, 从而减少程序的长度。
②增加程序的可读性。
③程序的模块化、结构化更强。
四、函数的定义与调用C语言中, 函数名是上述封装体的名称。
函数定义是按照规定形式对函数的描述。
函数调用是要求执行函数的描述。
一个实用的C语言源程序总是由许多函数组成, 这些函数多数都是根据实际任务由用户来编写的, 在这些函数中, 可以调用C语言提供的库函数, 也可调用用户自己写的或他人编写的函数。
五、函数的执行C程序总是从主函数 main 开始执行, 到主函数的最后一个“}”确处结束。
在 main 中, 调用库函数或自己定义的函数时, 控制权转移到函数, 主程序等待, 待函数执行完毕后, 控制返回到调用处, 主函数继续执行。
其他函数中调用函数的过程与此相同。
六、掌握函数的使用与函数的定义从C语言函数来讲, 一方面要掌握库函数的调用方法, 尽可能地熟悉系统提供的常用库函数的功能, 尽量使用库函数实现程序功能。
另一方面,库函数毕竟不能解决所有的问题, 需要掌握自己定义函数的方法。
七、在程序设计中要注意对函数的两种观点一种观点是从函数外部调用者的角度考虑怎样使用和设计函数,不论是库函数还是自定义函数, 我们只关心函数如何使用, 实现什么功能、函数名字是什么、有几个参数、类型是什么、返回什么值, 而不关心函数内部的实现细节,也没有必要关心。
从这个层次上考虑问题, 可以摆脱细节干扰、把握总体和全局应该具有的功能和结构。
另一种观点是从函数内部实现者的角度, 定义函数实现的功能, 要考虑函数启动时需外部提供什么数据及其类型、函数如何工作、如何得到结果、何时结束、如何返回结果, 而不关心外部什么地方调用这个函数, 调用时具体参数是什么。
我们在函数内部定义的计算功能是具有一般性的抽象计算功能, 只有函数被调用的时候, 才具体化地解决一个实际问题。
6.2 库函数一、熟悉库函数的使用C语言非常简洁, 程序所需的许多东西通过函数方式提供。
掌握C语言的一个重要方面, 就是要熟悉库函数的使用。
ANSI C标准对过去各种C语言系统的函数进行了分析, 并将其规范化, 它将一批最常用的功能总结出来, 定义了C语言的标准库、每种C语言系统, 都按照这个标准提供了一批标准库函数, 还根据实际运行环境提供了扩充函数库。
写C程序时可直接调用函数,不必关心函数是如何实现的, 这样可节省大量的时间和精力。
使用库函数, 要学会使用联机帮助或系统的有关手册。
参考 P371 列出了常用的库函数。
二、调用库函数的两个骤步①使用 include 命令指出关于库函数的相关定义和说明。
include 命令必需以“#”开头, 系统提供的头文件以 .h 作为文件后缀, 文件名用一对尖括号“< >”或一对双撇号 " " 括起来。
include 的功能在下一章介绍, 它的使用形式如下:#include <math.h>math.h 是有关数学函数的头文件。
#include 开头的程序行不是C语句, 末尾不加“ ; ”号。
②调用标准库函数。
调用库函数的形式为:函数名(参数表)。
三、库函数调用的两种方式①表达式中调用。
函数是表达式的一个运算对象, 如 y = z * sin(x)+ 0.5 这种调用方式, 通常需要使用函数的返回值进行计算;②作为独立语句。
可看作表达式语句如printf("%d\n”, a);四、库函数联机帮助在 Turbo C的编辑器中, 将光标置于库函数的任意一个字符上, 按下"Ctrl+F1", 可得到关于此库函数的定义信息。
调用库函数时, 要注意按照库函数的参数类型(形参)要求, 给出调用的参数(实参)。
实参可以是表达式, 函数调用的第一步就是计算实参的值, 然后传给形参变量。
6.3 函数定义(P156)一、一般格式函数类型函数名(类型名形参1, 类型名形参2…){ 说明部分语句部分}二、说明①函数名、形参是用户命名的标识符, 同一程序中, 函数名必须唯一,形参名在同一函数中唯一即可, 可以与其他函数中的变量同名。
② C语言规定, 不能在函数的内部再定义函数(即嵌套定义)。
所有函数都是互相平行独立的。
③省略返回类型名时, 缺省值为 int。
④函数名后括号内的参数叫形参, 形参必须用括号括起来,可有多个形参, 也可以一个也没有。
⑤函数定义的一对 { } 中可以为空, 这样的函数什么也不做。
⑥函数体中说明部分的变量, 只在函数体内有效, 并在进入函数时为变量开辟单元, 退出时释放分配的单元。
函数体中说明部分的变量与其他函数体中的变量互不相关。
⑦函数头部构成函数内外部之间的界面。
函数接口定义清楚了, 函数的定义和使用完全可以由不同人来完成。
⑧函数允许递归调用, 即在函数中可直接或间接地调用自己。
⑨函数值通过 return 语句返回。
例无参函数printstar( ){ printf( "**********\n");}或printstar(void ){ printf( "**********\n");}例有参函数(现代风格)int max( int x, int y){ int z;z=x>y?x:y;return(z);}例空函数dummy( ){ }【例6.1】写一个函数, 求两个双精度浮点数的和。
double add( double a, double b ){ double s;s=a+b;return s;}⑩在老版本 C语言中, 参数类型说明允许放在函数说明部分的第 2 行单独指定。
其格式如下:函数类型函数名(形参表)形参类型说明{ 说明部分语句部分}例如: 求两个双精度浮点数的和, 写成传统风格的有参函数如下:double add( a, b )double a,b ; /* 参数类型说明 */{ double s;s=a+b;return s;}三、函数的返回值1、返回语句形式 return (表达式);2、或 return 表达式;3、或 return;4、功能:使程序控制从被调用函数返回到调用函数中,同时把返值带给调用函数。
5、说明:●函数中可有多个 return 语句;●若无 return 语句, 遇 } 时, 自动返回调用函数;●若函数类型与 return 中表达式值的类型不一致, 按前者为准,自动转换--函数调用转换;●void 型函数表示该函数没有值返回, 调用这类函数的惟一的方法就是作为独立的语句。
6.4 函数的调用和函数说明(P162)一、函数的调用●函数调用的形式:函数名(实参表);●函数调用方式。
与库函数的调用类似,有以下两种调用方式:①函数语句。
只进行某些操作, 不返回函数值。
以函数作为独立的语句,末尾一定要加“;”号。
②函数表达式。
函数作为表达式的一项, 出现在表达式中, 以函数返回值参与表达式的运算。
这种方式要求函数是有返回值的。
③函数参数。
函数调用作为一个函数的实参。
如:①函数表达式例 5.l 定义的函数 add, 允许下列的调用方式:y = add( 3.0, 4.0 );for ( y = 0, i = 1; i <= 5; i++ )y = add( y, i ) ;if ( add( x,y ) ) > 0 { … }printf(“%d”,add(a,b) ); /*函数为参数*/②函数语句而对于前面定义的函数 printstar 只能用函数语句调用方式:printstar();③函数参数m=max(a,max(b,c));●说明⏹函数名后面的列表内的参数叫实参。
⏹调用的函数名字必须与定义的函数名字完全一致。
⏹实参个数与形参个数应一致, 类型也应统一;如不匹配, 系统进行自动转换。
不兼容的赋值转换(某些类型之间不能进行赋值,如指针和浮点类型之间)并不给出错误信息, 程序继续运行,但结果不正确,这点应特别注意。
⏹函数可以嵌套调用。
如 a 函数调用 b 函数, b 函数中又调用 a函数。
(但数不许嵌套定义)⏹实参表求值顺序, 因系统而定 (Turbo C 自右向左)如:参数求值顺序main(){ int i = 2, p;p = f( i, ++i ); //改成p = f( i, i++ );运行结果是1 printf("p = %d", p);//运行结果是0}int f(int a, int b){ int c;if (a>b) c=1;else if (a == b) c=0;else c = -1;return (c);}【例6.2】写程序, 从键盘读入两个浮点数, 用例6.1 中定义的函数求两个双精度浮点数的和。
程序#include<stdio.h>double add(double,double) /* 原型说明 */main(){ double x, y, z ;scanf( " %lf%lf ",&x, &y );z=add( x , y )printf( " z = %lf ", z);}double add(double a , double b){ return ( a + b );}二、函数说明(P163)1、函数的原型说明概念C语言规定, 函数必须先定义, 后调用。
但实际写程序时, 由于函数之间可能互相调用, 也很难保证这种关系总是成立。
解决这种问题的方法是在调用之前对函数进行说明, 这种方法称为函数的原型说明。