第4章模块化程序设计_第1页
第4章模块化程序设计_第2页
第4章模块化程序设计_第3页
第4章模块化程序设计_第4页
第4章模块化程序设计_第5页
已阅读5页,还剩65页未读 继续免费阅读

下载本文档

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

文档简介

第4章模块化程序设计第一页,共80页。教学目标理解如何用函数构造程序模块会声明、定义和调用函数并理解函数调用的机制掌握变量的作用域和存储类别2第二页,共80页。4.1模块化程序设计概述

4.2函数的声明、定义和调用

4.3函数的多级调用

4.4变量的作用域和存储类别

4.5计算机随机模拟方法(不要求)4.6编译预处理

3第三页,共80页。复杂任务可以分解为若干子任务。重复使用的程序段,将其进行独立设计,使计算机可以重复执行。程序执行从主控程序开始、也从主控程序结束。分段设计的出发点在于一个程序模块对于某个问题的解决应保持相对的完整性。main()func1()func2()func3()func4()func5()func6()图4-1程序模块结构图4.1

模块化程序设计概述4第四页,共80页。源文件1函数n函数2函数1源文件m源文件2函数是C语言的基本构件一个C程序

一个C程序的源文件............5第五页,共80页。4.2函数的声明、定义和调用引例函数说明函数定义函数调用及参数的传递带自定义函数的程序设计6第六页,共80页。引例

/*程序名:4_1.cpp*//*功能:计算两个实数中大的值*/#include<stdio.h>floatfmax(floatx,floaty);

/*函数说明*/voidmain(){floata,b,c;scanf("%f,%f",&a,&b);c=fmax(a,b);/*函数调用*/printf("max=%f\n",c);}floatfmax(floatx,floaty)

/*函数定义*/{floatz;z=x>y?x:y;returnz;}7第七页,共80页。函数定义

函数定义的一般形式:函数返回值类型函数名(类型名形参1,类型名形参2,…)/*函数头*/{ /*函数体*/

函数实现过程}例如floatfmax(floatx,floaty){floatz;z=x>y?x:y;

returnz;}不能省略必为变量结束本函数的执行并返回函数值此处不能有分号可以没有参数8第八页,共80页。函数定义的几点说明在定义函数时不指定函数返回值类型,系统会隐含指定函数返回值类型为int型。一个函数可有多个return语句。一个return语句只能返回一个值。如果被调函数中没有return语句,函数并不是不带回值。对不返回值的函数,要使用关键字void,但可以在函数体中使用return;。即使函数没有参数,其名后的括弧也不能省。函数头与函数说明不同,函数头不是一条语句。9第九页,共80页。函数说明(函数原型)

说明格式为:

函数返回值类型函数名(参数表);

#include<stdio.h>floatfmax(floatx

,floaty);

/*函数说明*/voidmain(){floata,b,c;scanf("%f,%f",&a,&b);

c=fmax(a,b);printf("max=%f\n",c);}

函数说明是一条语句,它指出函数返回值的类型、函数的名称、函数要接收的参数的个数、顺序和类型。如果在一个函数中要调用另外一个函数,则在调用之前要对该函数进行说明。如果函数定义出现在程序中首次使用该函数之前,则不需要说明函数原型。可省略必须有分号10第十页,共80页。函数调用及参数的传递

函数调用的一般形式为:

函数名(实参表)

voidmain(){floata,b,c;scanf("%f,%f",&a,&b);

c=fmax(a,b);printf("max=%f\n",c);}可用两种方式调用函数:(1)

函数的调用可以作为表达式出现在允许表达式出现的任何地方。如:c=fmax(a,b)+3;(2)函数调用可以作为一条独立的语句。比如,有函数定义:voidprintstar(){printf(“***************”);}则可以把该函数调用作为一个独立语句。

printstar();printf(“max=%f\n”,fmax(a,b));可为常量,变量或表达式11第十一页,共80页。函数返回值

(函数值)

函数返回值的类型是由函数说明中的函数返回类型决定的。如果返回的类型与函数说明的不同,则在返回值时,先作隐含的类型转换,然后再返回。#include<stdio.h>intfmax(floatx,floaty){returnx>y?x:y;}voidmain(){intmax;floata=3.5,b=2.6;

max=fmax(a,b);

printf("max=%d\n",max);}max=3floatreturn(x>y?x:y);12第十二页,共80页。形参和实参

形式参数:定义函数时放在函数名称之后括号中的参数,简称形参。形参必须是变量。实际参数:调用函数时括号中的参数,简称实参。实参可为常量、变量或表达式。形参与实参的结合:函数调用时,将生成实参值的一个副本传递给对应的形参,这个过程称为形参与实参的结合。只允许实参向形参传递数据,则称为“单向传递”。图4-2实参和形参数据的传递3.53.52.62.6实参a实参b形参x形参y实参与形参必须一一对应,数量相同且类型一致13第十三页,共80页。函数的调用过程

#include<stdio.h>floatfmax(float,float);voidmain(){floata,b,c;scanf(“%f,%f”,&a,&b);

c=fmax(a,b);printf(“max=%f\n”,c);}floatfmax(floatx,floaty)

{floatz;z=x>y?x:y;returnz;}保存返回地址及当前现场,为形参分配内存并将实参值的副本传给形参变量恢复main函数的现场,取得返回地址和返回值14第十四页,共80页。带自定义函数的程序设计

程序设计思路:(1)定义一个函数isprime(inta)判断a是否为素数,若是素数,函数返回1,否则返回0。#include<stdio.h>#include<math.h>intisprime(inta)//函数定义{inti;if(a==1)return0;for(i=2;i<=sqrt(a);i++)if(a%i==0)

return0;

return1;}(2)在主函数中输入一个整数,调用isprime函数,如果函数值为1,则打印是素数,否则打印不是素数。voidmain(){intiNumber;printf("请输入一个整数:");scanf("%d",&iNumber);if(isprime(iNumber))//函数调用

printf("%d是素数\n",iNumber);elseprintf("%d不是素数\n",iNumber);}【例4-2】从键盘输入一个整数,判断该整数是否为素数。15第十五页,共80页。例题输入圆柱的高和半径,求圆柱体积,

volume=×r2×h。 要求定义和调用cylinder(r,h)计算圆柱体的体积。16第十六页,共80页。/*计算圆柱体积*/#include<stdio.h>voidmain(){doubleheight,radius,volume; doublecylinder(doubler,doubleh);/*函数声明*/ printf("Enterradiusandheight:"); scanf("%lf%lf",&radius,&height); /*调用函数,返回值赋给volume*/

volume=cylinder(radius,height); printf("Volume=%.3f\n",volume);}/*定义求圆柱体积的函数*/doublecylinder(doubler,doubleh) { doubleresult; result=3.1415926*r*r*h;/*计算体积*/ returnresult; /*返回结果*/}17第十七页,共80页。例题输出5之内的数字金字塔。

12233344445555518第十八页,共80页。/*输出数字金字塔*/#include<stdio.h>voidmain(){

voidpyramid(intn); /*函数声明*/

pyramid(5); /*调用函数,输出数字金字塔*/}voidpyramid(intn) /*函数定义*/{ inti,j; for(i=1;i<=n;i++)/*需要输出的行数*/{ for(j=1;j<=n-i;j++) /*输出每行左边的空格*/ printf(""); for(j=1;j<=i;j++) /*输出每行的数字*/ printf("%d",i); /*每个数字的后各有一个空格*/

putchar('\n');

}}19第十九页,共80页。例题

输入精度e,使用格里高利公式求π的近似值,精确到最后一项的绝对值小于e。要求定义和调用函数funpi(e)求π的近似值。20第二十页,共80页。/*用格里高利公式计算π的近似值,精度为e*/#include<stdio.h>#include<math.h>voidmain(){ doublee,pi;

doublefunpi(doublee); printf("Entere:"); scanf("%lf",&e);

pi=funpi(e); printf("pi=%.4f\n",pi); }doublefunpi(doublee){ intdenominator,flag;doubleitem,sum;

flag=1; denominator=1;

item=1.0; sum=0;while(fabs(item)>=e){ item=flag*1.0/denominator;sum=sum+item;flag=-flag; denominator=denominator+2;} returnsum*4;}21第二十一页,共80页。4.3函数的多级调用函数的嵌套调用函数的递归调用递归与递推22第二十二页,共80页。引例

设计一个常用圆形体体积的计算器,采用命令方式输入1、2、3,分别选择计算球体、圆柱体、圆锥体的体积,并输入计算所需相应参数。23第二十三页,共80页。#include<stdio.h>#definePI3.141592654voidcal(intsel);voidmain(){intsel;

while(1)

{printf("1-计算球体体积\n"); printf("2-计算圆柱体积\n"); printf("3-计算圆锥体积\n"); printf("其他-退出程序运行\n"); printf("请输入计算命令:"); scanf("%d",&sel); if(sel<1||sel>3)

break; /*输入非1~3,循环结束*/ else

cal(sel); /*输入1~3,调用cal()*/

}}24第二十四页,共80页。/*常用圆形体体积计算器的主控函数*/voidcal(intsel){doublevol_ball();doublevol_cylind();doublevol_cone();switch(sel){ case1: printf("球体积为:%.2f\n",vol_ball()); break;case2: printf("圆柱体积为:%.2f\n",vol_cylind()); break;case3: printf("圆锥体积为:%.2f\n",vol_cone()); break; }}25第二十五页,共80页。/*计算球体体积V=4/3*PI*r*r*r*/doublevol_ball(){doubler;printf("请输入球的半径");scanf("%lf",&r);return(4.0/3.0*PI*r*r*r);}/*计算圆柱体积V=PI*r*r*h*/doublevol_cylind(){doubler,h;printf("请输入圆柱的底圆半径和高:");scanf("%lf%lf",&r,&h);return(PI*r*r*h);}/*计算圆锥体积V=h/3*PI*r*r*/doublevol_cone(){doubler,h;printf("请输入圆锥的底圆半径和高:");scanf("%lf%lf",&r,&h);return(PI*r*r*h/3.0);}26第二十六页,共80页。嵌套调用

main函数{……x=root(x1,x2);……}root函数{……x=xpoint(x1,x2);……}xpoint函数{……return(x1*f(x2)-x2*f(x1))/(f(x2)–f(x1));……}f函数{……}图4-5函数调用关系示意图C语言不允许嵌套定义函数,但允许嵌套调用函数。除了主函数外,其它函数可以相互调用。27第二十七页,共80页。递归调用

递归调用指的是一个函数执行过程中出现了直接或间接调用函数本身的调用方式。如果直接调用函数本身称为直接递归;如果调用了另外一个函数,那个函数又调用该函数,则称为间接递归。递归方法的基本思想是将一个问题向下分解具有同样解决方法但规模不断缩小的子问题,不断进行这样的分解,直到分解的子问题有一个已知解。28第二十八页,共80页。

例如:有4个人坐在一起,问第4个人多少岁?他说比第3个人大2岁。问第3个人多少岁?他说比第2个人大2岁。问第2个人多少岁?他说比第1个人大2岁。最后问第1个人,他说他10岁。请问第4个人多大。29第二十九页,共80页。分析:age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10可以用数学公式表示为:

age(n-1)+2(1<n≤4)age(n)=10(n=1)30第三十页,共80页。age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10age(2)=12age(3)=14age(4)=16求第4个人年龄的过程如下图第一阶段“回推”,第二阶段“递推”递归过程结束条件31第三十一页,共80页。可以看出,当n>1时,求第n个人的年龄的公式是相同的。因此可以编写一个函数来表示上述关系。32第三十二页,共80页。#include<stdio.h>intage(intn){ intc; if(n==1) c=10;

else

c=age(n-1)+2;

returnc;}voidmain(){ printf("%d\n",age(4));}其中:age函数共被调用4次,即age(4),age(3),age(2),age(1)33第三十三页,共80页。age(4)mainc=age(3)+2age函数n=4c=age(2)+2age函数n=3c=age(1)+2age函数n=2c=10age函数n=1age(2)=12age(3)=14age(4)=16输出age(4)age(1)=1034第三十四页,共80页。#include<stdio.h>floatfac(intn){ floatf; if(n==1) f=1; else f=n*fac(n-1);

returnf; }voidmain(){ intn; floaty; printf("inputanintergernumber:"); scanf("%d",&n); if(n>0) { y=fac(n); printf("%d!=%10.0f\n",n,y); } else printf("n<=0,dataerror!\n");}用递归的方法求n!35第三十五页,共80页。递归的条件

设计一个函数来实现递归算法,这个函数必须不断使用下一级值调用自己,但不能无限地调用下去,最终应能终止递归。因此递归函数一般必须满足下列条件:必须有完成函数任务的语句(return语句);必须有一个确定是否能终止递归调用的语句;必须有一个递归调用语句。36第三十六页,共80页。递归与递推

大多数递归问题都可以转化为递推求解,递归调用使用选择结构,而递推调用使用循环结构。

37第三十七页,共80页。intage(intn){ intc=10,i=1;

while(i<n) { i++; c=c+2; } returnc;}intage(intn){ intc; if(n==1) c=10; else c=age(n-1)+2; returnc;}递归递推38第三十八页,共80页。递归的优点:使用递归能够更自然地反映解决问题的过程,符合人的思维习惯,易于理解和调试程序,简化程序,便于阅读递归的缺点:大量的递归调用会占用处理器很多时间和大量的内存递推的优点:效率高递推的缺点:比较难编程,可读性较差39第三十九页,共80页。4.4变量的作用域和存储类别程序在内存中的分布区域局部变量及存储类别全局变量及存储类别40第四十页,共80页。引例用函数实现财务现金记账。先输入操作类型(1--收入;2--支出;0--结束),再输入操作金额,计算现金剩余额,经多次操作直到操作类型为0时结束。要求定义并调用函数,其中现金收入与现金支出分别用不同函数实现。41第四十一页,共80页。#include<stdio.h>floatcash;intmain(void){ voidincome(floatnumber),expend(floatnumber); intchoice; floatvalue;

cash=0; printf("Enteroperatechoice(0--end,1--income,2--expend):"); scanf("%d",&choice); while(choice!=0) { if(choice==1||choice==2) { printf("Entercashvalue:"); scanf("%f",&value); if(choice==1)

income(value); else

expend(value); printf("Currentcash:%.2f\n",cash); } printf("Enteroperatechoice(0--end,1--income,2--expend):"); scanf("%d",&choice); } return0;}voidincome(floatnumber){ cash=cash+number;}voidexpend(floatnumber){ cash=cash-number;}42第四十二页,共80页。从变量占用空间的角度(作用范围)来分析问题,划分出全局变量和局部变量,这是变量的作用域问题。从变量值存在的时间角度(生存周期)来分析问题,划分出变量的静态存储和动态存储,这是变量的存储类别问题。43第四十三页,共80页。(1)程序区:存放用户程序代码,即程序中各个函数的代码。(2)静态存储区:存放程序的全局数据和静态数据。分配在静态存储区中的变量的生命期最长,它们在main函数运行之前就存在了,在程序的整个活动期(从程序开始执行到执行结束)中,这些变量始终占用静态存储区中对应的存储空间,即程序开始执行时分配存储单元,程序执行完毕后释放。(3)动态存储区:存放局部变量。分配在动态存储区中的变量只有在所定义的函数被调用时才分配存储单元,函数结束时就释放。系统对函数调用时的现场保护、返回地址等也占用动态存储区。程序在内存中的分布区域

44第四十四页,共80页。局部变量:在一个函数内定义的变量。局部变量作用域:块内定义、块内使用。所谓块内是指一对以{}为界限的若干个语句,例如函数体、复合语句。块内使用是指变量的作用范围仅仅局限在从变量定义处开始、到变量定义所在的那个块结束。如:voidmain(){intn;/*……*/}voidfunc(){intn;/*……*/}局部变量及存储类别

main的局部变量func的局部变量45第四十五页,共80页。形式参数也为局部变量,其作用范围是形式参数所在的整个函数。例如:voidmain(){printf("%d,%d",x,y);

……}voidfunc(intx,inty){

……}在main函数中不能使用在func函数中定义的局部变量46第四十六页,共80页。在复合语句中定义局部变量。#include<stdio.h>voidmain(){int a;a=1;

{ /*复合语句开始*/intb=2;b=a+b;a=a+b;

}

/*复合语句结束*/ printf("%d",a);}b:小范围内的临时变量

47第四十七页,共80页。局部变量的存储类别:自动变量:用关键字auto(可缺省)

加以说明的局部变量。如:autofloatb;或floatb;

特点:是短生命期的局部变量,安排在动态存储区,由系统自动分配和释放,用到时分配内存,不用时释放内存,以节省程序执行时的内存资源。局部静态变量:用关键字static

加以说明的局部变量。如:

staticintcount;

特点:是长生命期的局部变量。函数执行结束后,分配给该变量的存储区不释放。局部静态变量安排在静态存储区。寄存器变量:关键字register说明的局部变量为寄存器变量。特点:寄存器变量的值存放在CPU的寄存器中,可以提高程序的执行效率。如registerinti;48第四十八页,共80页。局部静态变量说明:

staticintcount局部静态变量属于静态存储类别;局部静态变量是在编译时赋初值的,即只赋初值一次;局部静态变量不赋初值,编译时自动赋初值0;局部静态变量在函数调用结束仍存在,但其他函数不能引用它。形参不能是局部静态变量。寄存器变量说明:如

registerinti;只有局部自动变量和形式参数可以作为寄存器变量,其它(如全局变量)不行。一个计算机系统中的寄存器数目有限,不能定义太多寄存器变量;局部静态变量不能定义为寄存器变量。如:

registerstaticinta,b;//error49第四十九页,共80页。【例4-10】局部变量存储方式举例,分析下面程序运行结果:/*程序名:4_10.cpp*//*功能:局部变量存储方式示例*/#include<stdio.h>intfun1(int);intfun2(int);voidmain(){inti;for(i=2;i<5;i++)printf("%d\t",fun1(i));printf("\n");for(i=2;i<5;i++)printf("%d\t",fun2(i));printf("\n");}intfun1(intx){

intf=1;return(f*=x);}intfun2(intx){

staticintf=1;return(f*=x);}2342624staticintf;f=1;23423450第五十页,共80页。全局变量:在所有函数外定义的变量。全局变量作用域:从变量定义处开始到所定义的源文件结束处,即从全局变量定义所在处开始到源文件结束处之间的所有函数都可以访问该变量。如:intn=1;voidmain(){/*……*/}floatm;voidfunc(){/*……*/}全局变量及存储类别

51第五十一页,共80页。全局变量定义#include"stdio.h"intx; /*定义全局变量x*/intf(){

intx=4;/*x为局部变量*/returnx;}voidmain(){

inta=1;

x=a; /*对全局变量x赋值*/a=f(); /*a的值为4*/{

intb=2; b=a+b; /*b的值为4*/

x=x+b; /*全局变量运算*/}printf("%d%d",a,x);}若局部变量与全局变量同名,局部变量优先52第五十二页,共80页。【例4-11】全局变量的作用域举例,分析下面程序运行结果。#include<stdio.h>voids);

inta,b;

voidmain(){scanf("%d,%d",&a,&b);printf("交换前的a和b是%d,%d\n",a,b);

swap();printf("交换后的a和b是%d,%d\n",a,b);}voidswap(){intt;

t=a;a=b;b=t;}53第五十三页,共80页。不要滥用全局变量使用全局变量会带来如下问题:程序的清晰度降低函数的灵活性、通用性降低存储空间的利用率降低54第五十四页,共80页。局部变量与全局变量同名时:小范围优先【例4-12】分析下面程序运行结果:#include<stdio.h>inti=1;/*变量i定义在所有函数之外,属于全局变量*/inttest();voidmain(){printf("主函数中i:%d其地址%p\n",i,&i);i=test()+1;printf("主函数中i:%d其地址%p\n",i,&i);}inttest(){inti;printf("test中i:%d其地址%p\n",i,&i);i=2;printf("test中i:%d其地址%p\n",i,&i);return(i);}55第五十五页,共80页。全局变量的存储类别:(静态存储)静态全局变量:使用关键字static定义的全局变量。特点:只能被其定义所在的源文件中的函数访问,同一程序的其它源文件中的函数都不能访问该变量。非静态全局变量:也称为外部变量,不使用任何关键字。特点:该变量不仅能被定义所在的源文件中的函数访问,而且组成程序的其它源文件中的函数也都能访问该变量。因此,从作用范围看,外部变量的作用域要比使用关键字static的静态全局变量的大。关键字extern

的作用关键字extern的作用是对要使用的某个尚未定义的全局变量在使用前作变量说明,该全局变量或者是以后会在该源文件中定义的全局变量,或者是在另一个源文件中定义的非静态全局变量。56第五十六页,共80页。/*程序名:a.cpp*//*功能:全局变量存储方式示例*/#include<stdio.h>externinta;/*对c.cpp中定义的变量进行说明*/voidfun1();voidfun2();voidmain(){fun1();fun2();printf("函数main中的a是%d\n",a);}【例4-13】全局变量存储方式举例,分析下面程序运行结果:57第五十七页,共80页。/*程序名:c.cpp*/#include<stdio.h>inta;

/*允许其它文件中函数访问的全局变量*/voidfun2(){a=4;printf("函数fun2中的a是%d\n",a);}/*程序名:b.cpp*/#include<stdio.h>staticinta;/*只允许文件b.cpp中函数访问的全局变量*/voidfun1(){a=2;printf("函数fun1中的a是%d\n",a);}58第五十八页,共80页。函数与程序文件模块如果一个程序包含多个文件模块,要实现在一个文件模块A中调用另一个文件模块B中的函数时,就要在文件模块A中对函数进行外部声明。声明格式为:

extern函数类型函数名(参数表说明);C语言也允许把函数定义成静态的,以便把函数的使用范围限制在文件模块内。即使其他文件模块有同名的函数定义,相互也没有任何关联,增强了文件模块的独立性。

static函数类型函数名(参数表说明);extern可省略59第五十九页,共80页。4.5计算机随机模拟方法伪随机数的产生蒙特卡罗方法(不要求)60第六十页,共80页。rand()函数可随机生成0~RAND_MAX之间的一个整数。RAND_MAX是头文件<stdlib.h>中定义的一个符号常量。ANSI规定RAND_MAX的值不小于32767。根据下面公式可以得到所需范围内的随机数:

n=a+rand()%b

其中a为位移,是所需连续整数范围的第一个数,b是比例因子,是所需连续整数范围的宽度,则希望产生1~6之间随机数的公式为:

face=1+rand()%6伪随机数的产生

61第六十一页,共80页。【例4-14】编写一个模拟投掷硬币的程序,模拟20次,统计出正面出现的次数。#include<stdio.h>#include<stdlib.h>voidmain(){ inti,face,iCount=0; for(i=1;i<=20;i++) { face=0+rand()%2; printf("%5d",face); if(i%10==0)printf("\n"); if(face)iCount++; } printf("正面出现次数:%d次\n",iCount);}62第六十二页,共80页。运行程序,结果为:11001000001111111010正面出现次数:11次再次运行该程序结果为:11001000001111111010正面出现次数:11次用函数void

srand(

unsigned

int

seed

),通过提供不同的种子产生不同的随机数序列。63第六十三页,共80页。用srand()函数进行随机化#include<stdio.h>#include<stdlib.h>voidmain(){ unsignedseed; printf("输入一个非负整数做种子:"); scanf("%d",&seed); srand(seed); for(inti=1;i<=10;i++) printf("%3d",1+rand()%6);}运行3次程序:输入一个非负整数做种子:161343565262输入一个非负整数做种子:333153565415输入一个非负整数做种子:16134356526264第六十四页,共80页。使用系统定时/计数器的值做为随机种子:

srand(time(NULL));time()函数返回以秒为单位的当前时间值,因为有时钟参数,而时间始终在变,随机数序列就不会固定不变了。【例4-16】编写程序,用来生成一个随机小写字符串。

#include<stdio.h>

#include<time.h>

#include<stdlib.h>voidmain(){srand(time(NULL)); for(inti=1;i<=20;i++) printf("%c",97+rand()%26); printf("\n");}65第六十五页,共80页。4.6编译预处理文件包含#include宏定义#define条件编译#if66第六十六页,共80页。“文件包含”是指一个源文件可以将另一个源文件的全部内容包含进来。在编译预处理时#include指令让预处理器用指定文件内容替换该语句,然后作为一个源文件编译形成新文件。文件包含的一般形式为:(1)#include<文件名>(2)#include"文件名"例如:#include<stdio.h>(只查C语言的系统目录)#include“stdio.h”(首先查当前目录)文件包含#include67第六十七页,共80页。(1)定义符号常量

#define标识符

字符串如:#definePI3.14预处理器将在源文件中搜索PI,并把每个PI替换成3.14。完成搜索和操作替换后,预处理器删除#define行。(2)定义宏

#define宏名(参数表)

字符串如:#defineS(a,b)a*b对程序中带有实参的宏(如S(3,4)),按#define命令中指定的字符串从左到右进行替换。如果字符串中包含宏的形参(如a,b),则将程序语句中相应的实参代替形参,如果宏定义中字符串中的字符不是参数字符(如a*b中的*)则原样保留。宏定义#define宏名中间不能有空格68第六十八页,共80页。宏的用途符号常量简单的函数功能实现如:#defineMAX(a,b)(a)>(b)?(a):(b)为程序书写带来一些方便如:#defineSINA""C语言允许宏嵌套定义如:#definePI3.14159#defineSPI*r*r#include<stdio.h>voidmain(){ intr=2; printf("%f\n",S);}69第六十九页,共80页。宏的范围宏可以写在程序中的任何位置,它的作用范围从定义书写处到该文件尾,在此范围内都可以用宏名进行替换,并可以通过#undef强制指定的宏的结束范围.#include<stdio.h>#defineA"Thisisthefirstmacro"voidf1(){printf("A\n");}#defineB"Thisisthesecondmacro"

voidf2(){printf(B); }#undefBvoidmain(){f1();f2();printf("\n");}70第七十页,共80页。带参数宏例1:#include<stdio.h>#defineSQR(n)(n)*(n)voidmain(){ intiNumb

温馨提示

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

评论

0/150

提交评论