B函数与程序结构_第1页
B函数与程序结构_第2页
B函数与程序结构_第3页
B函数与程序结构_第4页
B函数与程序结构_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

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

文档简介

第5章函数与程序结构(B)主要内容局部变量,全局变量静态变量变量的存储类型变量的作用域变量的生命期变量的可见性编译预处理头文件与多文件结构小结与作业变量在内存中的存放程序员对变量的使用2课件制作5.11局部变量和全局变量程序的运行和数据的访问程序开始运行和运行结束时占用的内存程序运行时占用的内存BootLoader3课件制作5.11局部变量和全局变量程序的内存区域代码区(codearea)全局数据区(dataarea)堆区(heaparea)栈区(stackarea)程序中各个函数代码块存放程序的全局数据和静态数据存放程序的动态数据存放程序的局部数据即各个函数中的数据4课件制作5.11局部变量和全局变量局部变量(localvariable)函数内部定义的变量,只在本函数范围内有效复合语句({}括起的语句

)中定义的变量,只在本复合语句范围内有效floatf1(inta)//函数f1{

inti1,i2;┆floatb,c; ┆returnb;}b、c有效a有效intmain()//主函数{

intm,n;┆

{

int

p,q; ┆

}returnn;}p、q有效域m、n有效5课件制作5.11局部变量和全局变量局部变量(localvariable)局部变量如果没有显式初始化其内容是不可预料的,即变量必须在使用之前声明一个局部变量的作用域从它的声明开始,直至包含它的程序块结束可以在一个函数内的复合语句中定义变量,这些变量只在本复合语句中有效,这种复合语句也称为分程序或程序块形式参数也是局部变量,参数的作用域覆盖整个函数不同函数中可以使用同名的变量,它们代表不同的对象,互不干扰函数中的局部变量存放在栈区6课件制作5.11局部变量和全局变量#include<iostream>usingnamespacestd;inlineint

square(inti){returni*i;}intmain(){

inti=0;i=square(i);

for(;i<3;i++){

intj=1;j+=square(j);

cout<<j<<",";}

cout<<endl;

cout<<"j的值为"<<j<<endl;

cout<<"i的值为"<<i<<endl;return0;}main函数中定义了变量i,在square函数中也定义变量i,它们在内存中占不同的单元,不会混淆square函数中的形参i也只在square函数中有效,其他函数不能调用复合语句中的变量只在复合语句内有效7课件制作5.11局部变量和全局变量voidfnFunction(){intx=1;inty=1;for(inti=1;i<10;i++){

intj=i+1;x+=i;}for(i=1;i<10;i++){

intj=i+1;y+=j;}cout<<i<<endl;cout<<j<<endl;return;}i作用域

j作用域

j作用域教材P123图5_7有误8课件制作5.11局部变量和全局变量全局变量,也称全程变量(globalvariable)在函数之外定义的变量全局变量的有效范围为从定义变量的位置开始到本源文件结束全局变量的默认值:数值变量是0,字符变量为空格9课件制作5.11局部变量和全局变量intp=1,q=5;//全局变量

floatf1(floata)//定义函数f1{

intb,c;┆}charc1,c2;//全局变量

charf2(intx,inty)//定义函数f2{

inti,j;┆}intmain()//主函数{

intm,n;┆}全局变量c1、c2的作用范围全局变量p、q的作用范围10课件制作5.11局部变量和全局变量全局变量如果在同一个源文件中,全局变量与局部变量同名,则在局部变量的作用范围内,全局变量被屏蔽,即它不起作用;此时若要使用全局变量,可通过一元作用域解析运算符::

访问全局变量,参见P122示例设全局变量的作用是增加函数间数据联系的渠道建议不在必要时不要使用全局变量全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元在执行函数时要受到外部变量的影响,使函数的通用性降低,难于移植使用全局变量过多,会降低程序的清晰性。在各个函数执行时都可能改变全局变量的值,程序容易出错11课件制作5.12静态局部变量在局部变量前使用关键字static修饰,该变量即成为静态局部变量,如staticinta;静态局部变量存放在内存的全局数据区,在程序整个运行期间都不释放静态局部变量赋初值是在编译时分配值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值若在定义静态局部变量时不赋初值,编译时自动赋初值0(对数值型变量)或空字符(对字符型变量)静态局部变量在其他函数是不能引用它的,即在其他函数中它是“不可见”的12课件制作5.12静态局部变量#include<iostream>usingnamespacestd;int

f(inta)//定义f函数,a为形参{

intb=0;//定义b为自动变量

staticintc=3;//定义c为静态局部变量

b=b+1;c=c+1;returna+b+c;}intmain(){

int

i,a=2;

for(i=0;i<3;i++)

cout<<f(a)<<",";

cout<<endl;return0;}13课件制作5.12静态局部变量实例:输出1~5的阶乘值(即1!,2!,3!,4!,5!)。#include<iostream>usingnamespacestd;int

fac(int);//函数声明intmain(){

inti;

for(i=1;i<=5;i++)

cout<<i<<"!="<<fac(i)<<endl;return0;}int

fac(intn){

staticintf=1;//f为静态局部变量,函数结束时f的值不释放

f=f*n;//在f原值基础上乘以nreturnf;}运行结果为1!=12!=23!=64!=245!=120每次调用fac(i),就输入一个i,同时保留这个i!的值,以便下次再乘(i+1)14课件制作5.12静态局部变量如果初始化后,变量只被引用而不改变其值,则这时用静态局部变量比较方便,以免每次调用时重新赋值用静态存储要多占内存,而且降低了程序的可读性,当调用次数多时往往弄不清静态局部变量的当前值是什么尽可能少用静态局部变量intmain(){

inti=0;i=square(i);

for(;i<3;i++){

staticinti=1;i+=square(i);

cout<<i+a<<",";}

cout<<i<<endl;return0;}#include<iostream>usingnamespacestd;inta=8;//inlineint

square(inti){returni*i;}思考题:该题运行结果?staticintk=1;k+=squre(k);cout<<k+a<<",";15课件制作5.13存储类型存储类型指的是数据在内存中存储的方法存储方法分为动态存储和静态存储两大类动态存储自动的(auto)、寄存器的(register)外部的(extern)静态存储静态的(static)16课件制作5.13存储类型自动存储自动变量用关键字auto作存储类别的声明存储类别auto和数据类型int

的顺序一般auto在前关键字auto可以省略,系统把它默认为自动存储类别程序中大多数变量属于自动变量int

f(inta)//定义f函数,a为形参{autoint

b,c=3;//定义b和c为整型的自动变量┆}17课件制作5.13存储类型寄存器存储只适用于变量变量前加register修饰,如registerinta;当今的优化编译系统能够识别使用频繁的变量,自动地将这些变量放在寄存器中外部存储:由多个文件构成的一个程序,在一个文件中需要使用另一文件定义的函数或全局变量,需要在使用前用关键字extern

进行声明18课件制作5.13存储类型//文件CH5_41.cpp#include<iostream>usingnamespacestd;voidfn1();//函数原型声明externvoidfn2();//外部函数原型声明intn;//全局变量声明intmain(){n=3;fn1();

cout<<n<<endl;return0;}voidfn1(){fn2();}//文件CH5_42.cpp//外部变量声明extern

intn;externvoidfn1();//函数fn2定义voidfn2(){n=8;}19课件制作5.13存储类型外部存储带extern的变量说明是变量声明,不是变量定义默认的函数声明或定义总是extern存储所有函数的声明一般都放在源文件的开始位置若共同的变量在各个文件中分别定义,或者声明的类型不一致,都会造成直接或间接错误20课件制作5.13存储类型静态存储静态局部变量静态全局变量在全局变量前用static修饰,使变量只在该源文件中可用,称之为全局静态变量,又称静态全局变量在多文件组成的程序中,静态全局变量使得该变量成为定义该变量的源文件所独享静态全局变量对组成该程序的其他源文件是无效的静态函数在函数定义返回值类型前加static形成静态函数,如staticintfn(){……};静态函数使得该函数只在一个源文件中有效,不能被其他源文件所使用解决不同源文件中使用同名函数发生冲突21课件制作5.14作用域含义:变量的有效范围C++的作用域范围分为:局部作用域(块作用域)、函数作用域、函数原型作用域和类作用域作用域开始于标识符的声明处局部作用域当标识符的声明出现在由一对花括号括起来的一段程序(块)内时,该标识符的作用域从声明点开始,到块结束处为止,该作用域的范围具有局部性语句是一个程序单位,如在if语句和switch语句中进行条件测试的表达式中声明标识符,则该标识符的作用域在该语句内22课件制作5.14作用域//CH5_5#include<iostream>usingnamespacestd;intmain(){

intn;

cout<<"Plsinputn:";

cin>>n;if(n>5)

inti=2*n;

//i作用域{inti=2*n;}else

doublef=n/2.0;//f作用域{doublef=n/2.0;}

cout<<n<<endl;

cout<<i<<endl;//?

cout<<f<<endl;//?return0;}//CH5_5#include<iostream.h>intmain(){

int

i,n=0;

for(i=0;i<10;i++){

floatn2;if(i%2==1)n++;}n2=n/2;//?n=i;return0;}23课件制作5.14作用域函数作用域:goto语句函数原型作用域:参数声明仅限于原型声明的括号内文件作用域:在所有函数定义之外进行说明,其作用域从说明点开始一直到源文件结束全局变量是文件作用域的,静态函数也是文件作用域,文件作用域是全局的在头文件的文件作用域所进行的声明,若该文件被另一源文件所包含,则声明的作用域也扩展到该源文件中直到源文件结束24课件制作5.14作用域//文件CH5_41.cpp#include<iostream>usingnamespacestd;voidfn1();//函数原型声明externvoidfn2();//外部函数原型声明intn;//全局变量声明intmain(){n=3;fn1();

cout<<n<<endl;return0;}voidfn1(){fn2();}//文件CH5_42.cpp#include"MyLib.h"//外部变量声明extern

intn;externvoidfn1();//函数fn2定义voidfn2(){n=8;}//文件MyLib.hbool

bIsLeapYear(intyear);bool

bIsOdd(intnum);int

fnGetMax(intx,inty,intz);25课件制作5.15生命期与可见性生命期定义:又称生存期,与存储区域密切相关,分为静态生命期、局部生命期和动态生命期静态生命期与程序的运行期相同在固定的数据区(代码区、数据区)中分配空间全局变量、静态变量、具有文件作用域的变量、函数静态生命期的变量,若无显式初始化则自动初始化为0(数字)或空格(字符)局部生命期函数内部声明的变量、块中声明的变量具有局部生命期的变量住在内存栈区具有局部生命期的变量若未被初始化则内容不可知26课件制作5.15生命期与可见性生命期动态生命期由程序中特定的函数(malloc()和free())或特定操作符(new和delete)来创建和释放具有动态生命期的变量住在内存的堆中可见性分析在某一位置标识符的有效性可见性与作用域是一致的标识符在某个位置可见,表示该标识符可以被引用常用于分析两个同名标识符作用域嵌套的特殊情况标识符的可见范围不超过作用域,作用域则包含可见范围若被隐藏的是全局变量,则可用一元作用域解析运算符::

来引用该全局变量27课件制作5.15生命期与可见性CH5-6:#include<iostream>usingnamespacestd;intg=1;//g为全局变量,具有静态生存期。intmain(){

staticinta;//静态局部变量,有全局寿命,局部可见。

intb=-10;//b,c为局部变量,具有动态生存期。

intc=0;

voidfnOther();//函数原型声明

cout<<"---MAIN---\n";//i:1a:0b:-10c:0

cout<<"g:"<<g<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl;c=c+8;

fnOther();

cout<<"---MAIN---\n";//I:33a:0b:-10c:8

cout<<"g:"<<g<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl;g=g+10;

fnOther();return0;}28课件制作5.15生命期与可见性voidfnOther(){

staticinta=2;staticintb;//a,b为静态局部变量,具有全局寿命,局部可见。

//只第一次进入函数时被初始化。

intc=10;//C为局部变量,具有动态生存期,

//每次进入函数时都初始化。

g=g+32;a=a+2;c=c+5;

cout<<"---OTHER---\n";

cout<<"g:"<<g<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl;b=a;//①i:33a:4b:0c:15}//②i:75a:6b:4c:15运行结果:---MAIN---

g:1

a:0b:-10c:0---OTHER---

g:33a:4b:0c:15---MAIN---

g:33

a:0b:-10c:8---OTHER---

g:75a:6b:4c:1529课件制作5.15生命期与可见性ints=0;//函数定义voidfnRefGlobal(){floats=3.0;

inta=2;

cout<<"inta="<<a<<endl;{floata=2.0;

::a=1;//a不是全局变量,引用出错

::s=1;//对全局变量s赋值1

cout<<"floata="<<a<<endl;

s=2.0;//对全局变量s赋值2.0}

cout<<"inta="<<a<<endl;

cout<<"floats="<<s<<endl;}

30课件制作5.16变量属性小结一个变量除了数据类型以外,还有3种属性存储类别:C++允许使用auto,static,register和extern4种存储类别作用域:程序中可以引用该变量的区域生命期:指变量在内存的存储期限以上3种属性是有联系的,程序设计者只能声明变量的存储类别,通过存储类别可以确定变量的作用域和生命期auto,static和register3种存储类别只能用于变量的定义语句中31课件制作5.16变量属性小结从作用域角度分,有局部变量和全局变量局部变量自动变量,即动态局部变量(离开函数,值就消失)静态局部变量(离开函数,值仍保留)寄存器变量(离开函数,值就消失)形式参数(可以定义为自动变量或寄存器变量)全局变量静态外部变量(只限本文件引用)外部变量(即非静态的外部变量,允许其他文件引用)32课件制作5.16变量属性小结从变量生命期(存在的时间)来区分,有动态存储和静态存储两种类型。静态存储是程序整个运行时间都存在,而动态存储则是在调用函数时临时分配单元动态存储自动变量(本函数内有效)寄存器变量(本函数内有效)形式参数静态存储静态局部变量(函数内有效)静态外部变量(本文件内有效)外部变量(其他文件可引用)33课件制作5.16变量属性小结从变量值存放的位置来区分,可分为内存中静态存储区静态局部变量静态外部变量(函数外部静态变量)外部变量(可为其他文件引用)内存中动态存储区:自动变量和形式参数CPU中的寄存器:寄存器变量关于作用域和存储期的概念:对一个变量的性质可以从两个方面分析,一是从变量的作用域,一是从变量值存在时间的长短,即生命期。前者是从空间的角度,后者是从时间的角度。二者有联系但不等同34课件制作5.16变量属性小结35课件制作5.16变量属性小结变量的可见性如果一个变量在某个文件或函数范围内是有效的,则称该文件或函数为该变量的作用域,在此作用域内可以引用该变量,所以又称变量在此作用域内“可见”,这种性质又称为变量的可见性自动变量和寄存器变量在函数内的可见性和存在性是一致的静态局部变量在函数外的可见性和存在性不一致静态外部变量和外部变量的可见性和存在性是一致的static声明使变量采用静态存储方式,但它对局部变量和全局变量所起的作用不同对局部变量来说,static使变量由动态存储方式改变为静态存储方式。对全局变量来说,它使变量局部化(局部于本文件),但仍为静态存储方式36课件制作5.17编译预处理目的:改进程序设计环境,提高编程效率C++提供的预处理功能主要有以下3种宏定义:#define文件包含:#include条件编译:#ifdef,#ifndef分别用宏定义命令、文件包含命令、条件编译命令来实现。为了与一般C++语句相区别,这些命令以符号“#”开头,而且末尾不包含分号预处理命令是C++统一规定的,但是它不是C++语言本身的组成部分,不能直接对它们进行编译必须正确区别预处理命令和C++语句,区别预处理和编译,才能正确使用预处理命令37课件制作5.17编译预处理宏定义指令:#define用#define命令将一个指定的标识符(即宏名)来代表一个字符串定义宏的作用一般是用一个短的名字代表一个长的字符串定义宏的一般形式为:#define

标识符字符串,如:

#definePI3.1415926

已被C++的const定义语句所代替:constfloatPI=3.1415926;用#define命令定义带参数的宏定义,已被C++的inline函数所代替

#defineMax(a,b)a>b?a:binlineint

Max(int

a,intb){returna>b?a:b;}38课件制作5.17编译预处理头文件包含指令:#include作用:一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中include命令的两种形式#include<文件名>:编译系统到系统目录中寻找要包含的文件,如果找不到,编译系统就给出出错信息#include"文件名":编译系统先在用户当前目录中寻找要包含的文件,若找不到,再按标准方式查找39课件制作5.17编译预处理头文件包含指令:#include关于C++标准库在C++编译系统中,提供了许多系统函数和宏定义,而对函数的声明则分别存放在不同的头文件中。如果要调用某一个函数,就必须用#include命令将有关的头文件包含进来新的C++标准库中的头文件一般不再包括后缀.h,例如

#include<iostream.h>//C形式的头文件

#include<iostream>//C++形式的头文件效果基本上是一样的,建议尽量用符合C++标准的形式,即在包含C++头文件时一般不用后缀如果用户自己编写头文件,可以用.h为后缀40课件制作5.17编译预处理条件编译希望程序中某一部分内容只在满足一定条件时才进行编译,也就是指定对程序中的一部分内容进行编译的条件;如果不满足这个条件,就不编译这部分内容,这就是“条件编译”。条件编译命令常用的有以下形式其他常见条件编译指令:#ifndef,#undef(1)#ifdef

标识符程序段1#else

程序段2#endif(2)#if表达式程序段1#else

程序段2#endif#if_MSC_VER>1000#pragmaonce#endif#ifdef__cplusplus#ifndef_INC_IOSTREAM#define_INC_IOSTREAM#if!defined(_WIN32)&&!defined(_MAC)#errorERROR:OnlyMacorWin32targetssupported!#endif41课件制作5.17编译预处理/****iostream.h-definitions/declarationsforiostreamclasses*Copyright(c)1990-1997,MicrosoftCorporation.Allrightsreserved.*****/#if_MSC_VER>1000#pragmaonce#endif#ifdef__cplusplus#ifndef_INC_IOSTREAM#define_INC_IOSTREAM#if!defined(_WIN32)&&!defined(_MAC)#errorERROR:OnlyMacorWin32targetssupported!#endif42课件制作5.17编译预处理输入一个字母字符,设置条件编译,使之能根据需要将小写字母改为大写字母输出或将大写字母改为小写字母输出,要求用两种形式的条件编译命令实现,即:1#ifdef

标识符 2#if表达式程序段1 程序段1#else #else

程序段2 程序段2#endif

#endif43课件制作5.17编译预处理#include<iostream>#defineLETTER

usingnamespacestd;intmain(){charch,ch1;

cout<<"请输入一字符:";

cin>>ch;

#ifdefLETTERif(ch>='a'&&ch<='z') ch1=ch-32;

#elseif(ch>='A'&&ch<='Z') ch1=ch+32;

#endif

cout<<"Yourinputis:"<<ch<<","<<ch1<<endl;return0;}

#ifdef

标识符程序段1 #else

程序段2 #endif

44课件制作5.17编译预处理#include<iostream>#defineLETTER2//1小写转大写,2大写转小写usingnamespacestd;intmain(){charch,ch1;

cout<<"请输入一字符:";

cin>>ch;

#ifLETTER>1if(ch>='a'&&ch<='z') ch1=ch-32;

#elseif(ch>='A'&&ch<='Z') ch1=ch+32;

#endif

cout<<"Yourinputis:"<<ch<<","<<ch1<<endl;return0;}#if表达式程序段1#else

程序段2 #endif

45课件制作5.18头文件与多文件结构一个较大的程序一般的做法是:把一个大的程序划分为若干个程序模块(即程序文件),每一个模块实现一部分功能,不同的程序模块可以由不同的人来完成在程序进行编译时,以程序模块为编译单位,即分别对每一个编译单位进行编译;如果发现错误,可以在本程序模块范围内查错并改正;在分别通过编译后,才进行连接,把各模块的目标文件以及系统文件连接在一起形成可执行文件在一个程序文件中可以包含若干个函数。无论把一个程序划分为多少个程序模块,只能有一个main函数,程序总是从main函数开始执行的46课件制作5.18头文件与多文件结构在程序运行过程中,由主函数调用其他函数,其他函数也可以互相调用……一个大项目程序文件程序文件……程序

温馨提示

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

评论

0/150

提交评论