




已阅读5页,还剩72页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1,Chapter 7 - Functions,Outline 7.1 Introduction 7.2 Program Modules in C 7.3 Math Library Functions 7.4 Functions 7.5 Function Definitions 7.6 Function Prototypes 7.7 Header Files 7.8 Calling Functions: Call by Value and Call by Reference 7.9 Random Number Generation 7.10 Example: A Game of Chance 7.11 Storage Classes 7.12 Scope Rules 7.13 Recursion 7.14 Example Using Recursion: The Fibonacci Series 7.15 Recursion vs. Iteration,2,7.1 Introduction,Divide and Conquer 分而治之 Construct a program from smaller pieces or components Each piece more manageable than the original program 函数是一段完成特定任务的程序。,3,模块化程序设计,基本思想:将一个大的程序按功能分割成一些小模块 特点: 各模块相对独立、功能单一、结构清晰、接口简单 控制了程序设计的复杂性 提高元件的可靠性 缩短开发周期 避免程序开发的重复劳动 易于维护和功能扩充 开发方法: 自上向下,逐步分解,分而治之,4,C程序结构,C是函数式语言 必须有且只能有一个名为main的主函数 C程序的执行总是从main函数开始,在main中结束 函数不能嵌套定义,可以嵌套调用,C是模块化程序设计语言,5,7.2 Program Modules in C,Functions Modules in C Programs written by combining user-defined functions with library functions C standard library has a wide variety of functions Makes programmers job easier - avoid reinventing the wheel,6,7.2 Program Modules in C (II),Function calls函数调用 Invoking functions调用函数 Provide function name and arguments (data) Function performs operations or manipulations Function returns results Boss asks worker to complete task Worker gets information, does task, returns result Information hiding: boss does not know details,7,7.3 Math Library Functions,Math library functions perform common mathematical calculations #include Format for calling functions FunctionName (argument); If multiple arguments, use comma-separated list printf( “%.2f“, sqrt( 900.0 ) ); Calls function sqrt, which returns the square root of its argument All math functions return data type double Arguments may be constants, variables, or expressions,8,7.4 Functions,Functions Modularize a program All variables declared inside functions are local variables(局部变量) Known only in function defined Parameters Communicate information between functions Local variables Benefits Divide and conquer Manageable program development Software reusability Use existing functions as building blocks for new programs Abstraction - hide internal details (library functions) Avoids code repetition,9,7.5 Function Definitions,Function definition format return-value-type function-name( parameter-list ) declarations and statements Function-name: any valid identifier Return-value-type: data type of the result (default int) void - function returns nothing Parameter-list: comma separated list, declares parameters (default int),10,7.5 Function Definitions (II),Function definition format (continued) return-value-type function-name( parameter-list ) declarations and statements Declarations and statements: function body (block) Variables can be declared inside blocks (can be nested) Function can not be defined inside another function Returning control If nothing returned return; or, until reaches right brace If something returned return expression;,11,1. 无参函数的定义形式 类型标识符 函数名( ) 说明部分 语句 例如: printstar( ) printf(“*n”); ,无参数传递,有参数传递,2. 有参函数的定义形式 类型标识符 函数名(形式参数表列) 形式参数说明 说明部分 语句 ,12,例 int max (int x,int y) int z; z=xy?x : y; return z; ,/*求x和y二者中大者,x,y为形参*/,/*形参说明必须在函数体外*/,/*函数体中变量的说明*/,/*将z的值作为函数返回值,该值的类型应该和类型标识符确定的函数的类型一致。*/,3 . 空函数的定义形式 类型标识符 函数名( ) 例如:dummy( ) 特点:调用后什么也不做。 用处:建立程序结构,在需要时补充功能。,13,7.5 函数参数,1.形式参数和实际参数 形式参数:在定义函数时函数名后面括弧中的变量名,简称形参。 实际参数:在调用函数时函数名后面括弧中的表达式,简称实参。,例 main( ) int a,b,c; scanf (“%d,%d”, ,int max(int x,int y) int z; z=xy? x:y; return(z); ,14,上例中形参与实参、函数名与返回值之间的关系:,c=max(a, b); - 实参:在运行时 把函数的 max(int x,int y) 把值传给函数. 结果赋给 函数名 returu (z); 形参:通知系统 要预留内存位置.,15,形参调用前不占内存单元,调用时占用,调用后释放。 形参是函数的内部变量,只在函数内部才有意义。 对每个形参必须指明其名字和数据类型。 实参必须有确定的值,可以是常量,变量或表达式。 实参与形参的类型个数应一致。 实参对形参的数据传递是值传递,即单向传递,只由实参传递给形参,反之不可。调用结束后,只有形参单元被释放,实参单元中的值不变。,2. 关于参数的几点说明:,16,返回语句 形式: return(表达式); 或 return 表达式; 或 return; 功能:使程序控制从被调用函数返回到调用函数中,同时把返值带给调用函数 说明: 函数中可有多个return语句 若无return语句,遇时,自动返回调用函数 若函数类型与return语句中表达式值的类型不一致,按前者为准,自动转换-函数调用转换 void型函数,例 无返回值函数 void swap(int x,int y ) int temp; temp=x; x=y; y=temp; ,函数的返回值,17,函数定义时应该指定函数的类型(即函数值的类型),应该与return语句的类型一致。,说明:,凡不加类型说明的函数,一律自动按整型处理。,如果函数类型和return语句的类型不一致,以函 数类型为准。对数值型数据,可以自动进行类型 转换。即函数类型决定返回值的类型。,如果函数不返回值,可以将函数定义为“无类 型”void (或称“空类型”)。,例如: void print_star(),函数值的类型,1. Function prototype (3 parameters) 2. Input values 2.1 Call function Function definition Program Output,Enter three integers: 22 85 17 Maximum is: 85,19,7.6 Function Prototypes,Function prototype 函数原型 Function name Parameters - what the function takes in Return type - data type function returns (default int) Used to validate functions Prototype only needed if function definition comes after use in program int maximum( int, int, int ); Takes in 3 ints Returns an int Promotion rules(提升规则) and conversions Converting to lower types can lead to errors,20,7.3 对被调用函数的说明 (声明), 对被调用函数说明的前提条件,被调用函数必须是已存在的函数,如用户自定义函数或库函数。,2. 被调用函数是用户自定义函数的函数说明,同变量一样,函数的调用也应该遵循“先说明,后使用”的原则。,如果使用用户自定义函数,而且主调函数和被调用函数在同一个文件中,应该在主调函数中说明被调函数的类型。其说明格式的一般形式如下:,21,一般形式: 类型标识符 函数名(类型1,类型2,); 类型标识符 函数名(类型1 形参1,类型2 形参2,); 功能:通知编译程序函数值是什么类型,有多少参数及它们各自的类型,为编译程序进行类型检查提供依据。,main() float add(float x,float y); float a, b, c; scanf(“ %f, %f”, ,/*定义add函数*/ float add (float x,float y) float z; z=x+y; return (z); ,对被调用函数的说明,作为表达式被调用,22,3. 函数说明和函数定义的区别,函数说明的作用是把函数的名字、函数类型以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时系统按此进行对照检查。,函数定义是指对函数功能的确立,包括指定函数名、函数值类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。,23,7.7 Header Files,Header files contain function prototypes for library functions , , etc Load with #include #include Custom header files Create file with functions Save as filename.h Load in other files with #include “filename.h“ Reuse functions,24,函数概述,在C语言中,子程序被称为函数 一个C程序一般由多个函数组成,其中必须有一个且仅有一个名为main主函数。 C程序总是从main函数开始执行 main函数可以调用其它函数,反之不行。 有两类函数:标准库函数;用户自定义函数。 long square(long x) long x_square; x_square=x*x; return x_square; ,举例说明函数声明,调用,函数定义,说明部分,执行部分,函数名字必须唯一。函数是独立的封闭的。互相不干扰。,25,例:输入三个整数,计算它们的和并输出运算结果。 main( ) int a, b, c, sum ; scanf(“%d,%d,%d“, ,int add(int x, int y, int z) int s; s=x+y+z; return s; ,26,调用形式 函数名(实参表); 说明: 实参与形参个数相等,类型一致,按顺序一一对应 实参表求值顺序,因系统而定(Turbo C 自右向左),函数的调用,27,函数语句: 例 printstar(); printf(“Hello,World!n”); 函数表达式: 例 m=max(a,b)*2; 函数参数: 例 printf(“%d”,max(a,b); m=max(a,max(b,c);,函数的调用方式,28,例:用函数计算浮点数x的n次方,其中n为int型, n=0,double power(double x, int n) double p; int i; for(p=i=1;i=n;i+) p=p*x; return p; ,29,例:计算函数的值. f(x)=,int f( int x) int y; if(x0) y=x-1; else if(x=0) y=1; else y=x+1; return y; ,main() int x; scanf(“%d”, ,30,7.8 Calling Functions: Call by Value and Call by Reference,Used when invoking functions Call by value Copy of argument passed to function Changes in function do not effect original Use when function does not need to modify argument Avoids accidental changes Call by reference Passes original argument Changes in function effect original Only used with trusted functions For now, we focus on call by value,31,值传递方式 方式:函数调用时,为形参分配单元,并将实参的值复制到形参中;调用结束,形参单元被释放,实参单元仍保留并维持原值 特点: 形参与实参占用不同的内存单元 单向传递,参数传递方式,32,/*swap.c*/ #include main() int x=7,y=11; printf(“x=%d,ty=%dn“,x,y); printf(“swapped:n“); swap(x,y); printf(“x=%d,ty=%dn“,x,y); swap(int a,int b) int temp; temp=a; a=b; b=temp; ,例 交换两个数,33,方式:函数调用时,将数据的存储地址作为参数传递给形参 特点: 形参与实参占用同样的存储单元 “双向”传递 实参和形参必须是地址常量或变量,函数的地址传递,34,/*swap.c*/ swap(p1,p2) int *p1,*p2; int p; p=*p1; *p1=*p2; *p2=p; main() int a,b; scanf(“%d,%d“, ,例子图解,例 交换两个数,35,例子解析,36,7.9 Random Number Generation,rand function Load Returns “random“ number between 0 and RAND_MAX (at least 32767) i = rand(); Pseudorandom Preset sequence of “random“ numbers Same sequence for every function call Scaling To get a random number between 1 and n 1 + ( rand() % n ) rand % n returns a number between 0 and n-1 Add 1 to make random number between 1 and n 1 + ( rand() % 6) / number between 1 and 6,37,7.9 Random Number Generation (II),srand function Takes an integer seed - jumps to location in “random“ sequence srand( seed ); srand( time( NULL ) ); /load time( NULL )- time program was compiled in seconds “randomizes“ the seed,1. Initialize seed 2. Input value for seed 2.1 Use srand to change random sequence 2.2 Define Loop 3. Generate and output random numbers,Program Output,Enter seed: 867 2 4 6 1 6 1 1 3 6 2,Enter seed: 67 6 1 4 6 2 1 6 1 6 4,Enter seed: 67 6 1 4 6 2 1 6 1 6 4,40,7.10 Example: A Game of Chance,Craps simulator Rules Roll two dice 7 or 11 on first throw, player wins 2, 3, or 12 on first throw, player loses 4, 5, 6, 8, 9, 10 - value becomes players “point“ Player must roll his point before rolling 7 to win,1. rollDice prototype 1.1 Initialize variables 1.2 Seed srand 2. Define switch statement for win/loss/continue 2.1 Loop,2.2 Print win/loss Program Output,Player rolled 6 + 5 = 11 Player wins,Program Output,Player rolled 6 + 6 = 12 Player loses,Player rolled 4 + 6 = 10 Point is 10 Player rolled 2 + 4 = 6 Player rolled 6 + 5 = 11 Player rolled 3 + 3 = 6 Player rolled 6 + 4 = 10 Player wins,Player rolled 1 + 3 = 4 Point is 4 Player rolled 1 + 4 = 5 Player rolled 5 + 4 = 9 Player rolled 4 + 6 = 10 Player rolled 6 + 3 = 9 Player rolled 1 + 2 = 3 Player rolled 5 + 2 = 7 Player loses,44,嵌套调用 C规定:函数定义不可嵌套,但可以嵌套调用函数,函数的嵌套与递归调用,45,#include int dif(int x,int y,int z); int max(int x,int y,int z); int min(int x,int y,int z); void main() int a,b,c,d; scanf(“%d%d%d“, ,int dif(int x,int y,int z) return max(x,y,z)-min(x,y,z); int max(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); int min(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); ,例 求三个数中最大数和最小数的差值,46,定义:函数直接或间接的调用自身叫函数的递归调用,int f(int x) int y,z; z=f(y); . return(2*z); ,递归调用,47,Recursion递归,Recursive functions Function that calls itself Can only solve a base case Divides up problem into What it can do What it cannot do - resembles original problem Launches a new copy of itself (recursion step) Eventually base case gets solved Gets plugged in, works its way up and solves whole problem,48,Recursion (II),Example: factorial:阶乘 5! = 5 * 4 * 3 * 2 * 1 Notice that 5! = 5 * 4! 4! = 4 * 3! . Can compute factorials recursively Solve base case (1! = 0! = 1) then plug in 2! = 2 * 1! = 2 * 1 = 2; 3! = 3 * 2! = 3 * 2 = 6;,49,#include int fac(int n) int f; if(n0) printf(“n0,data error!“); else if(n=0|n=1) f=1; else f=fac(n-1)*n; return(f); main() int n, y; printf(“Input a integer number:“); scanf(“%d“, ,例 求n的阶乘,50,Example Using Recursion: The Fibonacci Series,Fibonacci series: 0, 1, 1, 2, 3, 5, 8. Each number sum of the previous two fib(n) = fib(n-1) + fib(n-2) - recursive formula long fibonacci(long n) if (n=0 | n=1) /base case return n; else return fibonacci(n-1) + fibonacci(n-2); ,51,Example Using Recursion: The Fibonacci Series (II),1. Function prototype 1.1 Initialize variables 2. Input an integer 2.1 Call function fibonacci 2.2 Output results. 3. Define fibonacci recursively Program Output,Enter an integer: 0 Fibonacci(0) = 0 Enter an integer: 1 Fibonacci(1) = 1,Program Output,Enter an integer: 2 Fibonacci(2) = 1 Enter an integer: 3 Fibonacci(3) = 2 Enter an integer: 4 Fibonacci(4) = 3 Enter an integer: 5 Fibonacci(5) = 5 Enter an integer: 6 Fibonacci(6) = 8 Enter an integer: 10 Fibonacci(10) = 55 Enter an integer: 20 Fibonacci(20) = 6765 Enter an integer: 30 Fibonacci(30) = 832040 Enter an integer: 35 Fibonacci(35) = 9227465,54,例7.7 用函数递归法以字符串形式输出一个整数,55,Recursion vs. Iteration(递归 vs. 迭代),Repetition Iteration: explicit loop Recursion: repeated function calls Termination Iteration: loop condition fails Recursion: base case recognized Both can have infinite loops Balance Choice between performance (iteration) and good software engineering (recursion),56,变量的作用域和生存期,变量的作用域指一个范围,在这个范围内程序的各个部分都可以访问该变量(可见的)。 #include int x=999; /*Global Variable*/ void print_value(void); void main() printf(“%dn“,x); print_value(); void print_value(void) printf(“%dn“,x); ,57,变量的属性 数据类型:变量所持有的数据的性质(操作属性) 存储属性: 存储器类型:寄存器、静态存储区、动态存储区 生存期:变量在某一时刻存在-静态变量与动态变量 作用域:变量在某区域内有效-局部变量与全局变量 变量的存储类型 auto - 自动型 register- 寄存器型 static - 静态型 extern - 外部型 变量定义格式: 存储类型 数据类型 变量表;,概述 变量是对程序中数据的存储空间的抽象,如: int sum; auto int a,b,c; register int i; static float x,y;,变量的存储属性,58,Storage Classes,Storage class specifiers Storage duration - how long an object exists in memory Scope - where object can be referenced in program Linkage - what files an identifier is known Automatic storage Object created and destroyed within its block auto: default for local variables auto double x, y; register: tries to put variable into high-speed registers Can only be used for automatic variables register int counter = 1;,59,局部变量-内部变量 定义:在函数内定义,只在本函数内有效 说明: main中定义的变量只在main中有效 不同函数中同名变量,占不同内存单元 形参属于局部变量 可定义在复合语句中有效的变量 局部变量可用存储类型:auto register static (默认为auto),60,局部变量函数内定义、可见,#include void print_value(void); void main() int x=999; /*Local Variable*/ printf(“%dn“,x); print_value(); void print_value(void) printf(“%dn“,x); ,61,不同函数中可以使用相同名字的局部变量,#include int a=1,b=2; max(int a, int b) int c; c=ab?a:b; return c; void main() int a=8; printf(“%d“,max(a,b); ,62,存储方式 静态存储:程序运行期间分配固定存储空间 动态存储:程序运行期间根据需要动态分配存储空间 内存用户区,生存期 静态变量:从程序开始执行到程序结束 动态变量:从包含该变量定义的函数开始执行至函数执行结束,动态变量与静态变量,63,Storage Classes (II),Static storage Variables exist for entire program execution Default value of zero static: local variables defined in functions. Keep value after function ends Only known in their own function. extern: default for global variables and functions. Known in any function,64,局部静态变量,特殊:在程序运行的整个过程中都占用内存单元,但还是只能在其所在的函数被调用时,才可以被使用。 #include void f() int a,b=3; static int c,d=5; a=3;c=5; a+;b+;c+;d+; printf(“%dt%dt%dt%dn“,a,b,c,d); main() f();f(); ,65,打印15的阶乘,#include fac(int n) static int f=1; f*=n; return f; main() int i; for(i=1;i5;i+) printf(“%d!=%dn“,i,fac(i); ,66,也称外部变量 定义:在函数外定义,可为本文件所有函数共用 有效范围:从定义变量的位置开始到本源文件结束,及有extern说明的其它源文件,应尽量少使用全局变量,因为: 全局变量在程序全部执行过程中占用存储单元 降低了函数的通用性、可靠性,可移植性 降低程序清晰性,容易出错,定义 说明 次数: 只能1次 可说明多次 位置: 所有函数之外 函数内或函数外 分配内存: 分配内存,可初始化 不分配内存,不可初始化,外部变量说明: extern 数据类型 变量表;,外部变量定义与外部变量说明不同,若外部变量与局部变量同名,则外部变量被屏蔽,外部变量可用存储类型:缺省 或 static,全局变量,67,float max,min; float average(float array, int n) int i; float sum=array0; max=min=array0; for(i=1;imax) max=arrayi; else if(arrayimin) min=arrayi; sum+=arrayi; return(sum/n); main() int i; float ave,score10; /*Input */ ave=average(score,10); printf(“max=%6.2fnmin=%6.2fn average=%6.2fn“,max,min,ave); ,例子解析,68,extern char c1,c2;,extern char c1,c2;,例子解析,69,int max(int x, int y) int z; z=xy?x:y; return(z); main() extern int a,b; printf(“max=%d“,max(a,b); int a=13,b=-8;,运行结果:max=13,extern int a,b; int max() int z; z=ab?a:b; return(z); main() printf(“max=%d“,max(); int a=13,b=-8;,例 外部变量定义与说明,70,/*ch7_17.c*/ int a=3,b=5; max(int a, int b) int c; c=ab?a:b; return(c); main() int a=8; printf(“max=%d“,max(a,b); ,运行结果:max=8,例 外部变量与局部变量,71,局部变量默认为auto型 register型变量个数受限,且不能为long, double, float型 局部static变量具有全局寿命和局部可见性 局部static变量具有可继承性 extern不是变量定义,可扩展外部变量作用域,变量存储类型,72,#include int i=1; main() static int a; register int b=-10; int c=0; printf(“-MAIN-n“); printf(“i:%d a:%d b:%d c:%dn“,i,a,b,c); c=c+8; other(); printf(“-MAIN-n“); printf(“i:%d
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论