版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C程序设计语言第4章函数与程序结构孙志岗
sun@
2024/5/51FunctionsandProgramStructure第1页大话三国懿问曰:“孔明寝食及事之烦简若何?”
使者曰:“丞相夙兴夜寐,罚二十以上皆亲览焉。所啖之食,日不过数升。”
懿顾谓诸将曰:“孔明食少事烦,其能久乎?”第2页程序设计艺术算法设计艺术程序灵魂DonaldE.Knuth,"TheArtofComputerProgramming",清华大学出版社,结构设计艺术程序肉体“..thelargertheproject,themoreessentialthestructuring!”—Dijkstra,1968模块化(Parnas,1972)结构化(Structural)面向对象(Object-Oriented)面向组件(Component-Oriented)面向智能体(Agent-Oriented)……第3页假如不模块化读多少行程序能让你不头疼?main()当中能放多少行程序?假如printf()函数由10行代码替换,那么你见过程序会成什么样子?假如全部代码都在main()当中,怎么团体合作?假如代码都在一个文件中,怎么团体合作?第4页模块化优点模块各司其职每个模块只负责一件事情,它能够更专心便于进行单个模块设计、开发、调试、测试和维护等工作一个模块一个模块地完成,最终再将它们集成开发人员各司其职按模块分配任务,职责明确并行开发,缩短开发时间分而治之(Wirth,1971)
信息隐藏(Parnas,1972)第5页函数(function)和模块(module)函数是C语言中模块化编程最小单位能够把每个函数看作一个模块若干相关函数能够合并作一个“模块”main()printf()scanf()power()putchar()getchar()main()stdio:printf()scanf()putchar()getchar()mymdl:power()第6页函数分类函数生来都是平等,没有高低贵贱之分,只有main()稍微特殊一点点1、按定义分:标准函数、自定义函数2、按调用分:无参调用、有参调用3、按功效分:无值返回、有值返回第7页库函数ANSIC定义标准库函数符合标准C语言编译器必须提供这些函数函数行为也要符合ANSIC定义第三方库函数由其它厂商自行开发C语言函数库不在标准范围内,能扩充C语言功效自定义函数自己编写函数包装后,也可成为函数库,供他人使用第8页函数定义两种形式[类型]函数名([形式参数表])形式参数说明{函数体[return()]}1、传统格调(1)有参函数(传统格调、当代格调)
intmax(x,y)intx,y;{intz;z=x>y?x:y;return(z);
}
第9页[类型]函数名([类型参数1,类型参数2,….]){函数体;[return表示式;]}2、当代格调(ANSI新标准,当前惯用)
intmax(intx,inty){intz;z=x>y?x:y;return(z);
}
第10页函数定义(definition)类型函数名(类型参数1,类型参数2,……)
{
函数体;
return
表示式;
}返回值类型标识符参数表返回值函数出口第11页类型标识符函数名(){说明部分语句}无参数传递(2)无参函数比如:voidprintstar(){printf(“***”);}第12页1、函数名前面类型实际上是返回值类型当函数无返回值时,可用void
定义为“无类型”或“空类型”。当函数有返回值时,必须定义函数类型,并一定有return语句说明:例:voidprintstar(){printf(“***”);}第13页2、若为无参函数,则形参列表为空,但括号不能省略。见上例3、若为有参函数,则必须有形参表及形参说明。第14页4、形参说明两种形式:如:下面对形式参数说明都是错误:(1)max(x,y)(2)main(intx,y)intx;intmax(x,y)intx,y;注意两种形式差异!!!
intmax(intx,inty)或第15页intmax(x,y)intx,y;
{intz;
z=x>y?x:y;return(z);}如:intmax(int
x,inty)
{intz;
z=x>y?x:y;return(z);}5、形参说明与函数体内说明一定要分别说明。第16页函数类型
函数定义时应该指定函数类型,应该与return语句类型一致。假如函数类型和return语句类型不一致,以函数类型为准。对数值型数据,能够自动进行类型转换。既函数类型决定返回值类型。凡不加类型说明函数,一律自动按整型处理。假如函数不返回值,能够将函数定义为“无类型”void。比如voidprintstar()第17页函数返回值1、函数返回值是经过函数中return语句取得,return语句将被调函数一个确定值带回主调函数中去。
若无值返回可省略return语句或只用return。2、返回值表示式类型应与定义函数类型相一致。语法:return(返回值表示式);第18页3、函数值与返回值类型不一样,则以函数类型为准。4、一个函数中允许有多个return语句,程序执行到哪个return语句,哪个语句起作用。5、return语句后面括弧能够不要,比如returnz;6、main()函数向调用进程(普通是操作系统)返回一个整数。第19页关于函数函数是这么一个运算:函数名说明运算规则参数是运算操作数返回值是运算结果当函数执行到return语句或}时,函数运算停顿。返回到调用它地方继续向下执行函数能够有多个return,但最好只有一个且是最终一行第20页
用void定义返回值类型函数没有运算结果,没有返回值return语句之后不需要任何表示式
用void定义参数,表示没有参数函数内部能够定义只能自己使用变量,称内部变量。参数表里参数(形式参数)也是函数语句块内变量关于函数第21页函数名命名规则在Linux/Unix平台习惯用function_name
本书采取Windows格调函数名命名用大写字母开头、大小写混排单词组合而成FunctionName
变量名形式“名词”或者“形容词+名词”如变量名oldValue与newValue等函数名形式“动词”或者“动词+名词”(动宾词组)如函数名GetMax()等第22页对函数接口加以注释说明/*函数功效:实现××××功效函数参数:参数1,表示×××××参数2,表示×××××
函数返回值:×××××*/返回值类型函数名(参数表){
函数体
return
表示式;}第23页例:计算两个整数平均数/*
函数功效:计算平均数函数入口参数:整型x,存放第一个运算数整型y,存放第二个运算数函数返回值:平均数*/intAverage(intx,inty){
intresult; result=(x+y)/2;
returnresult;}第24页形式参数和实际参数形式参数:在定义函数时函数名后面括弧中变量名,简称形参。实际参数:在调用函数时函数名后面括弧中表示式,简称实参。函数参数第25页
例
main()max(intx,inty)
{{intz;inta,b,c;z=x>y?x:y;scanf(“%d,%d”,&a,&b);return(z);
c=max(a,b);
}printf(“Maxis%d”,c);}运行结果:7,8Maxis8
第26页参数传递——单向值传递值传递——函数参数为基本数据类型时地址传递
——函数参数为数组名、指针类型时第27页单向值传递调用函数时,必须提供全部参数printf和scanf是采取变长变量表定义函数,所以变量个数不固定。提供参数个数、类型、次序应与定义时相同第28页在函数调用前,形参不占内存单元,调用时占用,调用后释放。形参变量和实参变量占用不一样内存单元(传值)定义函数时,必须指定形参类型。实参必须有确定值,能够是常量,变量或表示式。在调用时将实参值赋给形参变量。关于参数几点说明:形参和实参区分——第29页实参加形参应匹配(次序、类型、个数)实参对形参数据传递若是单向传递,只由实参传递给形参,调用结束后,只有形参单元被释放,实参单元中值不变。若是地址传递,可了解为实参加形参共用同一存放单元。(这一点在学习数组、指针时请注意听)。形参和实参区分——第30页
c=max(a,b);-----------------------max(intx,inty){……returu(z);}
实参:在运行时把值传给函数形参:通知系统要预留内存位置把函数结果赋给函数名形参加实参、函数名与返回值之间关系第31页函数调用(call)函数名(表示式1,表示式2,……);调用一个函数之前,先要对其返回值类型、函数名和参数进行申明(declare)不对函数进行申明是非常危险函数定义也有申明函数效果调用函数时,提供表示式(叫实际参数,argument)和该函数形式参数必须匹配数目一致类型一一对应(会发生自动类型转换)表示式值赋值给对应参数返回值能够按需处理realeql.c第32页第33页函数调用普通形式1.函数调用普通形式为:
有参函数:函数名(实参表列);
无参函数:函数名();2.相关要求:多个实参间用逗号隔开实参加形参间个数相等,类型应一致实参加形参按次序对应,一一传递数据函数调用(CALL)第34页1.函数语句:
把函数调用作为一个语句。此时不要求函数带回值,只要求函数完成一定操作。
比如:printstar();max(a,b)2.函数表示式:
函数出现在一个表示式中,这种表示式称为函数表示式。这时要求函数带回一个确定值以参加表示式运算。
比如:c=3+max(a,b);3.函数参数:(函数嵌套调用)函数调用作为一个函数实参。比如:m=max(a,max(b,c));函数调用方式第35页
函数嵌套调用
嵌套调用:在调用一个函数过程中,又调用另一个函数。函数是相互平行,C语言要求函数不能嵌套定义,但能够嵌套调用。第36页main函数调用A函数结束A函数调用B函数B函数192873456两层嵌套示意图第37页函数每次执行都会建立一个全新独立环境为函数每个变量(包含形式参数)分配内存把实际参数值复制给形式参数开始执行函数内第一条语句函数内代码在这个独立环境内工作函数退出时求出返回值,将其存入一个能够被调用者访问地方(x86中通常使用EAX存放器)收回分配给全部变量(包含形式参数)内存程序控制权交给调用者,调用者拿到返回值,将其作为函数调用表示式结果函数调用过程第38页main()C语言允许不对函数参数和返回值类型进行说明甚至能够连函数名都不申明此时默认该函数参数是不定个数int型该函数返回值为int型永远不要利用此特征!printf()、scanf()变长参数表,<stdarg.h>缺点:对参数类型和个数无法严格验证,易使用犯错main()、printf()和scanf()特殊吗?第39页使用函数要注意每个函数只完成一个功效(包含main())对函数功效能够用不含连词一句话描述函数不能过长1986年IBM研究结果:大多数有错误函数都大于500行1991年研究表明:小于143行函数比更长函数更轻易维护函数一定要对传进来非法参数做点什么向调用者提供错误信息assert()safediv.c第40页调用自定义函数之前,应该在主调函数中说明被调函数类型。函数说明(函数原型说明)
在主函数中对被调函数作类型说明,意在告诉编译系统,本函数中将要用到某函数是什么类型,方便让编译系统作出对应处理。函数说明普通形式为:
类型函数名();注意:函数类型说明是函数调用中一个非常主要步骤,忽略它将造成程序编译时犯错。第41页
例7:调用函数求n!。main(){intnum;longt;longf();/*函数类型说明*/scanf("%d",&num);t=f(num);/*函数调用*/printf("%d!=%1d",num,t);}longf(n)/*定义f函数,其功效是求n!*/intn;{inti;longa=1;/*变量a存放阶乘*/for(i=1;i<=n;i++)/*求阶乘*/a*=i;return(a);}/*返回a值*/第42页函数定义与函数说明区分
函数定义是指函数功效确实立,包含指定函数名、函数类型、形参及其类型、函数体等。它是一个完整、独立单位函数说明是对函数名、函数返回值类型、形参类型说明,不包含形参和函数体。函数说明只起到一个申明作用。第43页下面几个情况除外,能够不作函数说明:(1)被调函数返回值是int时(2)被调函数定义出现在主调函数之前时如:①被调函数在主调函数之后,需说明
main(){longf();……t=f();…….}longf(intx,inty){…….}第44页②被调函数在主调函数之前已定义,不需说明longf(intx,inty){}main(){t=f(a,b);}第45页(3)在源程序开头,在全部函数定义之前已说明了函数类型floata();main(){………a(c,d);……..}floata(intx,inty){……..}如:第46页用函数完成此题编程先由计算机“想”一个1到100之间数请人猜,假如人猜对了,则计算机给出提醒:“Right!”,不然提醒:“Wrong!”,并告诉人所猜数是大(Toohigh)还是小(Toolow),最多能够猜10次。假如猜了10次仍未猜中话,则停顿此次猜数,然后继续猜下一个数。每次运行程序能够重复猜多个数,直到操作者想停顿时才结束。第47页框架流程开始结束初始化退出主功效为程序运行所作准备工作程序主体功效在退出前要做事情,比如资源释放第48页主功效猜数字开始结束生成数字猜数字是否继续?NY开始结束猜得对吗?NY提醒大小次数==10?输入数字YN第49页§4.2变量作用域和存放类
1、定义语句出现位置——作用域问题2、变量值存在时间长短(是否保留变量)——生存期问题变量必须先定义,后使用。另外,还包括到以下问题:第50页一、变量作用域
全局变量局部变量变量作用域:在程序中定义变量位置及能被访问范围。第51页局部变量在语句块内定义变量形参也是局部变量特点定义时不会自动初始化,除非程序员指定初值进入语句块时取得内存,仅能由语句块内语句访问,退出语句块时释放内存,不再有效并列语句块各自定义同名变量互不干扰
局部变量第52页1、局部变量:在函数内部或复合语句内定义变量称为~。(离开该范围,其值就不能再引用,即含有局部性)intf1(inta,intb){int
m;m=a*b;return(m);}例:在函数内部m为局部变量,形参a,b也是局部变量,只在函数f1()中有效。随函数f1()建立而建立,并随其消亡而消亡。第53页main(){intx=10;if(x==10){char
s=‘a’;printf(“%c\n",s);}printf(“%d\n",x);}在复合语句内例:
s为局部变量,只在if语句块中有效局部变量s在if入口处建立,在出口处消亡第54页说明:①局部变量只在定义它函数内有效,即在此函数之外是不能使用这些局部变量。(main()一样)
main(){inta;a=10;f();}f(){intb;b=a*a;/*变量a只在主函数内有效*/
printf(“%d”,b);}第55页③能够在任何复合语句中定义局部变量。
④
形参也是局部变量如:main(){inta=10;f();printf("main():a=%d\n",a);}f(){inta=20;printf("f():a=%d\n",a);}②不一样函数中定义局部变量允许取相同变量名。
运行结果:f():a=20main():a=10第56页在全部函数之外定义变量是全局变量,在定义它位置以后都有效全局变量自动初始化为0全局变量使函数之间数据交换更轻易,效率也高一些不过不推荐使用,甚至禁止使用程序任何部分都能够改写全局变量,极难确定在程序哪里改写了它,程序结构混乱不得不用时候(这种情况比较少见),要严格控制对它改写全局变量(GlobalVariable)第57页2、全局变量(/外部变量):在全部函数之外定义变量有效范围是:从定义变量位置开始到根源程序结束
比如:inta,b;main(){………}intx,y;f(){……….}全局变量a、b作用范围全局变量x,y作用范围第58页说明:1、同一源文件中全部函数都能够引用全局变量值。在一个函数中对全局变量修改会影响到其它函数。例:#include<stdio.h>
intn=100;voidde(){n-=10;}main(){for(;n>=60;){de();
n-=10;printf(“n=%d\n”,n);}}运行结果:n=80n=60n=40第59页2、若全局变量在文件开头定义,则整个文件范围内都能够使用该全局变量而无须进行变量说明;(见上例)
假如不在文件开头定义,按要求其作用域只限于定义点到文件终了。若定义点之前函数想引用该全局变量,则必须在该函数内用关键字extern做“外部变量说明”。格式:extern类型名变量名第60页
max(intx,inty){intz;z=x>y?x:y;return(z);}main(){extern
inta,b;/*外部变量说明*/
printf(“Maxis%d”,max(a,b));}inta=3,b=8;
/*外部变量定义*/
例:第61页外部变量定义与外部变量说明区分:1、外部变量定义只能有一次,它位置在全部函数之外;在同一文件中外部变量说明能够有屡次,它位置在函数之内(即哪个函数要用,就在哪个函数中说明)2、系统依据外部变量定义(而不是依据外部变量说明)分配存放单元,对外部变量初始化只能在“定义”时进行,而不能在“说明”中进行。3、对外部变量说明只是申明该变量是一个已在外部定义过变量,仅仅是为了引用该变量而做“申明”第62页3、全局变量能够与局部变量同名。在局部变量作用范围内,全局变量不起作用。
例:#include<stdio.h>
intm=10,n=100;voidde(){intn=100;
n-=20;
m-=2;}
main()
{intn=80;
for(;n>=60;){de();
n=n-20;
printf(“%d\n”,n+m);
}}运行结果:6846de()函数中局部变量n作用域main()中局部变量n作用域全局变量m,n作用域第63页例5.7#include<stdio.h>intglobal; /*定义全局变量*/voidGlobalPlusPlus(void);main(){ global=1;
printf("BeforeGlobalPlusPlus(),itis%d\n",global); GlobalPlusPlus();
printf("AfterGlobalPlusPlus(),itis%d\n",global);}/*函数功效:对全局变量global加1,并打印加1之前与之后值函数入口参数:无函数返回值:无*/voidGlobalPlusPlus(void){
printf("Before++,itis%d\n",global); global++;
printf("After++,itis%d\n",global);}BeforeGlobalPlusPlus(),itis1Before++,itis1After++,itis2AfterGlobalPlusPlus(),itis2第64页例5.8#include<stdio.h>
voidGlobalPlusPlus(void);main(){
intglobal=1;
printf("BeforeGlobalPlusPlus(),itis%d\n",global); GlobalPlusPlus();
printf("AfterGlobalPlusPlus(),itis%d\n",global);}/*函数功效:对局部变量global加1,并打印加1之前与之后值函数入口参数:无函数返回值:无*/voidGlobalPlusPlus(void){
intglobal=1;
printf("Before++,itis%d\n",global); global++;
printf("After++,itis%d\n",global);}BeforeGlobalPlusPlus(),itis1Before++,itis1After++,itis2AfterGlobalPlusPlus(),itis1第65页变量存放类型指数据在内存中存放方式即编译器为变量分配内存方式,它决定变量生存期动态存放依据需要暂时分配存放空间,离开即释放静态存放在程序运行期间分配固定存放空间不释放程序区静态存放区动态存放区形参、自动变量、函数调用现场等全局变量、静态变量第66页二、变量存放类(从生存期角度来描述变量)C语言中每个变量和函数都有两个属性——
数据类型和数据存放类别数据类型:如整型、字符型、浮点型等数据存放类别:数据在内存中存放方式(静态存放方式、动态存放方式)存放类型说明符数据类型说明符变量名表;所以,变量说明完整形式为:
第67页静态存放——程序开始执行时分配固定存放单元(位于静态存放区),直到程序执行完成才释放所占存放单元。动态存放——程序运行期间按照需要暂时分配存放单元(位于动态存放区),使用结束马上释放所占存放单元。变量存放方式(变量生存期)分为:第68页
auto自动变量——动态存放区
register存放器变量——CPU中存放器
extern外部变量——静态存放区
static静态变量——静态存放区存放类型程序区静态存放区动态存放区形参、自动变量、函数调用现场等全局变量、静态变量存放数据第69页局部变量存放方式(三种)自动变量静态局部变量存放器变量第70页“自动”表达在进入语句块时自动申请内存,退出时自动释放内存对它们分配和释放存放空间工作由编译系统自动处理,故称其为自动变量标准定义格式auto类型名变量名;动态局部变量缺省存放类型不初始化时,值是不确定1、自动变量(auto)第71页例:
intf(inta)/*形参a为自动变量,auto省略*/{autointb,c=3;/*定义b,c为自动变量*/……}第72页2、静态局部变量:有时希望函数中局部变量值在函数调用结束后不消失(以后一直存在,并总是保持它最新值,即含有记忆性。)即不释放存放单元。此时可指定该变量为“静态局部变量”,用关键字“static”说明。静态局部变量系统自动初始化为0。存放在静态存放区中第73页静态变量和全局变量都是静态存放类型自动初始化为0从静态存放区分配,生存期为整个程序运行期间但作用域不一样第74页例:f(inta){autointb=0;
staticintc=3;/*定义静态局部变量c*/b=b+1;c=c+1;return(a+b+c);}main(){inta=2,i;for(i=0;i<3;i++)printf(“%d”,f(a));}运行结果为:789第75页例5.9#include<stdio.h>voidFunc(void);main(){
inti;
for(i=0;i<10;i++) { Func(); }}/*函数功效:打印被调用次数
函数入口参数:无函数返回值:无*/voidFunc(void){
inttimes=1; /*自动变量*/
printf("Func()wascalled%dtime(s).\n",times++);}Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).
第76页例5.9#include<stdio.h>voidFunc(void);main(){
inti;
for(i=0;i<10;i++) { Func(); }}/*函数功效:打印被调用次数
函数入口参数:无函数返回值:无*/voidFunc(void){
static
inttimes=1; /*静态局部变量*/
printf("Func()wascalled%dtime(s).\n",times++);}Func()wascalled1time(s).Func()wascalled2time(s).Func()wascalled3time(s).Func()wascalled4time(s).Func()wascalled5time(s).Func()wascalled6time(s).Func()wascalled7time(s).Func()wascalled8time(s).Func()wascalled9time(s).Func()wascalled10time(s).
第77页对频繁使用变量,为降低存取变量花费时间,C语言允许将局部变量值存放在CPU运算器存放器中,称为“存放器变量”,用关键字“register”说明。3、存放器变量(register)第78页说明:存放器变量类型普通只限于整型、字符型或指向整型、字符型指针,且只用于局部变量和形参。所以,全局存放器变量是非法。
不能定义任意多个存放器变量,因为一个计算机系统中存放器数目是有限。不能取存放器变量地址存放器变量(register)第79页存放器变量(register)当代编译器有能力自动把普通变量优化为存放器变量,而且能够忽略用户指定,所以普通无需尤其申明变量为register如:registerstaticinta,b,c;
因为变量a,b,c不能既放在静态存放区中,又放在存放器中局部静态变量不能定义为存放器变量。第80页局部变量(按存放方式分)静态局部变量(用static申明)动态局部变量含有动态性:随本过程建立而建立,随本过程结束而消亡;再次执行本过程时再重新建立。含有局部性:只在本过程中有效。即仅能被定义它代码块中语句访问,在此代码块之外是不可知。动态局部变量:(放在动态存放区)含有静态性:第一次执行本过程时建立,以后一直存在,并总是保持它最新值。含有局部性:只在本过程中有效静态局部变量:(放在静态存放区)局部变量小结、存放器变量(register)第81页存放器变量:(放在CPU里存放器中)普通只限于整型、字符型或指向整型、字符型指针,不能取存放器变量地址含有动态性:随本过程建立而建立,随本过程结束而消亡;再次执行本过程时再重新建立。含有局部性:只在本过程中有效。即仅能被定义它代码块中语句访问,在此代码块之外是不可知。第82页全局变量存放方式全局变量在编译时分配在静态存放区。全局变量能够:被本文件中函数引用也能够被其它文件中函数引用第83页1、允许其它文件中函数引用。假如在一个文件中要引用在另一个文件中定义全局变量,应该在需要引用它文件中全部函数外部用“extern”说明。第84页文件file1.c内容为:
inta;main(){intpower();intb=3,c,d,m;printf(“enteraanditspower:\n”);scanf(“%d,%d”,&a,&b);c=a*b;printf(“%d*%d=%d\n”,a,b,c);d=power(m);printf(“%d^%d”=%d”,a,m,d);文件file2.c内容为:
externinta;power(intn){intI,y=1;for(i=1;i<=n;i++)y*=a;return(y);}第85页2、只被本文件中函数引用。
若希望一些全局变量只限于被本文件引用而不能被其它文件引用,能够在定义外部变量时前面加一个static说明。静态外部变量系统自动初始化为0。staticinta;Main(){…..}externinta;fun(intn){…..a=a*n;…….}file1.cfile2.c注:在file1.c中定义了一个全局变量a,但它有static说明,所以只能用于本文件,即使在文件file2.c中用了“externinta”,但文件file2.c无法使用file1.c中全局变量a。第86页存放类别小结
对一个数据定义,需要指定两种属性:数据类型和存放类别,分别用两个关键字定义。如:staticinta;(静态内部变量或静态外部变量)
autocharc;(自动变量,在函数内部定义)
registerintd;(存放器变量,在函数内部定义)对外部变量说明时,能够用extern,说明为已定义外部变量
externintb;(说明b为一个已定义外部变量)第87页从不一样角度对存放类别归纳1、从作用域角度分,有局部变量和全局变量,它们采取存放类别是:局部变量
自动变量,即动态局部变量(离开函数,值就消失)静态局部变量(离开函数,值仍保留)存放器变量(离开函数,值就消失)(形式参数能够定义为自动变量或存放器变量)全局变量静态外部变量(只限本文件使用)
外部变量
(即非静态外部变量,允许其它文件引用)第88页2、从变量存在时间来分,有动态存放和静态存放两种类型。静态存放是程序整个运行期间都存在,而动态存放则是在调用函数时暂时分配存放单元。动态存放
自动变量
(本函数内有效)存放器变量(本函数内有效)
形式参数
静态存放静态局部变量(函数内有效)
外部变量
(其它文件可引用)静态外部变量(本文件内有效)第89页3、从变量值存放位置来区分,可分为:1.内存中静态存放区静态局部变量(函数内有效)
外部变量(其它文件可引用)静态外部变量(本文件内有效)2.内存中动态存放区:3.CPU中存放器:自动变量和形式参数存放器变量第90页对局部变量来说,static使变量由动态存放方式改为静态存放方式。对全局变量来说,static使变量局部化(局部于本文件),但仍为静态存放方式。从作用域角度看,凡有static说明,其作用域都是局限,或者是局限于本函数内(静态局部变量),或者局限于本文件内(静态外部变量)4、static对局部变量和全局变量作用不一样。第91页全局变量静态外部变量
(只限本文件使用)外部变量
(即非静态外部变量,允许其它文件引用)局部变量
自动变量,(离开函数,值就消失)存放器变量(离开函数,值就消失)(形式参数能够定义为自动变量或寄存器变量)定义点之前使用,需用extern申明静态局部变量(离开函数,值仍保留)动态局部变量第92页递归(Recursion)函数直接或间接调用自己为递归unsigned
intfunc(unsigned
intn)
{
if(n==0)
return1;
else
returnn*func(n-1);
}recur.c第93页模块包含两部分源文件(xxx.c):一系列相关函数定义头文件(xxx.h):这些函数申明等必要信息函数申明、外部变量申明、宏定义、类型定义……能够将模块编译为.obj文件,同.h文件一起供他人使用,从而保护了源代码使用模块过程建立一个工程(project)把各模块都加入到工程中#include模块头文件开始使用此模块模块第94页编写模块技术模块信息隐藏用static定义函数和全局变量只在此模块内有效(提议采取)允许被其它模块使用全局变量在源文件中定义,不加static修饰在头文件中进行申明,加extern修饰第95页*模块化程序设计方法功效分解自顶向下、逐步求精过程模块分解标准确保模块相对独立性高聚合、低耦合模块实现细节对外不可见外部:关心做什么内部:关心怎么做设计好模块接口接口是指罗列出一个模块全部与外部打交道变量等定义好后不要轻易改动在模块开头(文件开头)进行函数申明第96页*函数设计标准函数功效要单一,不要设计多用途函数函数规模要小,尽可能控制在50行代码以内1986年IBM在OS/360研究结果:大多数有错误函数都大于500行1991年对148,000行代码研究表明:小于143行函数比更长函数更轻易维护参数和返回值规则参数要书写完整,不要省略对函数入口参数进行有效性检验没有参数和返回值时,用void填充每个函数只有一个入口和一个出口,尽可能不使用全局变量尽可能少用静态局部变量,以防止使函数含有“记忆”功效第97页模块和链接将一个程序分解成若干个模块,分别放在几个源文件中,形成一个项目文件(.prj)(Project)然后,对每一个源文件(.c)分别单独进行编译再将它们目标代码(.obj)连同标准函数库中函数链接在一起,形成可执行文件(.exe)。模块之间经过相互调用函数联络起来头文件(.h)是联络纽带
第98页模块和链接优点:当一个文件代码被修改后,无须对全部程序重新编译,从而节约了程序编译时间。使程序更宜于维护,给多个程序员共同编制一个大型项目标代码提供了方便伎俩。第99页模块和链接例5.10能够不看将习题5.5修改成1个.h头文件(X5-5-1.h)2个.c源文件(X5-5-1.c,X5-5.c)1个.prj项目文件(X5-5.prj)由全部源程序文件组成X5-5-1.CX5-5.C参见试验指导书第133页第100页编译器在开始正式编译之前处理指令,叫预编译指令它们不会存在于最终生成目标代码中文件包含:#include用#include指定文件内容替换#include所在行用<>或者""括上文件名<>表示在编译器include目录内查找文件""表示在当前目录查找文件文件名中能够带有路径预
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度医药产品研发合作合同:新药研发与专利共享2篇
- 雷达基本工作原理课件
- 2024年度知识产权许可合同:专利技术使用权授权及费用支付2篇
- 2024年度人力资源外包服务合同标的:员工招聘与培训
- 2024年度企业物联网应用咨询与实施合同
- 某煤矿集团火力发电厂01-综合管理制度汇编(修改稿)
- 2024年度网络技术服务合同标的为网络系统的设计、实施及维护
- 2024年度工程建设委托管理合同
- 高中地理《地球的运动》课件中图版必修课件
- 《审计决定审理》课件
- 公安派出所建筑外观形象设计规范1
- 施工劳务承包合同精简版2页
- 分管教学副校长在期中质量分析会上的发言教学文稿
- AI表面质量检测系统产品介绍PPT课件
- 预缴税款的申报表(doc 2页)
- 餐饮服务单位(食堂)餐厨废弃物(泔水)处理记录台账
- 青少年特发性脊柱侧弯症中医诊疗方案4
- 研发系统积分考核管理办法
- 食品安全自查表格模板
- 加热装配计算
- 北师大版四年级数学上册第七单元教材分析
评论
0/150
提交评论