第6章-函数和模块设计课件

上传人:仙*** 文档编号:241646492 上传时间:2024-07-12 格式:PPT 页数:99 大小:811.50KB
返回 下载 相关 举报
第6章-函数和模块设计课件_第1页
第1页 / 共99页
第6章-函数和模块设计课件_第2页
第2页 / 共99页
第6章-函数和模块设计课件_第3页
第3页 / 共99页
点击查看更多>>
资源描述
第第 6 章章 函函 数数 和和 模模 块块 设设 计计 7/12/20241程序设计基础(C语言)wh第第 6 6 章章 函数和模块设计函数和模块设计 6.1 6.1 结构化程序设计结构化程序设计结构化程序设计结构化程序设计 6.2 6.2 函数的定义和调用函数的定义和调用函数的定义和调用函数的定义和调用 6.3 6.3 程序嵌套调用和递归调用程序嵌套调用和递归调用程序嵌套调用和递归调用程序嵌套调用和递归调用 6.4 6.4 作用域和存储类型作用域和存储类型作用域和存储类型作用域和存储类型 6.5 6.5 内部函数和外部函数内部函数和外部函数内部函数和外部函数内部函数和外部函数 6.6 6.6 模块化程序设计模块化程序设计模块化程序设计模块化程序设计 6.7 6.7 应用举例应用举例应用举例应用举例 7/12/20242程序设计基础(C语言)wh 对大千世界的许多描述大都可以在计算机中运用程序对大千世界的许多描述大都可以在计算机中运用程序设计中的函数问题来解决,设计中的函数问题来解决,C语言程序设计也不例外。语言程序设计也不例外。一个功能较大的系统,它一定包含有若干个相对独立一个功能较大的系统,它一定包含有若干个相对独立的子功能,通过子程序模块来描述这些子功能,再通过的子功能,通过子程序模块来描述这些子功能,再通过对这些子程序的组织和调用,来实现整个程序的功能要对这些子程序的组织和调用,来实现整个程序的功能要求。而这些功能比较独立的子程序模块则称之为函数求。而这些功能比较独立的子程序模块则称之为函数。本章用于揭开函数的真面目!本章用于揭开函数的真面目!7/12/20243程序设计基础(C语言)wh6.1 6.1 结构化程序设计结构化程序设计 6.1.1 6.1.1 6.1.1 6.1.1 结构化程序设计的基本概念结构化程序设计的基本概念结构化程序设计的基本概念结构化程序设计的基本概念结构化程序设计基本思想:结构化程序设计基本思想:将一个大的程序按功能分割成一些子模块,将一个大的程序按功能分割成一些子模块,再通过对这些子模块的组织和调用,来实现整个再通过对这些子模块的组织和调用,来实现整个程序的功能要求。程序的功能要求。7/12/20244程序设计基础(C语言)wh#include stdio.h void main()float a,b,c,v;scanf(”%f,%f,%f”,&a,&b,&c);v=volume(a,b,c);print_message();float volume(float a,float b,float c)float v;v=a*b*c;return(v);void print_message()printf(”v=%f”,v);输出体积输出体积输出体积输出体积组织和调用组织和调用组织和调用组织和调用计算立方体计算立方体计算立方体计算立方体示例:编程序计算一立方体的体积,并在屏幕上输出。示例:编程序计算一立方体的体积,并在屏幕上输出。7/12/20245程序设计基础(C语言)wh6.1 6.1 结构化程序设计结构化程序设计 6.1.1 6.1.1 6.1.1 6.1.1 结构化程序设计的基本概念结构化程序设计的基本概念结构化程序设计的基本概念结构化程序设计的基本概念 结构化程序设计特点:结构化程序设计特点:各模块相对独立、功能单一、结构清晰;各模块相对独立、功能单一、结构清晰;控制了程序设计的复杂性;控制了程序设计的复杂性;提高元件的可靠性提高元件的可靠性缩短开发周期;缩短开发周期;避免程序开发的重复劳动;避免程序开发的重复劳动;易于维护和功能扩充;易于维护和功能扩充;开发方法开发方法:自上向下,逐步求精自上向下,逐步求精 ,模块化,模块化 ,限限制使用制使用gotogoto语句。语句。7/12/20246程序设计基础(C语言)wh6.1 6.1 结构化程序设计结构化程序设计 6.1.2 6.1.2 6.1.2 6.1.2 结构化程序设计的基本特征结构化程序设计的基本特征结构化程序设计的基本特征结构化程序设计的基本特征 1.1.程序的三种基本结构程序的三种基本结构 AB顺序结构图顺序结构图顺序结构图顺序结构图 条件条件AB真真假假选择结构图选择结构图选择结构图选择结构图 条件条件A假假真真循环结构图循环结构图循环结构图循环结构图 7/12/20247程序设计基础(C语言)wh2.C2.C语言语言是模块化程序设计语言是模块化程序设计语言C C程序结构程序结构A AB BC CD DE EF FG GH HI I7/12/20248程序设计基础(C语言)wh3.3.程序设计采用自顶向下逐步细化过程程序设计采用自顶向下逐步细化过程 工资计算程序工资计算程序工资计算工资计算信息输入信息输入工资额计算工资额计算工资表打印工资表打印应发部分应发部分扣除部分扣除部分基本工资基本工资其他补贴其他补贴水电、公积金水电、公积金7/12/20249程序设计基础(C语言)wh6.2 6.2 函数的定义和调用函数的定义和调用 函数是函数是C语言程序的一种基本组成部分,语言程序的一种基本组成部分,C语言程序的功能是通过函数之间的调用来实语言程序的功能是通过函数之间的调用来实 现,一个完整的现,一个完整的C语言程序可由一个或多个函语言程序可由一个或多个函 数组成。数组成。0;-x)y=y*x;return(y);传统式传统式例例 有参函数有参函数 long facto(int x)long y;for(y=1;x0;-x)y=y*x;return(y);现代式现代式函数类型函数类型 函数名函数名(形参类型说明表形参类型说明表)说明部分说明部分语句部分语句部分现代格式现代格式函数返回值类型函数返回值类型缺省缺省 int 型型无返回值无返回值 void合法标识符合法标识符可以为空可以为空也可以有多个参数也可以有多个参数函数体函数体例例 无参函数无参函数 void print_message()printf(”v=%f”,v);例例 空函数空函数myfile()函数体为空函数体为空7/12/202413程序设计基础(C语言)wh6.2 6.2 函数的定义和调用函数的定义和调用 6.2.2 6.2.2 6.2.2 6.2.2 函函函函 数数数数 的的的的 调调调调 用用用用 一一.函数调用格式及执行过程函数调用格式及执行过程 调用形式调用形式函数名函数名(实参列表实参列表);说明:说明:实参与形参实参与形参个数相等,类型一致,按顺序一一对应个数相等,类型一致,按顺序一一对应;实参列表求值顺序,因系统而定实参列表求值顺序,因系统而定(Turbo C 自右向左自右向左);实参的量可以是常量、有值的变量或运算表达式实参的量可以是常量、有值的变量或运算表达式.7/12/202414程序设计基础(C语言)wh#include stdio.h void main()int i=1,n;n=f(i,+i);printf(”nn=%dn”,n);f(int a,int b)int c;if(a=b)c=1;else c=0;return(c);自右向左顺序自右向左顺序自右向左顺序自右向左顺序#include stdio.h void main()int i=1,n;n=f(i,+i);printf(”nn=%dn”,n);f(int a,int b)int c;if(a=b)c=1;else c=0;return(c);自左向右顺序自左向右顺序自左向右顺序自左向右顺序 【例【例6_3】实参求值顺序举例。实参求值顺序举例。运行结果:运行结果:n=0 运行结果:运行结果:n=1 i(1),+i(2)a(1),b(2)c=0;i(2),+i(2)a(2),b(2)c=1;7/12/202415程序设计基础(C语言)wh函数调用语句的执行过程:函数调用语句的执行过程:首先计算每个实参表达式的首先计算每个实参表达式的值,并把此值存入所对应值,并把此值存入所对应 的形参单元中,的形参单元中,执行流程转入函数体,执行函数体中的各语句。执行流程转入函数体,执行函数体中的各语句。函数体执行完之后,函数体执行完之后,return(c)return(c)返回到调用该函数的返回到调用该函数的 函数中的调用处的下一条语函数中的调用处的下一条语/*计算面积计算面积*/#include stdio.h void main()int x=5,y=4,s=0;s=f(x,y);printf(”ns=%dn”,s);f(int a,int b)c=a*b;return(c);x=5y=4a=5b=4c=5*4=20s=20运行结果:运行结果:s=20 7/12/202416程序设计基础(C语言)wh二二.函函 数数 的的 调调 用用 方方 式式 3.以函数调用中的一个实际参数形式调用以函数调用中的一个实际参数形式调用 例如例如 k=hust(hust(m,n),j);printf(”%d”,power(a,b);2.以函数表达式的一个运算对象形式调用以函数表达式的一个运算对象形式调用 例如例如 k=hust(m,n)*hust(i,j);1.以函数调用语句形式调用以函数调用语句形式调用例如例如 hust();7/12/202417程序设计基础(C语言)wh三三.对被调用函数的使用说明对被调用函数的使用说明 在程序中调用另一个函数时,要满足以下三个条件在程序中调用另一个函数时,要满足以下三个条件:被调用函数可以是已存在的用户自定义函数或库函数。被调用函数可以是已存在的用户自定义函数或库函数。#include stdio.h void main()int x=5,y=4,s=0;s=f(x,y);printf(”ns=%dn”,s);f(int a,int b)c=a*b;return(c);用户自定义函数用户自定义函数库函数库函数 若是库函数,应用若是库函数,应用#include命令将有关库函数所需的信息包含到本文件中命令将有关库函数所需的信息包含到本文件中#include stdio.h void main()printf(“*”);若是用户自定义的函数,且该函数与调用它的函数若是用户自定义的函数,且该函数与调用它的函数(即调用函数即调用函数)在同一个源在同一个源文件中,则在调用函数中应对被调用函数返回值的类型加以说明。文件中,则在调用函数中应对被调用函数返回值的类型加以说明。7/12/202418程序设计基础(C语言)wh#include stdio.h void main()float volume(float a,float b,float c)float x,y,z,v;scanf(”%f%f%f”,&x,&y,&z);v=volume(x,y,z);printf(”v=%fn”,v);float volume(float a,float b,float c)float d;d=a*b*c;return(d);【例【例6_4】求长方形体积的程序。求长方形体积的程序。对自定义函数对自定义函数volume说明说明 调用自定义函调用自定义函数数volume 7/12/202419程序设计基础(C语言)wh6.2 6.2 函数的定义和调用函数的定义和调用 6.2.3 6.2.3 6.2.3 6.2.3 函数的函数的函数的函数的返回值返回值返回值返回值 n返回语句形式返回语句形式return(表达式表达式);说明:说明:l系统默认的返回值类型为系统默认的返回值类型为int型型 l当函数有返回值时,凡是允许表达式出现的地方,都可以调用该函数当函数有返回值时,凡是允许表达式出现的地方,都可以调用该函数 l当函数没有返回值时,函数的返回值类型可以说明为当函数没有返回值时,函数的返回值类型可以说明为void型型(空类型空类型)l若无若无return语句,遇语句,遇 时,自动返回调用函数时,自动返回调用函数l函数中可有多个函数中可有多个return语句语句或或return 表达式;表达式;或或return;n功能功能:利用利用return语句,将计算结果语句,将计算结果(或不带结果或不带结果)返回给调用程序,返回给调用程序,同时,也使程序的执行流程转到调用语句的下一语句去执行。同时,也使程序的执行流程转到调用语句的下一语句去执行。7/12/202420程序设计基础(C语言)wh float count(int n)int i;float s;if(n=0);printf(”The%d is invalid”,n);return(0);else s=0;for(i=1;i=n;i+)s+=1/(float)i;return(s);【例【例6_5】编一函数,求编一函数,求112131n的值。的值。强制转换成实型强制转换成实型 7/12/202421程序设计基础(C语言)wh void spc(int n)int i;for(i=0;in;i+)printf(”%c”,);return(0);【例【例6_6】打印打印n个空格的函数。个空格的函数。void spc(int n)int i;for(i=0;in;i+)printf(”%c”,);返回调用函数返回调用函数 或或7/12/202422程序设计基础(C语言)whvoid line(int n)line(int n)int i;for(i=1;i=n;i+)printf(”%c”,-);return;调用该函数:调用该函数:printf(”%d”,line(30);当无返回值的函数将当无返回值的函数将void省掉时,省掉时,函数将返回一个不确定的值。函数将返回一个不确定的值。例如例如:输出一段虚线的输出一段虚线的同时,还输出同时,还输出line函数的返回函数的返回值值,它是一个不它是一个不确定的值。确定的值。引起编译错误引起编译错误 7/12/202423程序设计基础(C语言)wh double power(float x,int n)int i;double pw;pw=l;for(i=1;i=n;i+)pw*=x;return pw;【例【例6_7】编一函数编一函数,求求x的的n次方的值次方的值,其中其中n是整数是整数。将将 x、n 做为做为函数参数函数参数 结果通过结果通过return语句语句返回调用程序返回调用程序 7/12/202424程序设计基础(C语言)wh to_str(int n)char str10;int i;if(n0);while(-i=0)putchar(stri);【例【例6_8】将一个给定的整数转换成相应的字符串后显示出来。将一个给定的整数转换成相应的字符串后显示出来。将数值型的数据将数值型的数据转换成数值字符转换成数值字符的内码的内码 7/12/202425程序设计基础(C语言)wh正确的形参定义正确的形参定义 int hust(a,b)int a,b;int hust(int a,int b)或或错误的形参定义错误的形参定义 int hust(int a,b)int b;int hust(int a,b)或或6.2 6.2 函数的定义和调用函数的定义和调用 6.2.4 6.2.4 6.2.4 6.2.4 函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递 n形式参数:定义函数时函数名后面括号中的变量名。形式参数:定义函数时函数名后面括号中的变量名。n实际参数:调用函数时函数名后面括号中的表达式。实际参数:调用函数时函数名后面括号中的表达式。例如例如n形参与实参形参与实参实参的定义实参的定义 s=hust(x,y);7/12/202426程序设计基础(C语言)wh/*计算面积计算面积*/#include stdio.h void main()int x=5,y=4,s=0;s=f(x,y);printf(”ns=%dn”,s);f(int a,int b)c=a*b;return(c);实参实参 形参形参 s=f(x,y);(main 函数函数)(f 函数函数)f(int a,int b)c=a*b;return(c);7/12/202427程序设计基础(C语言)wh6.2 6.2 函数的定义和调用函数的定义和调用 6.2.4 6.2.4 6.2.4 6.2.4 函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递 n形式参数:定义函数时函数名后面括号中的变量名。形式参数:定义函数时函数名后面括号中的变量名。n实际参数:调用函数时函数名后面括号中的表达式。实际参数:调用函数时函数名后面括号中的表达式。n形参与实参形参与实参说明:说明:l实参可以是常量、已赋值的变量或表达式。实参可以是常量、已赋值的变量或表达式。l实参在次序、类型和个数上应与相应形参表中的形参保持一致。实参在次序、类型和个数上应与相应形参表中的形参保持一致。l通常,当需要从调用函数中传值通常,当需要从调用函数中传值(或传地址或传地址)到被调用函数中的形参时到被调用函数中的形参时应设置实参。应设置实参。7/12/202428程序设计基础(C语言)wh6.2 6.2 函数的定义和调用函数的定义和调用 6.2.4 6.2.4 6.2.4 6.2.4 函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递 n值的传递值的传递:调用函数将实参:调用函数将实参(常数、变量、数组元素或可计算常数、变量、数组元素或可计算的表达式的表达式)的值传递到被调用函数形参设置的临时变量存储的值传递到被调用函数形参设置的临时变量存储单元中,被调用函数形参值的改变对调用函数的实参没有单元中,被调用函数形参值的改变对调用函数的实参没有影响。调用结束后,形参存储单元被释放,实参仍保持原影响。调用结束后,形参存储单元被释放,实参仍保持原值不变。值不变。n传递形参值的两种方法传递形参值的两种方法 n特点特点:l形参与实参占用形参与实参占用不同不同的内存单元的内存单元.l单向单向传递传递7/12/202429程序设计基础(C语言)wh#include stdio.h void main()int i=25;printf(”The value of i in main()before calling sqr(x)is%dn”,i);printf(”Calling sqr(x):sqr(%d)=%dn”,i,sqr(i);printf(”The value of i in main()after calling sqr(x)is%dn”,i);sqr(int x)x=x*x;return(x);【例【例6_9】值的传递程序举例值的传递程序举例 实参值复制给形参实参值复制给形参25i:调用前:调用前:调用:调用:25x:25i:运行结果:运行结果:The value of i in main()before calling sqr(x)is 25 Calling sqr(x):sqr(25)=625 The value of i in main()after calling sqr(x)is 25sqr:25i:6252525x:25i:调用结束:调用结束:结论:结论:在值的传递调用中,只是实参的复制值被传递,在值的传递调用中,只是实参的复制值被传递,被调用函数中的操作不会影响实参的值。被调用函数中的操作不会影响实参的值。7/12/202430程序设计基础(C语言)wh6.2 6.2 函数的定义和调用函数的定义和调用 6.2.4 6.2.4 6.2.4 6.2.4 函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递 n地址的传递地址的传递:调用函数将实参:调用函数将实参(数组名或指针型变量数组名或指针型变量)的地址的地址作为参数传递给形参。若实参是数组名,则调用函数将实参作为参数传递给形参。若实参是数组名,则调用函数将实参数组的起始地址传递给形参的临时变量单元;若实参是指针数组的起始地址传递给形参的临时变量单元;若实参是指针变量或地址表达式,则调用函数将实参指针变量所指向单元变量或地址表达式,则调用函数将实参指针变量所指向单元的地址或实参的地址传递给形参的临时变量存储单元。的地址或实参的地址传递给形参的临时变量存储单元。n传递形参值的两种方法传递形参值的两种方法 n特点特点:l形参与实参占用形参与实参占用相同相同的内存单元的内存单元.l双向双向传递传递l实参和形参必须是实参和形参必须是地址地址常量或变量常量或变量7/12/202431程序设计基础(C语言)whvoid f(int b)int max,max_i,i;max=b0,max_i=0;for(i=0;i10;i+)if(maxbi)max=bi;max_i=i;max=b0;b0=bmax_i;bmax_i=max;return;#include stdio.h void main()void f(int b);int a10,i;for(i=0;i10;i+)scanf(”%d”,&ai);f(a);for(i=0;i10;i+)printf(”n%4d”,ai);【例【例6_11】将数组中的最大元素值与第一个元素值交换】将数组中的最大元素值与第一个元素值交换 运行结果:运行结果:0 1 2 3 4 5 6 7 8 9 9 1 2 3 4 5 6 7 8 0 调用前调用前0a9b调用调用0a9交换交换b9a0返回返回9a0 结论:结论:在地址的传递调用中,数组在地址的传递调用中,数组b与数组与数组a共用同一存储空间。共用同一存储空间。所以被传递的数据在被调用函数中对存储空间的值做出某种所以被传递的数据在被调用函数中对存储空间的值做出某种 变动后,必然会影响到使用该空间的调用函数中变量的值。变动后,必然会影响到使用该空间的调用函数中变量的值。实实参参数数组组的的起起始始地地址址传传递递给给形形参参7/12/202432程序设计基础(C语言)wh6.2 6.2 函数的定义和调用函数的定义和调用 6.2.4 6.2.4 6.2.4 6.2.4 函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递 一、一、非数组名作为函数参数非数组名作为函数参数 n参数传递的两种形式参数传递的两种形式 当非数组名作为函数参数,在函数调用时,当非数组名作为函数参数,在函数调用时,C语言语言编译系统根据形参的类型为每个形参分配存储单元,并编译系统根据形参的类型为每个形参分配存储单元,并将实参的值复制到对应的形参单元之中,形参和实参分将实参的值复制到对应的形参单元之中,形参和实参分别占用不同的存储单元,且形参值的改变不影响与其对别占用不同的存储单元,且形参值的改变不影响与其对应的实参,即按应的实参,即按“值的传递值的传递”方法操作。方法操作。7/12/202433程序设计基础(C语言)wh f(int a,int b)a=a+2;b=b+4;printf(”a=%d,b=%dn”,a,b);return(a);#include stdio.h void main()int f(int a,int b);int x=1,y=2,z;static int a=0,1,2,3,4;z=f(x,y);printf(”z=%d,x=%d,y=%dn”,z,x,y);z=f(a3,a4);printf(”z=%d,a3=%d,a4=%dn”,z,a3,a4);z=f(x,y+1);printf(”z=%d,x=%d,y=%dn”,z,x,y);【例【例6_12】非数组名作为参数的值的传递程序举例非数组名作为参数的值的传递程序举例 运行结果:运行结果:7/12/202434程序设计基础(C语言)wh6.2 6.2 函数的定义和调用函数的定义和调用 6.2.4 6.2.4 6.2.4 6.2.4 函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递函数参数及函数间的数据传递 二、二、数组名作为函数参数数组名作为函数参数 n参数传递的两种形式参数传递的两种形式 单个数组元素可以作为函数参数,这同非数组名作为单个数组元素可以作为函数参数,这同非数组名作为函数参数的情形完全一样,即遵守函数参数的情形完全一样,即遵守”值传递值传递”方式。方式。7/12/202435程序设计基础(C语言)wh1 1、数组名作为函数参数的表示方法数组名作为函数参数的表示方法 当数组名作为函数参数时,需要对其类型进行相应的说明当数组名作为函数参数时,需要对其类型进行相应的说明 例如例如 int test(int array10).若数组说明时不指定数组的长度若数组说明时不指定数组的长度,可用另一个参数来表示数组的长度,可用另一个参数来表示数组的长度 例如例如 int test(int array,int n).用用形形参参n来来表表示示array数数 组组 的的 实实际长度,更灵活际长度,更灵活7/12/202436程序设计基础(C语言)whint solve(int a,int n)int sum,i;sum=0;for(i=0;in;i+)if(ai!=0)sum+;return(sum);【例【例6_13】编一函数编一函数,用来统计一个一维数组中用来统计一个一维数组中非非0元素的个数元素的个数用用形形参参n来来表表示示a数组的实际长度。数组的实际长度。7/12/202437程序设计基础(C语言)wh1 1、数组名作为函数参数的表示方法数组名作为函数参数的表示方法 l 当多维数组名作为函数参数时,除第一维可以不指定长当多维数组名作为函数参数时,除第一维可以不指定长度外,其余各维都必须指定长度。度外,其余各维都必须指定长度。例如例如 check(float a 10,float n).下面的参数说明都是不正确的:下面的参数说明都是不正确的:例如例如 float a ;或或 float a10;.7/12/202438程序设计基础(C语言)wh说明:说明:用数组名作为函数参数时,应该在调用函数和被调用函数用数组名作为函数参数时,应该在调用函数和被调用函数 中分别定义数组。中分别定义数组。实参数组和形参数组类型应一致,否则出错。实参数组和形参数组类型应一致,否则出错。形参数组的大小应大于等于实参数组的大小,否则得不到形参数组的大小应大于等于实参数组的大小,否则得不到 实参数组的全部值。实参数组的全部值。特别注意的是,数组名作为函数参数时,是将实参数组特别注意的是,数组名作为函数参数时,是将实参数组 的首地址传给形参数组,两数组的对应元素占用同一内的首地址传给形参数组,两数组的对应元素占用同一内 存单元。传递时按数组在内存中排列的顺序进行。存单元。传递时按数组在内存中排列的顺序进行。7/12/202439程序设计基础(C语言)wh2 2、数组名作为函数参数的传递方式数组名作为函数参数的传递方式 数组名作为函数参数时,不是采用数组名作为函数参数时,不是采用“值传递值传递”方式,方式,而是采用而是采用“地址传递地址传递”方式。方式。这意味着形参数组中某一元素的改变,将直接影响到这意味着形参数组中某一元素的改变,将直接影响到 与其对应的实参数组中的元素。与其对应的实参数组中的元素。7/12/202440程序设计基础(C语言)whvoid sort(int array10)int i,j,k,t;for(i=0;i9;i+)k=i;for(j=i+1;j10;j+)if(arrayjarrayk)k=j;t=arrayk;arrayk=arrayi;arrayi=t;#include stdio.h void main()int x10,i;void sort(int array10);for(i=0;i10;i+)scanf(”%d,”,&xi);sort(x);printf(”The sorted array:n”);for(i=0;i10;i+)printf(”%d,”,xi);printf(”n”);【例【例6_146_14】将一个将一个1010个元素的一维数组用函数调用实现选择排序。个元素的一维数组用函数调用实现选择排序。调用前调用前9x009 调用调用9x009array 交换交换0 x909array 返回返回0 x909寻寻找找排排序序7/12/202441程序设计基础(C语言)wh6.3 6.3 嵌套调用和递归调用嵌套调用和递归调用 C语言中的函数定义是互相独立的,函数和函数之间语言中的函数定义是互相独立的,函数和函数之间没有从属关系,即一个函数内不允许包含另一个函数的定没有从属关系,即一个函数内不允许包含另一个函数的定义。一个函数既可以被其他函数调用,同时,它也可以调义。一个函数既可以被其他函数调用,同时,它也可以调用别的函数,这就是函数的嵌套调用。函数的嵌套调用为用别的函数,这就是函数的嵌套调用。函数的嵌套调用为自顶向下、逐步求精及模块化的结构化程序设计技术提供自顶向下、逐步求精及模块化的结构化程序设计技术提供了最基本的支持。了最基本的支持。=0)break;result=fact(n);printf(”Result=%ld”,result);【例【例6_166_16】从键盘输入一非负整数从键盘输入一非负整数n,并求出,并求出n!的值。的值。n!=n*(n-1)!结果分析:结果分析:n=4 f(4)=4*fac(4-1)=3 f(3)=3*fac(3-1)=2 f(2)=2*fac(2-1)=1 f(1)=1*fact(1-1)=0 f(0)=1回推回推递推递推运行情况:运行情况:Input a number:4 Result=24递归调用递归调用嵌套调用嵌套调用if(n=0)/*递归终止条件递归终止条件*/f=1;递归过程的两个阶段:递归过程的两个阶段:fact(4)fact(4)是主函数调用的。在一次调用是主函数调用的。在一次调用factfact函数时函数时并不是立即得到并不是立即得到fact(4)fact(4)的值,而是一次又一次地的值,而是一次又一次地进行递归调用进行递归调用(回推回推回推回推),直到,直到fact(1)fact(1)时才有确定的值。时才有确定的值。之后,再之后,再递推递推递推递推出出fact(2)fact(2)、fact(3)fact(3)、fact(4)fact(4)的值。的值。7/12/202446程序设计基础(C语言)whdouble xpower(float x,int n)if(n=0)return(1);else return(x*xpower(x,n-1);#include stdio.h void main()double xpower(float x,int n);float x;int n;double r scanf(”%f%d”,&x,&n);r=xpower(x,n);printf(”Result=%f”,r);【例【例6_17】编一程序,利用函数的递归调用求编一程序,利用函数的递归调用求x的的n次方的值,次方的值,其中其中n为正整数。为正整数。运行情况:运行情况:2,3 Result=8 小结:小结:任何有意义的递归调用总是由两部分组成:任何有意义的递归调用总是由两部分组成:即即递归方式递归方式与与递归终止条件递归终止条件。if(n=0)/*递归终止条件递归终止条件*/return(1);7/12/202447程序设计基础(C语言)wh6.4 6.4 作用域和存储类型作用域和存储类型 n 变量是对程序中数据的存储空间的抽象变量是对程序中数据的存储空间的抽象n 变量的属性变量的属性n数据类型:变量所持有的数据的性质(数据类型:变量所持有的数据的性质(操作属性操作属性)n存储属性存储属性l存储器类型:寄存器、静态存储区、动态存储区存储器类型:寄存器、静态存储区、动态存储区l生存期生存期:变量在某一时刻存在:变量在某一时刻存在 静态变量与动态变量静态变量与动态变量l作用域作用域:变量在某区域内有效:变量在某区域内有效 局部变量与全局变量局部变量与全局变量n 变量的存储类型变量的存储类型n auto 自动型自动型n register 寄存器型寄存器型n static 静态型静态型n extern 外部型外部型n 变量定义格式:变量定义格式:存储类型定义符存储类型定义符 数据类型数据类型 变量名表变量名表;如如:int sub;auto int x,y,z;register int n;static float a,b;7/12/202448程序设计基础(C语言)wh6.4 6.4 作用域和存储类型作用域和存储类型 6.4.1 6.4.1 6.4.1 6.4.1 局部变量及其存储类型局部变量及其存储类型局部变量及其存储类型局部变量及其存储类型 定义定义在在 函数函数 或或 复合语句复合语句 内部定义的变量称为内部定义的变量称为 局部变量局部变量。说明说明n主函数主函数main中定义的变量也只在主函数中有效,其它函数不能引用;中定义的变量也只在主函数中有效,其它函数不能引用;n不同函数中可以使用相同名字的变量,它们代表不同的对象,占用不同不同函数中可以使用相同名字的变量,它们代表不同的对象,占用不同的内存单元,互相独立;的内存单元,互相独立;n形式参数形式参数也是局部变量;也是局部变量;n可以在可以在复合语句复合语句中定义变量,其作用域只是本复合语句。中定义变量,其作用域只是本复合语句。7/12/202449程序设计基础(C语言)wh float hust1(int a)int x,y;举举 例例局部变量局部变量a、x、y的作用范围的作用范围 float hust2(int b,int c)char s;局部变量局部变量b、c、s的作用范围的作用范围void main()int m,n;局部变量局部变量m、n的作用范围的作用范围7/12/202450程序设计基础(C语言)wh举举 例例#include”stdio.h”void main()int p,q;int x;x=p+q;x 的有效范围的有效范围p、q的有效范围的有效范围7/12/202451程序设计基础(C语言)wh6.4 6.4 作用域和存储类型作用域和存储类型 6.4.1 6.4.1 6.4.1 6.4.1 局部变量及其存储类型局部变量及其存储类型局部变量及其存储类型局部变量及其存储类型 1.自动存储变量自动存储变量 auto自动存储自动存储自动存储自动存储变量变量变量变量 在函数或复合语句中定义和说明的变量,通常称为自动变在函数或复合语句中定义和说明的变量,通常称为自动变量。自动变量前可以冠以量。自动变量前可以冠以“autoautoautoauto”,若变量前不加任何存储类,若变量前不加任何存储类别说明别说明 ,则按,则按缺省规则都为自动存储类别缺省规则都为自动存储类别的变量。的变量。作用域:作用域:自动变量通常是局部变量,它的作用域仅限于定义它的那自动变量通常是局部变量,它的作用域仅限于定义它的那个函数或复合语句。它的可见性与生存期和作用域相同。个函数或复合语句。它的可见性与生存期和作用域相同。auto float a;float a;或或7/12/202452程序设计基础(C语言)wh【例【例6_18】不同函数中的同名变量不同函数中的同名变量#include stdio.hvoid main()int a;a=0;data();a=a+100;printf(”main:a=%dn”,a);data()int a;a=-199;printf(”data:a=%dn”,a);运行结果:运行结果:data:a=-199main:a=100不指定为不指定为auto型型不指定为不指定为auto型型#include stdio.hvoid main()int a;a=1;data();a=a+100;printf(”main:a=%dn”,a);data()int a;printf(“da=%dn,a);a=-199;printf(”data:a=%dn”,a);运行结果:运行结果:da=1 data:a=199 main:a=1017/12/202453程序设计基础(C语言)wh【例【例6_18】不同函数中的同名变量不同函数中的同名变量#include stdio.hvoid main()int a;a=10;printf(“ma=%d,%xn,a,&a);data();a=a+100;printf(”main:a=%dn”,a,&a);data()int a;printf(“da=%dn,a,&a);a+=1;printf(“daa=%d,%xn,a,&a);a=-199;printf(”data:a=%dn”,a,&a);运行结果:运行结果:ma=10,ffdcda=404,ffd6daa=405,ffd6data:a=199,ffd6main:a=110,ffdc7/12/202454程序设计基础(C语言)wh6.4 6.4 作用域和存储类型作用域和存储类型 6.4.1 6.4.1 6.4.1 6.4.1 局部变量及其存储类型局部变量及其存储类型局部变量及其存储类型局部变量及其存储类型 2.静态局部变量静态局部变量 static 如果希望在函数调用结束后仍然保留函数中定义的局部变如果希望在函数调用结束后仍然保留函数中定义的局部变量的值,则可以将该局部变量定义为静态局部变量。量的值,则可以将该局部变量定义为静态局部变量。静态局部变量前可以冠以静态局部变量前可以冠以“static”例如例如 static int t,s;说明:说明:静态局部变量的作用域在定义它的函数内部,它的值在函静态局部变量的作用域在定义它的函数内部,它的值在函 数调用结束后并不消失,但其他函数仍然不能访问它。数调用结束后并不消失,但其他函数仍然不能访问它。静态局部变量赋初值是在编译过程中进行的,静态局部变量赋初值是在编译过程中进行的,且只赋一次且只赋一次 初值初值。而且连续保留上一次函数调用时的结果。而且连续保留上一次函数调用时的结果。静态局部变量的默认初值数值型为静态局部变量的默认初值数值型为0,字符型为,字符型为Null7/12/202455程序设计基础(C语言)wh【例【例6_19】编一程序,观察静态局部变量在调编一程序,观察静态局部变量在调用过程中的情况。用过程中的情况。#include stdio.h void test()static int a=0;printf(”a=%dn”,a);+a;void main()int i;for(i=0;i4;i+)test();运行结果:运行结果:a=0 7/12/202456程序设计基础(C语言)wh#include int func(int a,int b)static int m=0,i=0;i+=m+1;m=i+a+b;return(m);main()()int k=3,m=2,p;p=func(k,m);printf(“p1=%dn”,p);p=func(k,m);printf(“p2=%dn”,p);运行结果:运行结果:p1=课堂练习:课堂练习:看程序写结果看程序写结果*i=i+(m+1)=0+(0+1)=1*m=1+3+2=6*i=i+(m+1)=1+(6+1)=8*m=8+3+2=13*7/12/202457程序设计基础(C语言)wh6.4 6.4 作用域和存储类型作用域和存储类型 6.4.1 6.4.1 6.4.1 6.4.1 局部变量及其存储类型局部变量及其存储类型局部变量及其存储类型局部变量及其存储类型 3.寄存器变量寄存器变量 register 为提高程序的运行速度,可将使用十分频繁的局部变量为提高程序的运行速度,可将使用十分频繁的局部变量说明为寄存器变量,即在局部变量前冠以说明为寄存器变量,即在局部变量前冠以register,告知编译,告知编译系统将其存储在系统将其存储在CPU的寄存器中的寄存器中 void test_r(register int n)register char c;.说明:说明:变量的存储类型为寄存器变量时,变量的存储类型为寄存器变量时,auto说明符可省,冠以说明符可省,冠以register说明符即可说明符即可寄存器变量的使用与机器的硬件特性有关,有一些限制寄存器变量的使用与机器的硬件特性有关,有一些限制:l如寄存器变量的个数;如寄存器变量的个数;l它只适用于自动变量和函数的形参;它只适用于自动变量和函数的形参;l它的类型只能是它的类型只能是char、short int、unsigned int、int和和指针型指针型;l不允许对寄存器变量取地址等。不允许对寄存器变量取地址等。Turbo C中寄存器变量只能用于中寄存器变量只能用于整型整型和和字符型字符型,且限制最多只允许定义,且限制最多只允许定义两个两个 寄存器变量。一旦超过,系统就自动地将其余的作为非寄存器变量来处理。寄存器变量。一旦超过,系统就自动地将其余的作为非寄存器变量来处理。7/12/202458程序设计基础(C语言)whi的作用范围的作用范围【例【例6_20】输出输出1到到5的阶乘的值。的阶乘的值。#include stdio.h void main()int fac(int n);int i;for(i=1;i=5;i+)printf(”%d!=%dn”,i,fac(i);int fac(int n)register int i,f=1;for(i=1;i=n;i+)f=f*i;return(f);运行结果:运行结果:1!=1 i、f的作用范围的作用范围7/12/202459程序设计基础(C语言)wh【例【例6_21】编一程序,输入编一程序,输入10名学生的成绩,名学生的成绩,并求出平均成绩并求出平均成绩#include stdio.h float ascore(float a,int n)register int i;float sum;sum=0;for(i=0;in;i+)sum+=ai;return(sum/n);void main()float array10;register int i;for(i=0;i10;i+)scanf(”%f”,&arrayi);printf(”Average score=%f”,;ascore(array,10);i的作用的作用范围范围i的作用的作用范围范围7/12/202460程序设计基础(C语言)wh6.4 6.4 作用域和存储类型作用域和存储类型 6.4.2 6.4.2 6.4.2 6.4.2 全局变量及其存储类型全局变量及其存储类型全局变量及其存储类型全局变量及其存储类型 定义定义一个源程序文件可以包含一个或若干个函数。一个源程序文件可以包含一个或若干个函数。在函数之外定义的变量称为全局变量或全程变量在函数之外定义的变量称为全局变量或全程变量(又称又称外部变量外部变量)。全局变量全局变量与与局部变量局部变量的区别:的区别:l全局变量全局变量在函数之外定义,在函数之外定义,局部变量局部变量在函数之内定义;在函数之内定义;l局部变量局部变量在本函数之内有效,在本函数之内有效,全局变量全局变量从定义变量的位置开始到本源文从定义变量的位置开始到本源文件结束均有效。件结束均有效。l编译时编译时全局变量全局变量分配在静态存储区,而分配在静态存储区,而局部变量局部变量则不一定则不一定。7/12/202461程序设计基础(C语言)wh【例【例6_22】编一程序,打印九九表编一程序,打印九九表#include stdio.h void row();int a=1;/*外部变量外部变量*/void main()int k;for(k=1;k=9;+k,+a)row();void row()int b;for(b=1;b=a;+b)printf(”%4d”,a*b);printf(”n”);k的有效范围的有效范围b的有效范围的有效范围作作用用域域a7/12/202462程序设计基础(C语言)wh6.4 6.4 作用域和存储类型作用域和存储类型 6.4.2 6.4.2 6.4.2 6.4.2 全局变量及其存储类型全局变量及其存储类型全局变量及其存储类型全局变量及其存储类型 1.外部变量外部变量 extern 外部外部外部外部变量变量变量变量 没有说明为没有说明为static的全局变量,其存储类型都是外部的,的全局变量,其存储类型都是外部的,统称为外部变量。统称为外部变量。外部变量说明外部变量说明外部变量说明外部变量说明extern extern 数据类型数据类型数据类型数据类型 变量表;变量表;变量表;变量表;注意:注意:凡在函数外定义的全局变量,按缺省规则可以不写说明凡在函数外定义的全局变量,按缺省规则可以不写说明externextern,但在函数体内说明其后所定义的全局变量时,要冠以但在函数体内说明其后所定义的全局变量时,要冠以externextern。若一个文件要引用另一个文件中的全局变量,应该在需要引用该若一个文件要引用另一个文件中的全局变量,应该在需要引用该 变量的文件中,用变量的文件中,用 extern说明该变量为外部的全局变量。说明该变量为外部的全局变量。7/12/202463程序设计基础(C语言)wh【例【例6_23】编一程序,打印九九表编一程序,打印九九表#include stdio.hvoid row();void main()int k;for(k=1;k=9;+k,+a)row();int a=1;/*定义外部变量定义外部变量*/void row()int b;for(b=1;b=a;+b)printf(”%4d”,a*b);printf(”n”);作作用用域域a作作用用域域a扩扩展展externextern只只能能用用来来说说明明变变量量,而而不不能能用用来定义变量。来定义变量。7/12/202464程序设计基础(C语言)wh 例如例如 在不同的文件中引用外部变量在不同的文件中引用外部变量 文件f1.c的内容:#include “f2.c”int x;/*外部变量定义*/main()int sum,y;scanf(“%d”,&y);store();sum=x+y;printf(“sum=%d”,sum);文件f2.c的内容:extern int x;/*外部变量引用说明外部变量引用说明*/void store()x=10;7/12/202465程序设计基础(C语言)wh6.4 6.4 作用域和存储类型作用域和存储类型 6.4.2 6.4.2 6.4.2 6.4.2 全局变量及其存储类型全局变量及其存储类型全局变量及其存储类型全局变量及其存储类型 2.静态静态外部变量外部变量 static 静态全局变量一定是在本文件中定义的全局变量,其存静态全局变量一定是在本文件中定义的全局变量,其存储类型说明符是储类型说明符是staticstatic。静态全局变量的作用域是其静态全局变量的作用域是其定义点开始到该文件的结束定义点开始到该文件的结束定义点开始到该文件的结束定义点开始到该文件的结束,在本文件外不能访问。在本文件外不能访问。这种全局变量起到一个屏蔽作用。也可以对函数定义成这种全局变量起到一个屏蔽作用。也可以对函数定义成静态的,来限制函数的作用域。静态的,来限制函数的作用域。静态外部变量静态外部变量与与外部变量外部变量的相同与区别:的相同与区别:两者都是在两者都是在静态存储区静态存储区中分配单元中分配单元;外部变量外部变量不仅在本函数之内使用,还可以用于其他函数不仅在本函数之内使用,还可以用于其他函数,但但静态外部变量静态外部变量则不能用于其他函数;则不能用于其他函数;7/12/202466程序设计基础(C语言)wh 例如例如 下面对静态全局变量的引用是错误的:下面对静态全局变量的引用是错误的:file1.c static int
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!