c4-function,c语言.ppt_第1页
c4-function,c语言.ppt_第2页
c4-function,c语言.ppt_第3页
c4-function,c语言.ppt_第4页
c4-function,c语言.ppt_第5页
已阅读5页,还剩89页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Computer Science & Technology HIT,September 2011,High-Level Language Programming,ZhongChuan Fu (傅忠传),Chapter IV,Functions 函数,Outline,函数原型(prototype)。函数definition定义和函数原型prototype说明declaration的方法及二者区别,调用。 掌握函数的参数传递方式与函数调用方法实参argument,形参parameter。 理解掌握variable变量的scope作用域和storage class存储类的概念。,Contents,functions函数 scope and storage class 变量作用域与存储类 *homework Pitfalls 5. #define macro 宏定义,Contents,function函数 1.1. functions相关概念 1.2.function definition函数定义 1.3. return value函数的返回值 1.4.function calling调用与parameter passing参数传递 1.5. prototype declaration函数原型声明 scope and storage class变量作用域和存储类 *homework Pitfalls *#define macro宏定义(macro substitution),Structure of a typical C program,functions函数,(1) functions commercial programs have hundreds or thousands of lines of code. In order to reduce the complexity involved in writing large programs, they have to be broken into smaller, less complex parts. Functions, along with classes become the building block of c/c+.即所谓的分而治之(divide and conquer).,(3)C程序的执行从main()函数开始。没有main( )函数的程序,不能执行。 调用其他函数后流程回到main函数,在main函数结束整个程序运行。 main函数是系统定义的。,(4)主函数可以调用任意子函数,而子函数不能调用主函数。 子函数的地位是平等的,相互独立,相互无从属关系,可以相互调用。 子函数可以直接或间接地自己调用自己,即递归调用。,functions(1),Built-in standard library functions标准库函数 使用:用#include 命令将调用函数所需头 文件包含到源文件中之后可直接调用。,从用户角度看:,如:scanf、printf、sqrt、getchar等,用户自定义函数user defined functions:先定义而后使用(调用)! 用户自定义函数过程:,definition定义,declaration声明, call调用,无参函数 int a( ) ,functions,从函数的形式看:,有参函数 int max( x , y ) ,主调函数调用 被调函数时,不 能传递参数(数 据)。一般用来执 行指定的一组 操作。,User defined function定义,(1)传统风格函数定义: 类型 函数名(形参表列) 形参说明 说明部分 语句 ,形参表列是用逗号分隔 的形参parameter,形参又称为形式参数、哑元、虚参、虚拟参数。在形参说明中,说明形参表中每个形参的类型。,函数类型:用来说明函数返回值的类型。当函数返回值是整型或不要求返回值时,可省略类型说明。无返回值可用“空类型” void,函数定义时的参数称为行参parameter;函数调用时的参数称为实参argument。,(2)函数的现代定义方式,类型 函数名 (形参说明表列) 说明部分 语句 ,函数体,将形参说明包含到形参列表中,即在 列出形参的同时,说明形参类型。 形参列表: 类型 参数1,类型 参数2, ,类型 参数n,传统定义举例 现代定义举例 int add(x, y) int add(int x, int y) int x, y; ,程序举例1,编写一个求模函数。,int mod(int m,int n) int x; x=m%n; return x; ,当函数不需要参数时,省略形参表列和形参说明,但不能省略括号,函数名后的括号内为空,即为无参函数。 Void print_info( ) printf(“-n“); printf(“Welcome to HIT.n“); printf(“-n“); ,函数定义说明,当函数为有参函数时,应对其全部参数进行数据类型说明。,函数使用标识符给函数命名,即取名原则与变量名相同。 Int max(float x, float y) float z; z=xy?x: y; return(z); ,函数名前面的类型即为函数的类型。 函数的类型实际上是函数返回值的类型。当被调函数无返回值时,实际上就是带回的是一个不确定的值,可用“void” 定义“无类型”(或称“空类型”)。当函数的返回值为整型时,函数名前的数据类型可以省略。,形参表列中,形参与形参间用“,”分隔。 形参说明是对形式参数的数据类型的说明。,在定义函数中指定的形参,在未被调用时,他们不占用内存单元,只有在该函数被调用时,函数中的形参才被分配 内存单元。,Return value函数返回值,功能,将被调函数中的结果值返回给主调函数。,语句,return(返回值表达式);,举例,int add(int x, int y) int z; z=x+y; return(z); ,Return,当函数要求返回函数值时,函数体内最后执行的语句应为返回语句return。 一个函数中可以有一条或多条return语句,只有被执行到的return语句才起作用。当函数不需要返回值时 ,后面不加括号和表达式,也可没有return。,当函数值的类型和return语句后的表达式类型不一致时,则以函数类型为准。对数值型数据可自动转换。 int max(float x, float y) float z; z=xy?x: y; return(z); ,有些系统可省略return后的括号。 return _ 表达式; 4.“函数类型就是函数中return语句后表达式的类型”是错误! 5.return语句完成了被调函数向主调函数值传递的功能。,Function definition函数定义,下面add函数的功能是求两个参数的和,并将和值返回调用函数。函数中的错误是: void add(float a, float b) float c; c=a+b; return c; ,void add(float a, float b),float add(float a, float b),calling of a function,格式,函数名(实参argument表列),与调用标准函数相同,说明,1.无参函数实参形参均为空;有参函数调用时,实参列表中各参数以逗号分隔,且实参与形参应在个数、类型、位置一一对应。即要按形参定义为准。,2.实参可以是常量、变量或表达式,调 用函数前必须保证每个实参都有确定值。 且调用时发生了实参向虚参进行参数传 递的过程。,3. 调用时,主调函数与被掉函数发生了程序 执行权的转移,被调函数只有在被调用时, 才被调入内存,获得程序执行权;函数退出时, 将返回值返回给主调函数,被掉所占存储空间 被释放,程序执行权返还给主调函数,主调函 数继续在断点处执行 。,4. 形参变量和实参变量占据不同的存储 单元,有不同的作用域。,5.实参argument和形参parameter 的数据传递是单向的(即只有实参传递给形参,而不能由形参传回数据给实参)。,Example (3),辗转相除法求最大公约数。,#include main() int m,n,r; scanf(“%d,%d“, ,int mod(int m,int n) int x; x=m%n; return x; ,函数调用方式,调用方式,函数调用语句,函数表达式,函数参数,print_star(n);,void print_star(int n) int i; for(i=1; i=n; i+) printf(“*“); ,x=max(a, b)+5;,x=max(max(a, b), c);,程序举例(4),分析一下程序,写出运行结果。,#include main( ) int a=5, b=10; printf(“a=%d, b=%dn“, a, b); fun(a, b); /*函数调用*/ printf(“a=%d, b=%dn“, a, b); int fun(int x, int y)/*现代风格函数定义*/ x=3; y=3; return; ,a=5 , b=10 a=5 , b=10,参数传递,主调函数向被调函数传值的方式:,赋值调用 把实参的值赋给形参。 赋地址调用 把实参的地址付给形参。在被调函数 中,用该地址访问主调函数中的实参。,实参,形参,调用,返回,单向值传递,Argument passing by value简单变量作函数参数,传递方式,属于赋值调用,将实参值传给虚参。,虚参要求,必须是简单变量。,实参要求,可为一般变量、常量、数组元素或者 表达式。,哑实结合,哑元和实元按顺序一一结合。由于是 赋值调用,修改哑元,对实元无影响,Pi function example,下面函数pi的功能是:根据以下公式, 返回满足精度(0.0005)要求的的值,请 填空。,程序举例52,#include /*Direct MSDOS console input/output*/ #include #include double pi(double eps ) /*子函数的定义*/ double s, t; int n; for( ; teps; n+) s+=t; t=n*t/(2*n+1); return ( ); /*函数的返回值*/ main( ) /*主函数*/ double x,p; printf(“nPlease enter a precision: “); scanf(“ %lf “, ,s=0.,t=1.0,n=1,2.0*s,实参,形参,调用,return,p=pi(x),函数原型的说明,在一个函数中调 用另一个函数时, 应具备什么条件?,被调用的函数必须是已经存在的函数 (是库函数或用户自己定义的函数)。,如果使用库函数,一般还应该在本文 件开头用 #include 命令将调用有关库函 数所需要用到的信息“包含”到本文件中 来。 #include 标准输入输出函数 #include 标准数学计算函数 ,如果使用用户自己定义的函数,而且 该函数与调用它的函数 (即主调函数) 在 一个文件中时,应在主调函数的说明部 分或主调函数之前对被调函数作声明。 函数声明的一般形式: 类型 函数名(类型1,类型2,) ; 类型 函数名(类型1 参数名1,);,函数声明的一般形式: 类型 函数名(类型1,类型2,) ; 类型 函数名(类型1 参数名1,); 举例: float add(float a, float b); float add(float, float);,不同版本的编译器,函数声明方式略 有不同。,有些系统在函数调用前,不对函数作 声明时,编译系统会把第一次遇到的该 函数形式(函数定义和函数调用)作为函 数声明,并将函数类型默认为int型。 因而,如果函数类型为int整形,可以在 函数调用前不必作函数声明。,如果被调用函数的定义出现在主调函 数之前,可以不必加以说明。 float add(float a, float b) return (ab?a: b); main( ) float a, b; scanf(“%f, %f“, ,如果在所有函数定义之前,在函数 的外部已作了函数声明,则在各个主调 函数中不必对所调用的函数再作声明。 float add(float a, float b); main( ) ,函数的“声明”和“定义”的差别: 定义:指函数功能的确立,包括指定函 数名、函数类型、形参及类型、函数 体等,是一个完整、独立的函数单位。 声明:是对已定义函数的返回值和形参 进行类型说明。它不包括形参本身和函 数体。,prototype,宏定义,不带参数的宏定义: 即第二章的符号常量,带参数的宏定义:,带参数的宏定义,功能,将一个带参数的标识符定义成一个字符串。,格式,#define 宏名(参数表) 字符串,字符串中可包含参数表中的参数。,举例,#define s(a, b) a*b area=s(3, 2);,处理,在编译时,用字符串替代带参数的宏名, 其中出现的参数由相应的实际参数替代。,带参数宏定义的说明,书写字符串时,应注意括号的使用。,如想计算(3+5)*(4+7),不能写成 #define s(a, b) a*b s(3+5, 4+7) 3+5*4+7=30 而应是 #define s(a, b) (a)*(b),不能写成 #define s(a, b) (a)*(b) 否则,在计算24/(3*4)时,使用 24/s(3,4)会出错, 24/(3)*(4) 32 而应是 #define s(a, b) (a*b),为了适应各种情况,将 #define s(a, b) a*b 改写成 #define s(a, b) (a)*(b),带参数宏和函数的区别,带参数宏与函数在使用上,同函数相同, 与其它语言的语句函数相似。,函数调用时,先求出实参表达式的值,然 后带入函数定义中函数的形参;而用带参宏 只是进行简单的字符替换,不进行计算。,函数调用是在程序运行时处理的,分配临 时的内存单元;而宏扩展则是在编译之前进 行的,在展开时并不分配内存单元,也不进 行值的传递处理,也没有“返回值”的概念 。,对函数中的实参和形参都要定义类型,且 二者的类型要求一致,如不一致应进行类型 转换;而宏不存在类型问题,宏名无类型, 它的参数也无类型,只是一个符号代表。,函数只可得到一个返回值,而用宏可以设 法得到几个结果。例如: #define PI 3.14159 #define CIRCLE(R,L,S) L=2*PI*R;S=PI*R*R CIRCLE(5,L,S);,多次使用宏时,宏展开后源程序变长,而 函数调用不使源程序变长。,宏替换不占运行时间,只占编译处理时 间,而函数调用则占运行时间。,Scope and storage class变量的作用域和存储类,varable scope 变量的作用域 variable storage class 变量的存储类,定义:存储类 类型 变量名; 描述变量的另外两个属性作用域与存储类 当了解了函数调用时发生程序执行权的转移,就很容易理解。,变量的使用过程:定义、声明、使用;,31,Scope of Variables,Scope The part of the program where the variable can be referenced. The scope of a variable starts from its declaration and continues to the end of the block that contains the variable. 从变量的定义或者生命开始,到程序块结束block:函数,复合语句等。,scope变量的作用域,程序中定义变量的位置及其能被读写访问的范围,它是从空间角度来描述变量。,Local 局部变量 Global 全局变量,定义,变量的作用域的分类,局部变量 local,定义,所谓local, global,相对于一个 function 而言。在一个函数(包括主函数main)内部定义的变量是local ,它只在本函数内有效,在此函数以外是不能使用这些变量。 The scope of a variable starts from its declaration and continues to the end of the block that contains the variable.,局部变量说明,不同函数中可以使用相同名字的变量,它 们代表不同的对象,互不干扰。 Float fun(int a) /*函数fun*/ int b, c; main( ) /*主函数main*/ int b, c; ,形式参数也是局部变量。 Float fun(int a) /*函数fun*/ int b, c; 形参a的作用域只在fun中 main( ) /*主函数main*/ int b, c; ,global全局变量,定义,在所有函数之外定义的变量称为全局变量,外部变量即全局变量。全局变量可以为本文件中所有其他函数所共有。它的有效范围为从定义变量的位置开始到本源文件结束。,实际上,local与global管理方式分别属于动态管理和静态管理。它们在内存的存储区不同。动态管理,复合自然规律(jobs讲稿)。,C程序的内存映像,C程序中变量的内存分配方式 从静态存储区分配 全局变量和静态变量 在栈上创建 存放函数参数值、局部变量值等 在执行函数调用时,系统在栈上为函数内的局部变量及形参分配内存,函数执行结束时,自动释放这些内存 从堆上分配 在程序运行期间,用动态内存分配函数来申请的内存都是从堆上分配的,动态内存的生存期由程序员自己来决定,37,Global Variables,Declared outside all functions and are accessible to all functions in its scope. Local variables do not have default values, but global variables are defaulted to zero.,Global variable,int p=1, q=5; float f1(int a) int b, c; char c1, c2; char f2(int x, int y) int i, j; main( ) int m, n; ,/*外部变量*/,/*定义函数f1*/,/*外部变量*/,/*定义函数f2*/,/*主函数*/,c1, c2 作 用 范 围,p, q 作 用 范 围,如果一个C程序只有一个源文件, 则外部变量的作用域为从定义变量的 位置开始到本源文件结束。,若要在定义点之前的函数内引用它 时,则应在该函数中用extern对该变 量作外部变量说明。,extern 类型 变量名; (与函数声明类似),外部变量说明可进行多次不分配内 存单元;但定义只能有一次,定义时 分配存储单元。,若一个程序由多个源文件组成,跨 文件引用外部变量也要做外部变量说 明。,在同一源文件中,外部变量与局部 变量同名,则在局部变量的作用范 围内外部变量不起作用。,全局变量增加了函数间数据联系的 渠道。在函数间可完成数据的传递。,慎用全局变量,全局变量在程序的全部执行过程中始 终占用存储单元,而不是仅在需要时才 开辟存储单元。即不利于节约内存资源。,函数在执行时要依赖于其所在的外部 变量,因而它使函数的通用性降低。 当移植该函数时,必须连同外部变量 及其值一起移过去。但移过去又有可能 与其他变量名同名。即降低了通用性或 可移植性(portability)。,使用全局变量太多,会降低程序的可 读性。 在程序执行时,人们很难清晰地判断 每一时刻各外部变量的值。因为每个函 数都可改变全局变量的值。即增加了调 试的困难。,程序举例20,给出下列程序的运行结果。,#include main( ) extern int a, b; printf(“Max=%dn“, max(a, b); int a=13, b=8; max(int x, int y) int z; z=xy?x: y; return(z); ,Max=13,int a=13, b=8; /全局变量 main( ) int a=5; /局部变量 printf(“Max=%dn“, max(a, b); max(int a, int b) int c; c=ab?a: b; return(c); ,Max=8,程序举例21,#include int k=1; main( ) int i=4; fun(i); printf(“(1) %d,%dn“, i, k); fun(int m) m+=k; k+=m; char k=B; printf(“(2) %dn“, k-A); printf(“(3) %d,%dn“, m, k); ,程序的运行结果是:,(2) 1 (3) 5, 6 (1) 4, 6,/*全局变量k=1*/,/*局部变量*/,/*形参m=4*/,/*m=m+k(5),k=k+m(6)全局变量k*/,/*复合语句的局部变量k*/,/*实参i=4*/,程序举例22,int i=0; main( ) int i=5; reset(i/2); printf(“i=%dn“, i); reset(i=i/2); printf(“i=%dn“, i); reset(i/2); printf(“i=%dn“, i); workover(i/2); printf(“i=%dn“, i); workover(int i) i=(i%i)*(i*i)/(2*i)+4); printf(“i=%dn“, i); return(i); reset(int i) i=i=2?5: 0; return(i); ,运行结果是:,i=5 i=2 i=2 i=0 i=2,Storage class,变量的存储类是从变量的存在时间或数据在内存中的存储方式,即变量的存储类别。,描述,存储方式,具体类型,auto自动变量 extern外部变量 static静态变量 register寄存器变量,定义:存储类 类型 变量名;,定义、声明、使用;,自动变量auto,在函数中,没有用static说明的形参和变量都属此类型,属于系统默认类别。,描述,在调用函数时系统会给该类型变量自动分配存储空间,在函数调用结束时就自动释放这些空间。这类局部变量称为自动变量。,定义,auto 类型 变量序列,变量声明,声明时,auto可省略,省略时,默认auto型。,自动变量是局部变量,作用域同于局部变量。,自动变量是动态存储类型的变量。,可在定义时初始化,若未进行初始 化,也没赋值,其值将是不确定的。,自动变量举例,int f(int a) auto int b,c=3; ,举例,/*定义函数f,a为形参*/,/*定义b, c为自动变量*/,auto int b,c=3; int b,c=3;,自动类型是默认类型,等价,寄存器变量register,该类型变量的存储空间不是内存,而 是cpu中的寄存器,因而称为寄存器变量。,定义,为了提高访问速度,将经常使用的变量定义在 cpu中的寄存器,提高系统效率。,原因,register 类型名 变量名;,定义格式,寄存器变量说明,只有局部自动变量和形参可以作为寄 存器变量,其他 ( 如全局变量、局部静 态变量)不行。并且寄存器变量一般只 限于整形、字符型和指向整形、字符型 的指针。 register static int a, b, c; register float x, y;,一个计算机系统中的寄存器数目是有 限的,不能定义任意多个寄存器变量。 不同的系统允许使用的寄存器不同。 例如: Turbo C只把源变址寄存器SI和 目的变址寄存器DI用于寄存器变量, 多余的按自动变量处理。,3.由于寄存器不参加内存编址,因而对 寄存器变量不能使用&运算符。 4.寄存器变量特别适用于要求快速和频 繁使用的场合,例如:循环控制变量、 数组的下标、动态数据结构中用于查询 的指针等。,寄存器变量举例,int fac (int n) register int i, f=1; for(i=1; i=n; i+) f=f*i; return(f); main( ) int i; for(i=1; i=5; i+) printf(“%d!=%dn“, i, fac(i); ,循环的次数越多, 越节省访问时间。,外部变量,在所有函数之外定义而没有指定其存 储类别的变量称为外部变量,即全局变 量。其作用域符合全局变量的规定,连 接在一起的各目标文件的源程序文件中 的所有函数均可以访问外部变量。,外部变量是静态存储类型的变量,在 程序运行期间分配固定的存储空间,因 此其生存期是整个程序的运行期,就是 说它的值不随函数的退出调用而消失。,外部变量可在定义时作初始化;没有 显式初始化的外部变量,由编译程序自 动初始化为零值。,外部变量的声明,*在一个文件内声明外部变量 *在多个文件中声明外部变量,在一个文件内声明外部变量,如果外部变量不在文件的开头定义, 其有效的作用域只限于定义处到文件终结 处。如果在定义点之前的函数想引用该外 部变量,则应该在引用前用关键字extern 对该变量作“外部变量声明”。表明该变量 是一个已经定义的外部变量。,int max(int x, int y) int z; z=xy? x: y; return(z); main( ) extern A, B; printf(“%dn“, max(A, B); int A=13, B=-8;,变量定义、变量声明、变量引用,/*外部变量定义*/,/*外部变量声明*/,/*外部变量的引用*/,在多个文件内声明外部变量,如果一个C程序是由一个或多个源程 序文件组成,如果在两个程序中都用到同 一个外部变量num时,不能分别在两个文 件中各自定义一个外部变量num,否则编 译出错。正确的作用:在任意一个文件中 定义外部变量num,而在另一个文件中用 extern对num作“外部变量声明”。,/*project工程文件包含func4.c和fun4.h两个文件*/ main() extern num; /*变量声明*/ int i; num=800; i=j;/*变量引用*/ printf(“%d“,num); getch(); ,/*func4.h*/ int num;/*变量定义*/,#include main() int i; num=800; i=j;/*变量引用*/ printf(“%d“,num); getch(); ,静态变量,静态变量是静态存储类型的变量,即在程序运行期间分配固定的存储单元,它永久存在,不随函数的退出调用而释放。,定义,静态局部变量,分类,static 类型 变量名;,语句格式,55,Static Local Variables,Static local variables are permanently allocated in the memory for the lifetime of the program. static int x; After a function completes its execution, all its local variables are destroyed. While, the static local variables are retained and can be reused in the next call. 静态局部变量,其值不随函数退出而释放,继续保存。因此,下次调用的初值是上次调用的终值。,在函数内部定义的静态变量是静态局 部变量。,定义,说明,对局部变量用static声明,则为该 变量分配的存储空间在整个程序执行 期间始终存在。,静态局部变量是在某函数中的局部 变量,其他函数无权访问。当退出对 该函数调用时,其值保留,下次调用的初值是上次调用退出的终值。,静态局部变量可在定义时初始化, 未显式初始化的静态局部变量在编译 时自动初始化为零值。,静态局部变量可使变量由动态存储 方式改变成静态存储方式。它作用域 不变,局限于本函数。,Static Local Variables,Example 23,给出以下程序的运行结果。,main( ) increment( ); increment( ); increment( ); increment( ) int x=0; x+=1; printf(“%dn“, x); ,1 1 1,main( ) increment( ); increment( ); increment( ); increment( ) static int x=0; x+=1; printf(“%dn“, x); ,1 2 3,main( ) int x=1; increment( ); printf(“%dn”,x); increment( ); printf(“%dn”,x); increment( ); printf(“%dn”,x); ,increment( ) static int x=0; x+=1; printf(“%dn“, x); ,1 1 2 1 3 1,程序举例24,给出以下程序的运行结果。,int n=1; func(); main( ) static int x=5; int y; y=n; printf(“MAIN: x=%2d y=%2d n=%2dn“, x, y, n); func( ); printf(“MAIN: x=%2d y=%2d n=%2dn“, x, y, n); func( ); func( ) static int x=4; int y=10; x=x+2; n=n+10; y=y+n; printf(“FUNC: x=%2d y=%2d n=%2dn“, x, y, n); ,MAIN: x= 5 y= 1 n= 1 FUNC: x= 6 y=21 n=11 MAIN: x= 5 y= 1 n=11 FUNC: x= 8 y=31 n=21,/*x 静态局部变量*/,/*函数声明*/,/*函数定义*/,/*函数调用*/,/*全局变量 n */,/* x 静态局部变量,初值=5;y局部变量*/,/*y=1 5 1 1 */,本章目录,函数 宏定义 变量的作用域和存储类 模块化程序设计方法 4.1.模块化程序设计方法的指导思想 4.2.模块分解的原则 应用设计实例 多文件方式组织的程序,模块化程序设计方法的指导思想,什么是模块化程序设计方法,在编写较大规模的程序,为了提高编写工作 的效率,可把程序总体上划分成几个功能相对 独立的程序模块,分别由不同的编程人员进行 编写。各模块之间用接口联系。这样,只要接 口关系不变,每个模块内部的具体实现细节可 以由各自的编程人员随意修改。这就是模块化 程序设计方法的指导思想。,无论多么复杂的任务,都可以划分为若干个 子任务。把每个子任务设计成一个子函数,若 子任务较复杂,还可以将子任务继续分解,直 到分解成为一些容易解决的子任务为止。每个 子任务对应一个子函数,完成总任务的程序由 一个主函数和若干子函数组成,主函数起着任 务调度的总控作用。,模块分解的原则,分解原则,1.使模块脱离其使用环境,应该保证 是正确的。,2.每个模块只完成一个相对独立的特 定功能,模块之间仅仅交换那些为完 成系统功能必须交换的信息,即模块 具有独立性。,3.模块应该设计得使其所含信息(过 程和数据)对于那些不需要这些信息 的模块不可访问,即信息隐藏性。,结构图,主模块,A,B,C,E,F,逐步求精与模块化设计的联系,1.在规模比较大的程序进行逐步求精时,为了提高 清晰度,常常采用分段结构的形式。在C语言中采用 函数表示一些功能比较独立的部分,而在PASCAL语 言中用过程(procedure)表示,从而使大的程序分 解为若干功能独立的小的程序段,这种形式蕴含着 模块化设计思想。 2.而对于每个模块来说,又可以采用逐步求精方法 进行设计。,逐步求精与模块化设计的区别,1.就程序规模来说,逐步求精主要是指一个程序的 设计过程,而模块化设计主要指一个比较大的系统 的设计过程。 2.就程序设计的两种方法(分解与抽象)来说,逐 步求精方法侧重于分解,而模块设计侧重于抽象。 模块化方法的外表是将系统化分成若干子系统,而 实质是要实现不同层次的数据或过程的抽象。,应用设计实例,请大家关注cms网站: 1、本周补实验,:同学们时间? 答疑时间:? 2、请同学们申报ACM竞赛情况; 3、补充练习题:三大结构,函数,数组。 打印杨辉三角形 求素数之和,程序举例1杨辉三角形,1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 ,问题分析1,主函数main(): 调用输入三角形输出行数n的函数input(); for i=0 to n 调用print_space(k)输出k个空格 调用输出杨辉三角形的第i行函数print(); ,输入函数input() 输入三角形输出行数n,问题分析2,输出三角形第i行函数print() for j=0 to i 调用print_j(i,j)输出第i行第j个元素; 输出回车换行,输出k个空格print_space(k) for l=1 to k printf(“ “);,问题分析3,输出第j个元素print_j() 输出 i!/(j!*(i-j)!),求m!函数func(m) fun=1 for l=1 to m fun=fun*l;,C程序1,#include void print_space(int); void print_j(int, int); int input( ); main() int i, j, n; n=input( ); for(i=0; in; i+) print_space(36-i*3); for(j=0; j=i; j+) print_j(i, j); printf(n ); ,C程序2,int input( ) int n; printf(请输入输出的行数:); scanf(%d , ,C程序3,long func(int n) int i; long m; for(m=i=1; i=n; i+) m*=i; return(m); void print_j(int n, int m) long cij; cij=func(n)/(func(m)*func(n-m); printf(%6ld , cij); ,程序举例2求素数之和,求1n之间所有素数之和。,问题分析1,输入n的值(输入函数input( ); 1到n间的所有素数求和; 输出求和的值。,细化2: i从1变化到n; 判断i 是否为素数; 若i为素数则进行累加求和。,问题分析2,C程序1,#include long sumofprime( ); int isprime( ); int input( ); void output( ); main( ) int n; long m; printf(“input n:“); n=input( ); m=sumofprime(n); output(m); ,C程序2,input( ) /* 输入模块 */ int n; scanf(“%d“, ,C程序3,int isprime(int m) /* 判断素数模块 */ int i; if(m=1) return 0; for (i=2; i=sqrt(m);i+) if (m%i=0) return 0; return 1; void output( long int n) printf(“sum=%ldn“,n); ,本章目录,函数 *宏定义 变量的作用域和存储类 *模块化程序设计方法 *应用设计实例 多文件方式组织的程序 1.文件包含 2. Turbo C集成开发环境下的项目文件,文件包含,指一个源文件可以将另一个源文件的全部 内容包含进来,即将另外的文件包含到本 文件中。,功能,格式,#include 或 #include “文件名“,功能,用双引号的,系统先在引用被包含文件的源文件所 在的文件目录中寻找要包含的文件,若找不到,再 按系统指定的标准方式检索其他目录。,用尖括号时不检查引用被包含文件的源文件所在的 文件目录,直接按系统指定的标准方式检索文件目 录。,include示意过程,1,文件包含的注明,1.在被包含文件修改后,凡包含此文件的所 有文件都要重新编译。 2.一个include命令只能指定一个被包含文件, 如果包含n个文件,要用n个include命令。 3.在一个被包含文件中还可以包含另一个被包 含文件,即文件包含是可以嵌套的。,Turbo C集成开发环境下的项目文件,定义,在Turbo C集成开发环境中,把多文件组成 的程序叫做project (项目),一个项目就 是一个扩展名为.prj 的文件。,说明,把项目文件进行编译,连接,运行会产生与 项目文件同名的.exe文件(可执行文件)。,建立项目程序的步骤,在Turbo C集成开发环境中,分别设计好组成项目 程序的各文件a.c,b.c,c.c。 设计一个叫myproject的项目文件。用文本编辑口把 所有的文件列出,一行一个文件名,该程序由三个文件 a.c,b.c和c.c组成。保存这个文件为myproject.prj。 在集成开发环境下,选择Project

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论