《(中职)C语言程序设计模块十电子课件.pptx》由会员分享,可在线阅读,更多相关《(中职)C语言程序设计模块十电子课件.pptx(25页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、YCF正版可修改PPT(中职)C语言程序设计模块十ppt电子课件LOGO预处理命令模块1010.1无参宏定义及宏代换所谓无参宏定义,指的是宏名(标识符)后面不带参数。定义方法:#define 标识符 字符串/*字符串可以是常量、表达式和格式串*/其意为:在书写时,用标识符代替其后的字符串出现于程序中;而在程序执行时,则用字符串去代换标识符。这就是宏代换。10.1无参宏定义及宏代换#include#define A(x*x+2*x)/*注意下面整个表达式用()括起来时的展开方法*/#define Bx*x+2*x/*注意下面表达式没用()括起来时的展开方法*/#define M(%d,%d,%d
2、n)/*格式串*/#define P(A*y+c)/*宏定义嵌套*/#define RB*y+cint main()int x,y,s1,s2,a=3,b=4,c;c=a+b;printf(Input x:);scanf(%d,&x);/*假设输入3*/y=2;s1=2*A;/*展开方法:2(33+23)=30,故s1为30*/s2=2*B;/*展开方法:233+23=24,故s2为24*/【例10-1】不同方式无参宏代换详解。10.1无参宏定义及宏代换a=b;/*a重新获得4*/b=c;/*b重新获得7*/c=a+b;/*c重新获得4+711*/printf(s1=%d,s2=%dn,s1,
3、s2);printf(M,a,b,c);/*按格式串宏代换输出a,b,c,注意宏名只能直接引用,不能加引号*/printf(A*y+c)=%dn,P);/*展开:(33+23)2+11=41*/printf(A*y+c=%dn,3*R);/*展开:333+232+11=50*/#undef A/*终止A的作用域,即其代替作用到此为止,下同*/#undef B#undef M#undef P输出结果如下:Input x:3s1=30,s2=244,7,11(A*y+c)=41A*y+c=5010.1无参宏定义及宏代换从上面的程序中可以得出以下结论:(1)宏定义一般不用带符号结束,如“#defin
4、e A(x*x+2*x)”。(2)当宏名后面的字符串以“()”括起来时,展开时它是一个整体进行运算。例如:#define A(x*x+2*x)s1=2*A;实际就是“s1=2*(x*x+2*x)”。(3)若宏名后面的字符串不以“()”括起来,展开时是按序展开的。例如:#define Bx*x+2*xs2=2*B;实际就是“s2=2*x*x+2*x”。可见,宏名后的字符串用“()”和不用,宏代换时其意完全不同。因此,在进行下面的运算时,算法就完全不同:10.1无参宏定义及宏代换#define P(A*y+c)#define RB*y+c printf(A*y+c)=%dn,P);printf(“
5、A*y+c=%dn”,3*R);P表示“(A*y+c)”,运算过程是“(x*x+2*x)*y+c)”。R表示“B*y+c”,3*R的运算过程就是“3*x*x+2*x*y+c”。(4)#undef用于强制中止宏名的作用域,若不中止,则其作用域为到程序结束。(5)宏名只能直接引用,若加引号,加双引号做字符串处理,加单引号做字符处理。(6)为与变量名区别开来,宏名一般用大写。还可用宏定义表数据类型。例如:#define DB double#define STU struct student DB m;STU st20,*p=st;最后须强调一点的是,预处理程序不会对错误的宏定义进行检查。10.2带参
6、宏定义与宏调用带参宏定义就是“宏名(标识符)”后带了参数,参数用“()”括起来。(1)定义方式(要注意形参表和标识符之间不能有空格)。(2)调用方式:标识符(实参表);【例10-2】带参宏定义与调用示例。#include#define PI 3.14#define S(r)(PI*r*r)/*计算圆的面积*/#define L(x,y,z)(x)*(y)+(z)/*形参表x,y,z,要区分带“()”和下面不带“()”的区别*/#define M(x,y,z)x*y+z#define MAX(m,n)(mn)?m:n/*比较两数大小*/int main()float r;10.2带参宏定义与宏调
7、用int a=2,b=3,c=4;printf(Input r:);scanf(%f,&r);printf(The area=%.2fn,S(r);printf(x)*(y)+(z)=%dn,L(a+b),(b+c),(a+c);printf(x)*(y)+(z)=%dn,L(a+b,b+c,a+c);printf(x*y+z=%dn,M(a+b),(b+c),(a+c);printf(x*y+z=%dn,M(a+b,b+c,a+c);printf(The Max is:%dn,MAX(int)S(r),M(a+b,b+c,a+c);10.2带参宏定义与宏调用各行计算如下:宏调用S(r),计算
8、表达式(PI*r*r),假如输入3,即3.1433=28.26。宏调用L(a+b),(b+c),(a+c),计算表达式“(x)*(y)+(z)”,即(a+b)*(b+c)+(a+c)=57+6=41。宏调用L(a+b,b+c,a+c),计算表达式“(x)*(y)+(z)”,即(a+b)*(b+c)+(a+c)=57+6=41,这里的“()”是表达式“(x)*(y)+(z)”中的“()”。宏调用M(a+b),(b+c),(a+c),计算表达式“x*y+z”,即(a+b)*(b+c)+(a+c)=57+6=41,这里的“()”是实参表里的“()”。宏调用M(a+b,b+c,a+c),计算表达式“x
9、*y+z”,即a+b*b+c+a+c=2+33+4+2+4=21,没有“()”,顺次展开。宏调用MAX(int)S(r),M(a+b,b+c,a+c),计算表达式“(mn)?m:n”的值,其实就是把两个调用结果进行大小的比较(比较时圆的面积先转为int型)。10.2带参宏定义与宏调用输出结果如下:Input r:3The area=28.26(x)*(y)+(z)=41(x)*(y)+(z)=41x*y+z=41x*y+z=21The Max is:28在上面的宏调用中,要特别注意没有“()”的表达式在计算中按序展开的情况,如上面的第个宏调用,否则很容易出错,如下例。10.2带参宏定义与宏调用
10、【例10-3】指出宏调用的输出结果。#include#define M(x,y)(x)(y)?x:yint main()int a=5,b=2,c=3,d=1,t;t=M(a+b,c+d)*10;printf(%d,t);该题若不仔细,是很容易出错的。一要注意实参a+b和b+c并没有带“()”,二要注意表达式“(x)(y)?x:y”中后面的x,y也没有带“()”。计算过程如下:t=(a+b)(c+d)?a+b:c+d*10结果是取:c+d*10=3+110=13/*输出13*/10.2带参宏定义与宏调用#include#define M(x)x*xint main()int a=2,b=3;p
11、rintf(x*x=%dta=%dtb=%dn,+M(a+b)-,a,b);printf(ta=%dtb=%dn,a,b);【例10-4】指出宏调用的输出结果。10.2带参宏定义与宏调用该题同样是按序展开的问题。同时要注意自增自减的问题。计算过程如下:(1)printf(x*x=%dta=%dtb=%dn,+M(a+b)-,a,b);printf()函数从右往左运算,故a,b输出原值。+M(a+b)-展开如下:+a+b*a+b-=3+32+3=12该行输出:x*x=12a=2b=3说明:不同的编译器可能产生不同的结果,在VC 2015中,该行输出结果直接体现了变量的自增自减变化,即+a+b*a
12、+b-=3+33+3=15输出:x*x=15a=3b=2;(1)不要把宏定义和宏代换和typedef混淆。(2)宏定义形参表与函数形参表的区别是:宏定义形参不可以定义类型、不分配内存单元、不存在值的传递(仅仅是符号代换)。10.2带参宏定义与宏调用(2)“printf(ta=%dtb=%dn,a,b);”输出变化了的值,即a=3,b=2。最后要指出的是:10.3条 件 编 译预处理程序提供了条件编译的功能,可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。1.#ifdef条件编译使用方法如下:#ifdef 标识符程序段1;/*如果标识符已定义,
13、执行程序段1*/#else程序段2;/*否则执行程序段2*/#endif/*结束条件编译*/10.3条 件 编 译2.#ifndef条件编译使用方法与#ifdef完全相反。#ifndef 标识符程序段1;/*如果标识符没有定义,执行程序段1*/#else程序段2;/*否则执行程序段2*/#endif/*结束条件编译*/3.#if条件编译#if 条件程序段1;/*如果条件为真,即值为1,执行程序段1*/#else程序段2;/*否则执行程序段2*/#endif/*结束条件编译*/10.3条 件 编 译【例10-5】条件编译示例。#include#define NUM/*做条件编译时定义标识符后面不
14、一定需要值*/#define R 1/*做条件判断时非0值均为1*/int main()struct stuint num;char*name;char sex;float score;*ps;ps=(struct stu*)malloc(sizeof(struct stu);ps-num=102;ps-name=zhang ping;ps-sex=m;ps-score=62.5;10.3条 件 编 译#ifdef NUMprintf(Number=%dnScore=%fn,ps-num,ps-score);/*NUM已宏定义,执行此行*/#elseprintf(No define NUMn)
15、;#endif#ifndef OKprintf(No define OKn);/*OK标识符没有宏定义,执行此行*/#elseprintf(Name=%snSex=%cn,ps-name,ps-sex);#endif#if R/*条件为真,执行下两行*/printf(Yes,Passn);printf(Name=%snSex=%cn,ps-name,ps-sex);#elseprintf(No,Failn);#endiffree(ps);10.4文 件 包 含文件包含其实在第8页已有说明,其形式就是“#include头文件名”或“#include”。关于头文件名用“”和“”包含的区别,详见2.
16、1节程序示例的说明。什么是头文件?从其在程序中所属的位置来讲,它是置于程序头部的外部文件,其扩展名为“.h”。它里面存放的一般是具有各个功能的函数,在程序头部包含了头文件后,在程序中就可以使用头文件里的各个功能函数。文件包含也是C语言预处理程序的一个重要功能。在编程中,除了包含库函数的头文件外,也可以包含用户自建的头文件。例如,自建一个名为myh.h的头文件,里面包含求圆的面积函数名area(),判断是否是直角三角形函数名delta(),判断是否是素数函数名prime(),分解质因数函数名(primefactor())等函数。把头文件置于程序所在的文件夹里保存时更改保存类型为“c头文件(*.h
17、)”。10.4文 件 包 含myh.h头文件如下:#define PI 3.14float area(float r)float f=1;f=PI*r*r;return f;int delta(float a,float b,float c)if(a*a+b*b=c*c|a*a+c*c=b*b|b*b+c*c=a*a)return 1;elsereturn 0;int prime(int x)int i,flag=1;for(i=2;ix/2;)10.4文 件 包 含if(x%i=0)flag=0;break;elsei+;return flag;void primefactor(int x)
18、int i,j,count=0;int m=x;int a10;for(i=0,j=2;j=x;)if(x%j=0)ai+=j;count+;x/=j;continue;j+;printf(%d=,m);for(i=0;icount-1;i+)printf(%d*,ai);printf(%d,acount-1);putchar(n);10.4文 件 包 含主程序代码如下:#include stdio.h#include myh.h/*包含自建的头文件,便可在主程序中调用自建的函数*/main()float r,x,y,z;int m,n;printf(Input r:);scanf(%f,&r
19、);printf(Area=%.2fn,area(r);/*调用函数求面积*/printf(Input x,y,z:);scanf(%f%f%f,&x,&y,&z);m=delta(x,y,z);/*调用函数判断输入3个数是否构成直角三角形*/10.4文 件 包 含if(m=1)printf(It is a Deltan);elseprintf(It isnt a Deltan);printf(Input n:);scanf(%d,&n);m=prime(n);/*调用函数判断是否是素数*/if(m=1)printf(It is prime!n);elseprintf(It isnt prime!n);primefactor(n);/*调用函数对上面输入的数分解质因数*/LOGO