C语言入门文档.ppt
04 Function(函数)Structure:ClanaguageteachgroupWenHeNEUSOFTKnowledgepointlFunctionDefinition函数定义函数定义lReturnStatement返回语句返回语句lFunctionCall函数调用函数调用lVariablestoragetypes变量存储类型变量存储类型lRecursivefunctioncalls函数递归调用函数递归调用2NEUSOFTlCisamodularprogramminglanguage(C是模块化程序设计语言是模块化程序设计语言)C program structure C program structure(C C程序结构)程序结构)&C是函数式语言&必须有且只能有一个名为main的主函数&C程序的执行总是从main函数开始,在main中结束&函数不能嵌套定义,可以嵌套调用3NEUSOFTUnderstandingofthefunction#include/*/*functionfunction:Computethesumof2integersComputethesumof2integersinputinput:integerofaandbintegerofaandboutput/returnvalueoutput/returnvalue:sumofaandbsumofaandb*/int Add(int a,int b)return(a+b);main()/*main function*/int x,y,sum=0;printf(Input two integers:);scanf(%d%d,&x,&y);sum=Add(x,y);printf(sum=%dn,sum);return;4NEUSOFTClassificationoffunctions(函数分类)(函数分类)l函数分类l从用户角度标准函数(库函数):libraryfunctions用户自定义函数userfunctionsl从函数形式无参函数non-argument有参函数witharguments5NEUSOFTFunctionDefinition(函数定义)(函数定义)Format:typename(argumentstatement)declarationstatement;statement;statement;6NEUSOFTFunctionDefinition(函数定义)(函数定义)7NEUSOFT合法标识符函数返回值类型缺省int型无返回值void函数体函数类型 函数名(形参类型说明表)说明部分语句部分格式:Eg:有参函数(with arguments)int max(int x,int y)int z;z=xy?x:y;return(z);Eg:有参函数 int max(int x,y)int z;z=xy?x:y;return(z);例 空函数 dummy()函数体为空Eg:无参函数(non-argument)printstar()printf(“*n”);or printstar(void)printf(“*n”);8NEUSOFTFunctionDefinitionvoid sum()void sum()函数体语句;函数体语句;intint sum()sum()函数体语句;函数体语句;floatfloat sum()sum()函数体语句;函数体语句;double double sum(intsum(int a,inta,int b)b)函数体语句;函数体语句;有类型标志符的函数,有类型标志符的函数,其函数体内一定有其函数体内一定有returnreturn语句语句void void sum(intsum(int a)a)函数体语句;函数体语句;9NEUSOFTFormat:returnexpression;return(expression);return;Annotation:Theprogramreturnstothecallingfunction,thevalueofexpressionreturnstoitscaller.返回调用函数Theremaybemorethanonereturnstatements,butthereisonlyonereturnvalueinafunction.可能不止一个return语句,但一次只能带回一个返回值。Returnstatement10NEUSOFTReturnstatementfloat max(float x,float y)float z;z=xy?x:y;return(z);int main()float a,b;int c;scanf(%f,%f,&a,&b);c=max(a,b);printf(Max is%dn,c);return 0;11NEUSOFTPrototypingaFunction(函数的声明)WeusedanANSIprototypetodeclarethefunctionbeforeitisused(函数使用之前需(函数使用之前需要要ANSI原型声明)原型声明)format:typename(argumentstatement);example:floatmax(floatx,floaty);orfloatmax(float,float);12NEUSOFTExample:float add(float,float);/*function declaration*/main()float a,b,c;scanf(%f,%f,&a,&b);c=add(a,b);printf(sum is%f,c);float add(float x,float y)float z;z=x+y;return(z);PrototypingaFunction(函数的声明)13NEUSOFTmain()float a,b;int c;scanf(%f,%f,&a,&b);c=max(a,b);printf(Max is%dn,c);max(float x,float y)float z;z=xy?x:y;return(z);int型函数可不作函数说明/*Example*/float add(float x,float y)float z;z=x+y;return(z);main()float a,b,c;scanf(%f,%f,&a,&b);c=add(a,b);printf(sum is%f,c);被调函数出现在主调函数之前,不必函数说明PrototypingaFunction(函数的声明)14NEUSOFT CallingaFunction(函数调用)CallingaFunctionwithoutArgument:functionname();();CallingaFunctionwithanArgument:functionname(ActualArguments););ActualArgumentsandFormalparameter:个数相等个数相等类型一致类型一致按顺序一一对应按顺序一一对应NEUSOFT CallingaFunction(函数调用)无参函数的调用形式:无参函数的调用形式:函数名();函数名();有参函数的调用形式:有参函数的调用形式:函数名(实参);函数名(实参);实参与形参:实参与形参:个数相等个数相等类型一致类型一致按顺序一一对应按顺序一一对应NEUSOFTCallingaFunction(函数调用)17NEUSOFTCallingmain()float a,b;int c;scanf(%f,%f,&a,&b);c=max(a,b);printf(Max is%dn,c);int max(float x,float y)float z;z=xy?x:y;return(z);18NEUSOFTlFunctionparametersandtheirtransfermodelFormalparameter&ActualArgumentsl形式参数:定义函数时函数名后面括号中的变量名l实际参数:调用函数时函数名后面括号中的表达式c=max(a,b);(main 函数)(max 函数)int max(int x,int y)int z;z=xy?x:y;return(z);例 比较两个数并输出大者main()int a,b,c;scanf(%d,%d,&a,&b);c=max(a,b);printf(Max is%d,c);int max(int x,int y)int z;z=xy?x:y;return(z);形参实参19NEUSOFTl说明:实参必须有确定的值形参必须指定类型形参与实参类型一致,个数相同若形参与实参类型不一致,自动按形参类型转换函数调用转换形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放lFunctionparametersandtheirtransfermodelFormalparameter&ActualArgumentsl形式参数:定义函数时函数名后面括号中的变量名l实际参数:调用函数时函数名后面括号中的表达式20NEUSOFT例 计算x的立方#include float cube(float x)return(x*x*x);main()float a,product;printf(Please input value of a:);scanf(%f,&a);product=cube(a);printf(”Cube of%.4f is%.4fn,a,product);xaproduct1.21.21.72821NEUSOFTlParameterpassinglValueispassedWhenthefunctioncall,Allocationunitfortheparameter,andtheargumentvalueiscopiedintotheparameter;Endofthecall,parameterunitisreleased,Argumentstoretaintheoriginalvalue.Features:TheparameterandargumentstakedifferentinthememoryunitOne-waytransfer22NEUSOFTl参数传递方式l值传递方式方式:函数调用时,为形参分配单元,并将实参的值复制到形参中;调用结束,形参单元被释放,实参单元仍保留并维持原值特点:形参与实参占用不同的内存单元单向传递23NEUSOFT711x:y:调用前:调用结束:711x:y:例4.5 交换两个数/*ch4_5.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;调用:711a:b:711x:y:swap:711x:y:117a:b:temp24NEUSOFTlAddressispassedFunctioncall,thedatastorageaddresspassedtotheparameterFeatures:TheparameterandargumentstakeinthesamestorageunitTwo-waytransferActualandformalparametersmustbeconstantorvariableaddress25NEUSOFTl地址传递方式:函数调用时,将数据的存储地址作为参数传递给形参特点:形参与实参占用同样的存储单元“双向”传递实参和形参必须是地址常量或变量26NEUSOFT/*ch9_3.c*/swap(p1,p2)int*p1,*p2;int p;p=*p1;*p1=*p2;*p2=p;main()int a,b;scanf(%d,%d,&a,&b);printf(“a=%d,b=%dn”,a,b);printf(“swapped:n”);swap(&a,&b);printf(”a=%d,b=%dn,a,b);Exanple:交换两个数a59b调前:a59b调swap:p1&a&bp2a95b交换:p1&a&bp2a95b返回:27NEUSOFTNestedfunctioncalls(函数嵌套调用)28NEUSOFTNestedfunctioncallsf1()f2();f2()f3();f3()29NEUSOFT#include long sum(int a,int b);long factorial(int n);main()int n1,n2;long a;scanf(%d,%d,&n1,&n2);a=sum(n1,n2);printf(a=%1d,a);long sum(int a,int b)long c1,c2;c1=factorial(a);c2=factorial(b);return(c1+c2);long factorial(int n)long rtn=1;int i;for(i=1;i=n;i+)rtn*=i;return(rtn);long sum(int a,int b);文件包含编译预处理命令函数类型说明函数定义函数调用函数调用函数返回值形参实参30NEUSOFT例 求三个数中最大数和最小数的差值#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,&a,&b,&c);d=dif(a,b,c);printf(Max-Min=%dn,d);Ch7_202.cint 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);main()调用函数dif输出结束dif函数max函数调用函数max调用函数minmin函数31NEUSOFTPractice1、计算、计算s=1k+2k+3k+N k函数首部为:函数首部为:long f1(int long f1(int n,intn,int k)k)/*/*计算计算n n的的k k次方次方*/long f2(int long f2(int n,intn,int k)k)/*/*计算计算1 1到到n n的的k k次方之累次方之累加和加和*/32NEUSOFTAnswer#define K 4#define N 5long f1(int n,int k)/*计算计算n的的k次方次方*/long power=n;int i;for(i=1;ik;i+)power*=n;return power;long f2(int n,int k)/*计算计算1到到n的的k次方之累加和次方之累加和*/long sum=0;int i;for(i=1;i=n;i+)sum+=f1(i,k);return sum;main()printf(Sum of%d powers of integers from 1 to%ld=,K,N);printf(%dn,f2(N,K);33NEUSOFTRecursion(递归)34NEUSOFTRecursionnC语言的函数调用允许直接或间接地调用该函数本身,称为函数的递归调用。n含有直接或间接调用自己的函数称为递归函数。函数f调用函数f函数f1调用函数f2调用函数f1函数f2直接调用本身直接调用本身直接调用本身直接调用本身间接调用本身间接调用本身间接调用本身间接调用本身35NEUSOFTExample1/*recur.c*/#includevoidup_and_down(int);intmain(void)up_and_down(1);return0;voidup_and_down(intn)printf(Level%d:nlocation%pn,n,&n);if(n4)up_and_down(n+1);printf(LEVEL%d:nlocation%pn,n,&n);36NEUSOFTExample137NEUSOFTn用递归函数求4!4!=4*3!;3!=3*2!;2!=2*1!;1!=1;n!=n*(n-1)!1!=1Example238NEUSOFTn!=n*(n-1)!intmyFac(intn)if(n=1)return1;/递归的结束条件returnn*myFac(n-1);myFac(n)就是求就是求n!myFac(n-1)就是求就是求(n-1)!Example239NEUSOFT#includeintmyFac(intn);main()intf,n;scanf(%d,&n);f=myFac(n);printf(%d!=%dn,n,f);Example2intmyFac(intn)ints;if(n=1)s=1;elses=n*myFac(n-1);returns;40Computing Factorialfactorial(4)=4*factorial(3)=4*(3*factorial(2)=4*(3*(2*factorial(1)=4*(3*(2*(1*factorial(0)=4*(3*(2*(1*1)=4*(3*(2*1)=4*(3*2)=4*6=24factorial(0)=1;factorial(n)=n*factorial(n-1);41Trace Recursive factorialExecutes factorial(4)42Trace Recursive factorialExecutes factorial(3)43Trace Recursive factorialExecutes factorial(2)44Trace Recursive factorialExecutes factorial(1)45Trace Recursive factorialExecutes factorial(0)46Trace Recursive factorialreturns 147Trace Recursive factorialreturns factorial(0)48Trace Recursive factorialreturns factorial(1)49Trace Recursive factorialreturns factorial(2)50Trace Recursive factorialreturns factorial(3)51Trace Recursive factorialreturns factorial(4)52NEUSOFTRecursionFundamentals(递归原理)1.eachleveloffunctioncallhasitsownvariables(每一级函数调用都有自己的变量)2.eachfunctioncallisbalancedwithareturn(一次函数调用有一次返回)3.statementsinarecursivefunctionthatcomeaftertherecursivecallareexecutedintheoppositeorderfromwhichthefunctionsarecalled(位于递归调用后的语句执行顺序与被调函数顺序相反4.itsvitalthatarecursivefunctioncontainsomethingtohaltthesequenceofrecursivecalls(递归调用必须包含终止递归调用的语句)53NEUSOFTRecursionProsandCons(递归的优缺点)goodpoints:simplestsolutiontosomeprogrammingproblems(为一些问题提供简单的方法)(为一些问题提供简单的方法)badpoints:somerecursivealgorithmscanrapidlyexhaustacomputersmemoryresources.(一些递归会很快耗(一些递归会很快耗尽内存)尽内存)difficulttodocumentandmaintain.(难于阅读和理(难于阅读和理解)解)54NEUSOFTPratice求下数列的第求下数列的第20项的值。项的值。1,2,3,5,8,13,21,34a1=1;a2=2;a3=a1+a2;an=an-1+an-2;55NEUSOFTPratice求下数列的第求下数列的第20项的值。项的值。1,2,3,5,8,13,21,34f(1)=1;f(2)=2;f(n)=f(n-1)+f(n-2);56NEUSOFTPraticevoidmain()inta;a=f(20);printf(“%d”,a);intf(intn)ints;if(n=1)s=1;elseif(n=2)s=2;elses=f(n-1)+f(n-2);returns;57NEUSOFTStorageClasses(存储类型)1.Variableshavetwoproperties:变量属性1)duration(存储时期)lstaticstoragedurationlautomaticstorageduration2)scope(作用域)llocal;局部变量lglobal.全局变量58NEUSOFTlocal&global(局部(局部&全局变量)全局变量)l局部变量与全局变量l局部变量-内部变量定义:在函数内定义,只在本函数内有效说明:main中定义的变量只在main中有效不同函数中同名变量,占不同内存单元形参属于局部变量可定义在复合语句中有效的变量局部变量可用存储类型:autoregisterstatic(默认为auto)float f1(int a)int b,c;.char f2(int x,int y)int i,j;main()int m,n;.a,b,c有效x,y,i,j有效m,n有效有效例 不同函数中同名变量main()int a,b;a=3;b=4;printf(main:a=%d,b=%dn,a,b);sub();printf(main:a=%d,b=%dn,a,b);sub()int a,b;a=6;b=7;printf(sub:a=%d,b=%dn,a,b);例 复合语句中变量#define N 5main()int i;int aN=1,2,3,4,5;for(i=0;iN/2;i+)int temp;temp=ai;ai=aN-i-1;aN-i-1=temp;for(i=0;iN;i+)printf(%d ,ai);运行结果:5 4 3 2 1例 复合语句中变量#define N 5main()int i;int aN=1,2,3,4,5;for(i=0;iN/2;i+)int temp;temp=ai;ai=aN-i-1;aN-i-1=temp;for(i=0;i外部变量说明:extern数据类型变量表;若外部变量与局部变量同名,则外部变量被屏蔽若外部变量与局部变量同名,则外部变量被屏蔽外部变量可用存储类型:缺省或static60NEUSOFTfloat 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);作用域maxmin61NEUSOFTStorageClasses2.Therearefourstorageclasses:lautovariables自动变量lregistervariables寄存器变量lstaticvariables静态变量lexternvariables外部变量62NEUSOFTAutovariables(自动型变量)1.Declareinsideablock:eg.autointa;autointb=123;autocharc;.63NEUSOFT2.Example:eg1./*tellthevalueofx*/main()intx=1;intx=2;intx=3;printf(%dn,x);/*outputx=3*/printf(%dn,x);/*outputx=2*/printf(%dn,x);/*outputx=1*/4.3.1 Auto variables64NEUSOFTRegistervariables1.Registercanonlybeappliedtotheautomaticvariablesandtotheformalparametersofafuntion.2.Registervariablesaretobeplacedinmachinesregisters,raideefficiency.3.Sameastheautomaticvariables,localandautomatic.65NEUSOFTRegistervariablesRestriction:1.Onlyafewvariablesineachfunctionmaybekeptintheregister,3atmost.Excessregisterdeclarationisignored,tokenasautomatic.2.Onlycertaintypesareallowed.(int,char)3.Itisimpossibletoaccesstheaddressofaregistervariable.66NEUSOFTregister变量变量l放在CPU内部寄存器的变量,register变量的优点为运算速度快。计算机中内存有两种类型,如图所示:CPU寄存器内存67NEUSOFTStaticVariables1.StaticexternalvariablesNootherfilewillbeabletoaccessthen.2.StaticfunctionItsnameisinvisibleoutsideofthefileinwhichitisdeclared.3.StaticinternalvariablesLocalbuttheyremaininexistenceratherthancomingandgoingeachtimethefunctionisactivated.68NEUSOFTmain()void increment(void);increment();increment();increment();void increment(void)int x=0;x+;printf(“%dn”,x);局部静态变量值具有可继承性运行结果:1 1 1main()void increment(void);increment();increment();increment();void increment(void)static int x=0;x+;printf(“%dn”,x);运行结果:1 2 369NEUSOFTExternalvariables1.Thescopeofanexternalvariablelastsfromthepointatwhichitisdeclaredtotheendofthefilebeingcomplied.2.Theyareglobalandstatic.70NEUSOFT3.Exampleintx=321;main()intx=123;printf(%dn,x);/*outputx=123*/External variables71NEUSOFTmain()externintx;/*globalvariabledeclaration*/printf(%dn,x);External variables72NEUSOFT例 引用其它文件中的外部变量int global;extern float x;main()int local;.extern int global;static int number;func2().float x;static int number;func3()extern int global;.file1.cfile2.cfile3.c73NEUSOFTl动态变量与静态变量l存储方式静态存储:程序运行期间分配固定存储空间动态存储:程序运行期间根据需要动态分配存储空间程序区静态存储区动态存储区全局变量、局部静态变量形参变量局部动态变量(auto register)函数调用现场保护和返回地址等l生存期静态变量:从程序开始执行到程序结束动态变量:从包含该变量定义的函数开始执行至函数执行结束74NEUSOFTl变量存储类型静态动态存储方式程序整个运行期间函数调用开始至结束生存期编译时赋初值,只赋一次每次函数调用时赋初值自动赋初值0或空字符不确定未赋初值静态存储区动态区存储区寄存器局部变量外部变量作用域定义变量的函数或复合语句内本文件其它文件u局部变量默认为auto型uregister型变量个数受限,且不能为long,double,float型u局部static变量具有全局寿命和局部可见性uextern不是变量定义,可扩展外部变量作用域register局部staticauto外部static外部存储类别75