第6讲函数与程序结构
- 格式:doc
- 大小:133.50 KB
- 文档页数:19
第六讲函数和程序结构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语言规定, 函数必须先定义, 后调用。
但实际写程序时, 由于函数之间可能互相调用, 也很难保证这种关系总是成立。
解决这种问题的方法是在调用之前对函数进行说明, 这种方法称为函数的原型说明。