欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    程序设计实践-预处理和EGG库.ppt

    • 资源ID:6596234       资源大小:355KB        全文页数:53页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    程序设计实践-预处理和EGG库.ppt

    提纲,预处理命令预处理指令#include预处理指令#define:符号常量预处理指令#define:宏条件编译2.Egg图形库说明,预处理指令#define:宏,#define用来定义符号常量(用符号表示的常量)。宏(用符号定义的操作)。宏宏用来替代一个字符串,类似于符号常量,宏在预处理时被替换字符串取代。不带参数的宏:预处理程序就像处理符号常量一样处理不带参数的宏。带参数的宏:先用替换文本取代参数,然后再把宏展开。,预处理指令#define:宏,带参数的宏定义格式:#define 标识符(形式参数表)字符串形式参数表由逗号分割开的标识符组成,这些标识符在字符串中出现。如:#define PI 3.14159/常量定义#define CIRCLE_AREA(x)(PI*(x)*(x)#define MAX(x,y)(x)(y)?(x):(y)#define NUL(x,y)(x)*(y),预处理指令#define:宏,宏调用格式:标识符(实在参数表)如:area=CIRCLE_AREA(3+4);宏在预处理时被展开:1.替换参数:文件中如果出现宏调用CIRCLE_AREA(3+4),则字符串中的x都用3+4替代;2.用字符串取代程序中的宏调用。语句area=CIRCLE_AREA(3+4);在预处理 时将被展开成 area=(3.14159*(3+4)*(3+4);,(3.14159*(3+4)*(3+4),预处理时被展开,预处理指令#define:宏,需要注意的是,在宏名和括起参数的括号之间绝对不能有空格。此外,为了避免在翻译宏时产生歧义,宏体和参数也应该用括号括起来。例如,象下例中这样定义宏CIRCLE_AREA是不正确的:define CIRCLE_AREA(x)PI*x*x如:int a=3,b=4;语句 area=CIRCLE_AREA(a+b);将被展开成 3.14159*a+b*a+b;,预处理指令#define:宏,使用宏还是函数宏与函数相比有一个明显的优势,即它比函数效率更高(并且更快),因为宏可以直接在源代码中展开,而调用函数还需要额外的开销。但是,宏一般比较小,无法处理大的、复杂的代码结构,而函数可以。此外,宏需要逐行展开,因此宏每出现一次,宏的代码就要复制一次,这样你的程序就会变大,而使用函数不会使程序变大。,条件编译使编译器能够按照不同条件编译不同的程序部分,产生不同的目标代码文件。两种条件编译:使用常量表达式判断、使用宏定义名判断,条件编译,条件编译,1.使用常量表达式判断(共3种),#if 整型常量表达式 文本1#else 其他文本#endif,#if 整型常量表达式 文本1#endif,第1种情况,第2种情况,首先求常量表达式的值,然后根据常量表达式值是否为0进行下面的条件编译。在第2种情况中,如果该表达式的值非0,则编译文本1,否则编译其他文本。,#if 整型常量表达式1 文本1#elif 整型常量表达式2 文本2#else 其他文本#endif,第3种情况,条件编译,让编译器不编译某一段代码:#if 0 不编译的代码#endif以后若想让编译器编译该段代码,只需要将0改成1,条件编译,2.使用宏定义名判断,#ifdef 标识符 文本1#else 文本2#endif,#ifndef 标识符 文本1#endif,如果定义了标识符为宏(即使宏体为空),则为真,编译#ifdef后面的文本;否则编译#else后面的文本,#ifdef 标识符 文本1#endif,条件编译,#ifdef 标识符是#if defiend(标识符)的缩写#ifndef 标识符是#if!defiend(标识符)的缩写,条件编译,调试阶段,若想打印变量的值,则代码如下:#define DEBUG/定义宏,宏体为空#ifdef DEBUG printf(“variable x=%dn”,x);printf(“variable y=%dn”,y);#endif完成调试后,可以去掉#define 指令,这样就会在编译过程中忽略上述两条printf语句。,条件编译,#include#define DEBUG/定义宏main()int age;char name20;printf(input your agen);scanf(%d,条件编译,#ifdef DEBUG printf(input age is:%dn,age);#endif#undef DEBUG/取消宏定义#ifdef DEBUG printf(input name is:%sn,name);#endif system(pause);return 0;,input your age30input your namejohninput age is:30请按任意键继续.,条件编译,怎样避免多次包含同一个头文件?在创建一个头文件时,你可以用#define指令为它定义一个唯一的标识符名称。你可以通过#ifndef指令检查这个标识符名称是否已被定义,如果已被定义,则说明该头文件已经被包含了,就不要再次包含该头文件;反之,则定义这个标识符名称,以避免以后再次包含该头文件。,猴子选大王 NodeType.h:,#ifndef _NODETYPE_H#define _NODETYPE_Hstruct listNodeint data;struct listNode*nextPtr;typedef struct listNode LISTNODE;typedef LISTNODE*LISTNODEPTR;#endif,#include“NodeType.h”#include“NodeType.h”,main.c,编译遇到第1条include指令,由于_NODETYPE_H未被定义,因此该头文件被包含,_NODETYPE_H 被定义;编译遇到第2条include指令时,由于_NODETYPE_H已定义,因此该头文件将不再被包含,其他预处理指令#error,#pragma运算符#和#行号#line预定义的符号常量宏assert,提纲,使用工程组织多个源文件预处理命令Egg图形库说明,图形库函数EGG简介,可以把代码编译成库供其他人员调用。其他人员看不到源代码。两种库:静态链接库和动态链接库静态链接库在链接(link)的时候被连接到.exe文件(.LIB中的代码被包含到.exe文件中了),导致应用程序比较大。当.LIB版本升级时,需要对调用该LIB的程序重新编译。,.exe,图形库函数EGG简介,.DLL(Dynamic Link Library):动态链接库DLL 是一个包含可由多个程序同时使用的代码和数据的库。例如,在 Windows 操作系统中,Comdlg32 DLL 执行与对话框有关的常见函数。因此,每个程序都可以使用该 DLL 中包含的功能来实现“打开”对话框。事先不被连接到.exe文件,在运行期才会被调用。,1.exe,调用,调用,2.exe,图形库函数EGG简介,动态链接库是分两步链接进程序中的:首先,在编绎的时候,链接器查找出程序需要的所有符号(函数,变量等等),然后链接进程序当中或者程序的另一个共享链接库当中。动态链接库中的目标文件并没有固化进可执行文件。替代的是,当程序运行的时候,由系统的一个程序(叫做动态装载器 dynamic libraries)检查程序需要哪些动态链接库,然后把它们装入内存并且与内存中的程序关联。,图形库函数EGG简介,DLL 的优点使用较少的资源当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在 Windows 操作系统上运行的程序。推广模块式体系结构DLL 有助于促进模块式程序的开发。简化部署和安装当 DLL 中的函数需要更新或修复时,部署和安装 DLL 不要求重新建立程序与该 DLL 的链接。此外,如果多个程序使用同一个 DLL,那么多个程序都将从该更新或修复中获益。当您使用定期更新或修复的第三方 DLL 时,此问题可能会更频繁地出现。,图形库函数EGG简介,Egg提供2个静态链接库和1个头文件:egg.lib/静态链接库eggd.lib/静态链接库egg.h,图形库函数EGG简介,EGG绘图功能:绘制直线绘制曲线(正圆和椭圆)绘制字符串贴图:.bmp文件 设置画笔的颜色和线条粗细移动画面的某些部分(动画),图形库函数EGG简介,坐标系统,采用我们最熟悉的平面直角坐标系,左下角是坐标原点,X坐标向右递增,Y坐标向上递增,单位是厘米,坐标原点,图形库函数EGG简介,画笔当前位置在Egg中有一个画笔,尽管我们看不到它,但它确确实实存在。画笔指向位置的坐标就是画笔的当前位置,简称画笔位置。所有绘图操作都是从画笔位置开始落笔绘图,按照绘图要求移动画笔,并把最后提笔结束的位置作为新的画笔位置。画笔的初始位置是画面的左上角,并非坐标原点(左下角)。,画笔初始位置,画笔相关函数,图形库函数EGG简介,初始化只要调用一个函数EggStart()就完成所有初始化Egg平台的工作。void EggStart(double fWidth,double fHeight);参数:绘图窗口的宽和高,单位厘米。你不需要考虑Egg的结束问题。只要程序正常退出,Egg占用的所有资源都会被自动释放。,图形库函数EGG简介,直线void DrawLine(double dx,double dy)从画笔当前位置,按照参数指定的位移画一条直线。位移可以为正(沿X/Y坐标的正方向绘制)、也可为负(沿X/Y坐标的负方向绘制),void line(void)EggStart(5,5);/初始化 DrawLine(5,-5);/绘制直线 WaitForExit();/等待用户关闭窗口,图形库函数EGG简介,正圆曲线void DrawArc(double r,double dStart,double dSweep);r:曲线所在圆的半径,单位厘米。dStart:曲线开始点在圆周上的角度(即画笔在圆周上的角度)dSweep:曲线沿圆周按逆时针方向扫过的角度。如:DrawArc(2,45,90);,图形库函数EGG简介,DrawArc(2,45,90);,圆半径为2的圆可以有多个,但是画笔位置在圆周上角度为45的圆只有一个。画笔位置、圆半径以及角度唯一确定一个圆。,void yuan1(void)EggStart(4,4);OffsetPen(4,-2);/相对移动 DrawArc(2,0,360);WaitForExit();,void yuan1(void)EggStart(4,4);OffsetPen(4,-1);/相对移动 DrawArc(2,0,360);WaitForExit();,画笔初始位置,void yuan1(void)EggStart(4,4);OffsetPen(2,-2);/相对移动 DrawArc(2,0,360);WaitForExit();,图形库函数EGG简介,椭圆曲线void DrawEllipticalArc(double rx,double ry,double dStart,double dSweep);参数dStart和dSweep的含义与DrawArc完全相同。rx是该椭圆在x轴的半径,ry是在Y轴的半径。,图形库函数EGG简介,字符串void DrawString(char*pString);例如,要输出Hello World,使用如下代码:DrawString(Hello World);字符串的左上角位于当前的画笔位置,输出后画笔位置移动到字符串的右上角。,Hello World,输出前画笔位置,输出后画笔位置,图形库函数EGG简介,贴图Egg支持.bmp文件的贴图,使用下面函数:void DrawBitmap(char*lpszFilename);参数是bmp文件名,例如要贴当前目录下的“beauty.bmp”文件,可以使用下面语句:DrawBitmap(beauty.bmp);位图的左上角位于画笔当前位置,贴图后,画笔当前位置移动到位图的右上角。,图片,输出前画笔位置,输出后画笔位置,void yuan1(void)EggStart(4,4);OffsetPen(2,-2);DrawArc(2,0,360);MovePen(2,2);DrawString(hello);DrawBitmap(pic.bmp);WaitForExit();,图形库函数EGG简介,画笔颜色和宽度函数SetPen()改变画笔的颜色和宽度,从此都用指定的颜色和宽度绘画各种图形、文字,直到下次调用相关函数为止。void SetPen(unsigned long color,double fWidth);fWidth是宽度,单位厘米。color是颜色,取值见具体宏定义。如果只想单独改变颜色或宽度,可以调用void SetPenColor(unsigned long color)void SetPenWidth(double fWidth),动画实现盘子:白色窗口egg:任何图形都是画在一个egg上,可以有多个egg,但每个egg都是相对独立的,可以绘画、移动任何一个egg,而不会影响其它的egg。移动时只能以egg为单位进行移动,因此要一起移动的内容得画在同一个egg上。egg的大小与调用EggStart()时指定的大小一致,并且覆盖整个盘子(盘子是Egg图形窗口的昵称),但它初始状态是透明的。,可以画多个egg,当两个蛋重合,后下的蛋会覆盖先下的蛋。使用ChangeEggLayer()可以改变egg的层次,调整互相之间的覆盖关系。需要特别注意的是,在egg上绘画时,所采用的坐标系是每个egg自己的独立坐标,而不是盘子坐标。也就是说,绘画时,不需要考虑egg在盘子内的位置(egg会移动),egg自己的左下角永远是坐标原点。,如何下蛋:每次调用LayEgg()都会生成一个新的egg,并把这个egg的句柄返回给你。HEGG LayEgg(void);执行完EggStart()后,便已经偷偷建立了一个egg,所有的绘图操作,都是在这个egg上进行的。当LayEgg()后,再执行绘图操作,就是在新的egg上绘图了。,如何设置活动蛋:绘图和移动都是在活动蛋上进行的;如果想回头在旧egg上绘图,可以使用void SetActiveEgg(HEGG hEgg)函数将旧的egg变成活动蛋因此,需要把每次LayEgg()的返回值(egg的句柄)保存下来,从而将旧蛋变成活动蛋;,#include egg.h#define NUMBER_OF_EGG 5int main(void)HEGG hEggsNUMBER_OF_EGG;int i;EggStart(10,5);for(i=0;iNUMBER_OF_EGG;i+)hEggsi=LayEgg();DrawArc(i+1,180,180);/在当前活动的蛋上画一个半圆 WaitForExit();/等待用户关闭窗口 return 0;,由于每个蛋是透明的,所以能看到所有蛋上的半圆,如何动蛋移动是在活动蛋上进行的。移动一个蛋时,该蛋上所有的图形都会一起动。如果只是想动整个图形的一部分(如电梯、小火车),则该部分一定要在一个独立的egg上绘制。void MoveEgg(double x,double y);在盘子上移动活动egg到盘子内的坐标处void OffsetEgg(double dx,double dy);在盘子上把活动egg移动(dx,dy)位移,/画5个能分别动起来的半圆void donghua1(void)HEGG hEggsNUMBER_OF_EGG;int i;EggStart(10,5);/画5个不同半径的半圆 for(i=0;iNUMBER_OF_EGG;i+)hEggsi=LayEgg();DrawArc(i+1,180,180);,/让5个半圆分别移动 i=0;while(WaitFor(100)SetActiveEgg(hEggsi);OffsetEgg(NUMBER_OF_EGG-i-1)*0.1,0);if(i NUMBER_OF_EGG-1)i+;else i=0;,/画5个能同时动起来的半圆void donghua2(void)HEGG hEggsNUMBER_OF_EGG;int i;EggStart(10,5);SetAutoUpdate(0);/设置不自动更新屏幕 for(i=0;iNUMBER_OF_EGG;i+)hEggsi=LayEgg();DrawArc(i+1,180,180);,Update();/也可以不要 i=0;while(WaitFor(100)/定时器 SetActiveEgg(hEggsi);OffsetEgg(NUMBER_OF_EGG-i-1)*0.1,0);if(i NUMBER_OF_EGG-1)i+;else i=0;Update();/更新Egg窗口,将5个egg的分时移动模拟为同时动,4.3-Egg定时器1,int WaitFor(unsigned int uMillisecond);这是一种很简单的定时器。调用此函数后,你的程序在uMillisecond毫秒内将什么也不做,静静地等待WaitFor()函数的返回。在需要延时的场合,这个函数是很好用的。但当用户关闭窗口的时候,它会立即返回,返回值为0。此时,我们要停止正在做的事情,转入退出流程。例:/让5个egg分别移动#include“egg.h”/先定义5个egg,代码略 i=0;while(WaitFor(100)/每隔0.1秒会有一个半圆移动 SetActiveEgg(hEggsi);OffsetEgg(NUMBER_OF_EGG-i-1)*0.1,0);if(i NUMBER_OF_EGG-1)i+;else i=0;,4.4-Egg定时器2,void StartTimer(unsigned int uMillisecond);void StopTimer(void);这两个函数比WaitFor()稍微复杂一点儿,但它们的控制能力更精准,而且可以和其它输入完全配合(WaitFor()在等待的时候,用户的所有输入动作都无效,除了关闭窗口)。StartTimer()后,每隔uMillisecond毫秒,都会产生一个TIMER事件,可以用WaitForEvent()捕获这个事件,进而做相应的周期工作。不再需要定时事件时,调用StopTimer()停止它。,4.4-Egg定时器2,EVENT_TYPE ev;.StartTimer(500);while(ev=WaitForEvent()!=EXIT)switch(ev)case TIMER:/响应周期事件 break;case KEYDOWN:/响应按键按下事件 break;case KEYUP:/响应按键抬起事件 break;StopTimer();,建议:定时器函数可以用在动画输出部分,控制对电梯画面的刷新。,

    注意事项

    本文(程序设计实践-预处理和EGG库.ppt)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开