首页 程序设计实践6w-概要设计和模块化

程序设计实践6w-概要设计和模块化

举报
开通vip

程序设计实践6w-概要设计和模块化*提纲1.软件概要设计和模块化2.使用线程实现任务并发3.时间控制函数*概要设计和模块化 复杂的软件研发核心策略:分而治之、模块化设计与实现*3.概要设计要点 概要设计的目的: 全局把握程序结构:进行程序的模块划分,设计模块之间如何相互调用来完成程序要求的功能。 定义关键全局数据结构,包括全局变量,用来存储各模块共享的数据,以及定义全局常量。 设计系统的自动机模型,提前对关键的、较难解决的问题进行处理。*3.概要设计要点概要设计主要从以下几个方面考虑:用户界面:界面友好,要能从界面提示信息了解火车的状态和请求。自动...

程序设计实践6w-概要设计和模块化
*提纲1.软件概要设计和模块化2.使用线程实现任务并发3.时间控制函数*概要设计和模块化 复杂的软件研发核心策略:分而治之、模块化设计与实现*3.概要设计要点 概要设计的目的: 全局把握程序结构:进行程序的模块划分,设计模块之间如何相互调用来完成程序要求的功能。 定义关键全局数据结构,包括全局变量,用来存储各模块共享的数据,以及定义全局常量。 设计系统的自动机模型,提前对关键的、较难解决的问 快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题 进行处理。*3.概要设计要点概要设计主要从以下几个方面考虑:用户界面:界面友好,要能从界面提示信息了解火车的状态和请求。自动机模型:火车的行为可以用自动机模型来描述。绘制状态迁移图,图上需要描述引起状态迁移的条件,并且要在文档中附加说明进入某状态要做的动作。全局数据结构:包括全局变量和常量等,较全面地给出各个模块要共享的数据。程序模块化:函数接口说明,函数调用关系说明。*用户界面设计命令行版本,要求实现键盘输入、命令行输出,并将输出结果记录到文件。定义键盘输入格式定义屏幕输出格式定义输出文件名称和文件格式 动画版本,要求实现图形界面输入、动画输出,并将输出结果记录到文件。 画出图形化界面中各个要素(如按钮、输入框、输出动画等) 说明界面中的各种操作 定义输出文件名称和文件格式*自动机模型设计 针对“不同对象”,画出对应的状态迁移图汽车状态图(可分层次画出)交通灯状态图*第一层状态第二层:行驶状态细化�向东行驶向南行驶向西行驶向北行驶加速/减速南行北行西行静止行驶暂停启动停前行加速/减速红灯绿灯红灯周期到绿灯周期到全局数据结构设计设计所有或多个模块(函数)都需要用到的公共变量或者常量 全局常量定义 汽车运行方向常量设置#defineNORTH0#defineWEST1#defineSOUTH2#defineEAST3#defineSTOP4 交通灯当前颜色的状态常量设置 #defineRedS0// #defineGreenS1// *全局数据结构设计 全局变量定义structCarAuto_A;//汽车AstructCarAuto_B;//汽车B 全局数据结构定义 汽车的结构:包括汽车的状态(state)与汽车的坐标structCar{intstate;doublex,y;};*程序模块化设计 模块又称构件,在传统的 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 中指用一个名字就可调用的一段代码。类似于高级语言中的过程、函数等。 一个模块可以包含一个或多个函数。*程序模块化设计 C语言中的模块开发 C语言允许一个程序由多个源文件组成。当程序规模比较大时,可以根据模块化原则将程序分成多个.c源文件,每个源文件看作是一个模块,每个源文件中可包含一个或多个功能连接紧密的函数。 在编译该程序时,可以以源文件为单位分别进行编译,产生对应的目标文件,然后再用链接程序将多个目标文件链接成一个可执行文件。C语言的这种编译过程称为分块编译,这种开发方法称为分块开发*程序模块化设计 程序模块化设计应该说明程序的模块结构,包括: 整个程序分成哪几个模块(.C源文件)? 每一个文件里面包含哪些函数?函数原型说明。 图示说明模块间调用关系(即模块间函数的调用关系)。 *每个模块是一个.C文件程序模块化设计 在确定一个程序要划分成几个模块(源文件),每一个源文件要包含哪些函数时,需要以提高模块独立性为原则,将相关的功能放在一起,形成一个源文件。 原则:高内聚、低耦合*通常,一个程序包含如下几个部分: 输入处理:负责接收程序的输入信息,将其存储到内存。如键盘输入、图形化输入(鼠标点击等)、文件输入等。 输出处理:负责输出程序的结果信息。如屏幕输出、图形化输出(输出火车、输出轨道、输出探测点等)、文件输出等。 数据处理:负责对输入信息进行各种策略处理,将其转化为最终的结果信息。数据处理按照程序内部不同的子功能可划分成不同的独立子模块,如火车状态处理、火车控制策略、公共轨道状态处理等。 程序总调度:通常由主函数完成,单独一个模块。负责对以上所有模块按照一定顺序进行调度。*程序模块化设计*程序总调度输入处理输出处理数据处理模块接口说明*表2函数说明表1模块说明 模块文件 模块说明 模块包含的函数名 函数功能  XXX.c 功能说明  intfunction1(void)    voidfunction2 (float)   序号 函数原型 功能 参数 返回值 1  intfunction1(void)  何时何条件被何模块调用?完成什么功能? 参数描述   返回值描述   2 voidfunction2 (float)    参数描述   返回值描述*程序模块化设计概要设计报告1用户界面设计命令行方式、文件方式、动画方式2有限状态自动机状态转换图3高层数据结构定义包括:全局常量定义、全局数据结构定义4系统模块划分画出系统模块的调用关系图;并详细说明各个模块的功能。程序模块化设计 头文件的确定 把所有公用的类型定义(结构、联合或枚举声明),公用的宏定义放在适当的头文件中,供各个文件参考。 如果在许多地方都使用一个(些) 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 头文件,或者某个头文件本身需要,则可以把标准头文件包含到一个自己定义的头文件里供使用。 如果只有一个源文件需要某个标准头文件,则不要将它放在公共的头文件中,而是让这个源文件直接包含它,以提高编译效率。 对于所有在一个源文件里定义、而在其他文件中使用的东西(函数原型或者变量的外部声明),都需要在某个头文件中声明,以方便使用。*程序模块化设计源文件设计时要注意以下问题: 每个源文件只包含必要的头文件,不用的东西尽量不包含。 如果源文件既要包含标准头文件,又要包含自定义头文件,则应将标准头文件写在前面,以防止本程序的局部定义影响标准库文件里的定义。 在一个源文件中,所有局部的东西都写在各自的函数中;所有只在本文件范围内使用的外部变量和函数,都使用static关键字定义为外部静态的。 对于多个函数都需要访问的变量,应该根据谁使用谁管理的归属原则,分别定义为不同源文件里的外部变量。在许多文件中都使用的全局变量,一般在主程序文件里定义。*提纲1.软件概要设计和模块化2.使用线程实现任务并发3.时间控制函数*1.使用线程实现任务并发 问题的引出:以电梯控制系统为例 目前能想到的程序主体结构main(){while(1){state_trans();//计算此刻电梯的状态print_message();//输出电梯此刻的状态,包括动画get_input();//接收当前时刻的新输入(包括新目 标和新呼叫)control();/*根据控制策略确定下一目标楼层, 在state_trans()中要用到*/time_count();//时间片推进一个}} 思考:上述结构不合理之处?*1.使用线程实现任务并发 上述结构不合理之处:计算和输出电梯状态与接收服务请求是串行的,与现实中的电梯运行不符! 程序结构的改进: 从上述代码中删除get_input(),从而实现每隔一小段时间就刷新电梯当前状态main(){while(1){state_trans();//计算此刻电梯的状态print_message();//输出电梯此刻的状态 control();/*根据控制策略确定下一目标楼层,这 在state_trans()中要用到*/time_count();//时间片推进一个}}*1.使用线程实现任务并发 但是,程序必须要能接收电梯服务请求,如何处理服务请求的输入? 理想状态: 电梯服务请求的接收和电梯状态的计算输出能同时进行,互不影响 但是,能否实现? 答案是:使用线程电梯状态计算和输出共享内存区接收服务请求*1.使用线程实现任务并发进程 一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动,例如 用字处理软件编辑文稿时,同时打开mp3播放程序听音乐,这两个独立的程序在同时运行,称为两个进程 进程是资源申请、调度和独立运行的单位*1.使用线程实现任务并发 线程 线程是系统分配处理器时间资源的基本单元。对于操作系统而言,其调度单元是线程(为线程提供时间片,线程在自己的时间片内运行)。 一个程序中多段代码同时并发执行,称为多线程 譬如用word同时打开多个文档进行编辑,用IE浏览器同时访问多个网站 通过多线程,一个进程表面上看同时可以执行一个以上的任务——并发**线程(续) 一个进程至少包括一个线程(称为主线程)。一个进程从主线程的执行开始进而创建一个或多个附加线程,就是所谓基于多线程的多任务。 线程自己不拥有系统资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源*1.使用线程实现任务并发在C程序中要创建线程,可以调用Windows操作系统提供的创建线程的函数CreateThread:HANDLE CreateThread(  LPSECURITY_ATTRIBUTES lpThreadAttributes,   DWORD dwStackSize,   LPTHREAD_START_ROUTINE lpStartAddress,   LPVOID lpParameter,   DWORD dwCreationFlags,   LPDWORD lpThreadId);  LPVOID是一个Void类型的指针,也就是说你可以将任意类型的指针赋值给LPVOID类型的变量。DWORD是32位无符号整数。**LPVOID是一个Void类型的指针,也就是说你可以将任意类型的指针赋值给LPVOID类型的变量(一般作为参数传递),然后在使用的时候在转换回来DWORD是32位无符号整数1.使用线程实现任务并发 lpThreadAttributes表示创建线程的安全属性,NT下有用。可赋值为NULL。 dwStackSize指定线程栈的尺寸,如果为0则与进程主线程栈相同。 lpStartAddress指定线程开始运行的地址。赋值为指向函数的指针,即函数名。该函数的名称任意,但函数类型必须遵照下述声明形式: DWORDWINAPIThreadProc(LPVOIDlpParameter);否则需要进行强制类型转换 lpParameter表示传递给线程的32位的参数(数值或指针)。若无参数则赋值为NULL。 dwCreationFlags表示是否创建后挂起线程(取值CREATE_SUSPENDED表示挂起,取值0表示创建后立即运行),挂起后调用ResumeThread继续执行。若不挂起则赋值为0。 lpThreadId用来存放返回的线程ID。DWORDThreadID1=1;HANDLEhRead1=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)getInput, NULL,0,&ThreadID1);*#include<stdio.h>#include<windows.h>DWORDWINAPIFun1Proc(LPVOIDlpParameter);intmain(){ HANDLEhThreadl;//<1> hThreadl=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);//<2> CloseHandle(hThreadl);//<3> printf("mainthreadisrunning\n");//<4> return0;}*DWORDWINAPIFun1Proc(LPVOIDlpParameter){ printf("hThreadlisrunning\n"); return0;}例1*#include<stdio.h>#include<windows.h>DWORDWINAPIFun1Proc(LPVOIDlpParameter)intmain(){ HANDLEhThreadl;//<1> hThreadl=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);//<2> CloseHandle(hThreadl);//<3> printf("mainthreadisrunning\n");//<4>Sleep(10);//让线程睡眠10毫秒 return0;}例2#include<stdio.h>#include<windows.h>intindex=0;DWORDWINAPIFun1Proc(LPVOIDlpParameter);intmain(){ HANDLEhThreadl;//<1> hThreadl=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);//<2> CloseHandle(hThreadl);//<3> while(index++<1000) { printf("mainthreadisrunning\n");//<4> } return0;}*例3DWORDWINAPIFun1Proc(LPVOIDlpParameter){ while(index++<1000) { printf("hThreadlisrunning\n"); } return0;}**#include<stdio.h>#include<windows.h>inttickets=100;DWORDWINAPIFun1Proc(LPVOIDpPararneter){ while(tickets>0) printf(“thread1sellticket:%d\n”,tickets--); return0;}DWORDWINAPIFun2Proc(LPVOIDpPararneter){while(tickets>0)printf(“thread2sellticket:%d\n”,tickets--);return0;}intmain(){ HANDLEhThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); HANDLEhThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL); CloseHandle(hThread1); CloseHandle(hThread2); Sleep(4000); return0;}** 线程的同步 利用互斥对象(mutex)实现线程的同步,互斥对象能够确保线程拥有对单个资源的互斥访问权。 3个操作 互斥对象的创建 互斥对象的释放 互斥对象的请求*互斥对象的创建 HANDLECreateMutex(LPSECURITY_ATTRIBUTESlpMutexAttributes,BOOLbinitialOwner,LPCTSTRlpNarne) lpMutexAttributes:可以给该参数传递NULL值,让互斥对象使用默认的安全性 binitialOwner:BOOL类型,指定互斥对象初始的拥有者。如果该值为真,则创建这个互斥对象的线程获得该对象的所有权;否则,该线程将不获得所创建的互斥对象的所有权。 lpName:指定互斥对象的名称。如果此参数为NULL.则创建一个匿名的互斥对象。如果调用成功,该函数将返回所创建的互斥对象的句柄*互斥对象的释放 BOOLReleaseMutex(HANDLEhMutex); ReleaseMutex函数只有一个HANDLE类型的参数,即需要释放的互斥对象的句柄。该函数的返回值是BOOL类型,如果函数调用成功,返回非0值;否则返回0值。*互斥对象的请求 DWORDWaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds); Handle:所请求的互斥对象的句柄。一旦互斥对象处于有信号状态,则该函数就返回。如果该互斥对象始终处于无信号状态,即未通知的状态,则该函数就会一直等待,这样就会暂停线程的执行。 dwMilliseconds:指定等待的时间间隔,以毫秒为单位。如果指定的时间间隔己过,即使所请求的对象仍处于无信号状态,WaitForSingleObject函数也会返回。如果将此参数设置为0,那么WaitForSingleObject函数将测试该对象的状态并立即返回;如果将此参数设置为INFINITE,则该函数会永远等待,直到等待的对象处于有信号状态才会返回。 调用WaitForSingleObject函数后,该函数会一直等待,只有在以下两种情况下才会返回:1)指定的对象变成有信号状态。2)指定的等待时间间隔己过。*HANDLEhMutex;inttickets=100; DWORDWINAPIFun1Proc(LPVOIDpPararneter){ while(tickets>0) { WaitForSingleObject(hMutex,INFINITE); if(tickets>0) printf("thread1sellticket:%d\n",tickets--); ReleaseMutex(hMutex); } return0;}*DWORDWINAPIFun2Proc(LPVOIDpPararneter){ while(tickets>0) { WaitForSingleObject(hMutex,INFINITE); if(tickets>0) printf("thread2sellticket:%d\n",tickets--); ReleaseMutex(hMutex); } return0;}*intmain(){ HANDLEhThread1,hThread2; hMutex=CreateMutex(NULL,FALSE,NULL); hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL); CloseHandle(hThread1); CloseHandle(hThread2); Sleep(4000); return0;}*线程在电梯控制系统中的使用 考虑现实中安装在电梯上的软件:接收电梯服务请求和计算电梯状态、从而控制电梯的运行是并行的 因此我们可以考虑在模拟电梯控制系统中设计一个线程专门用于接收电梯服务请求,另一个线程实行电梯的状态计算和状态输出电梯状态计算和输出线程共享内存区接收服务请求电梯状态计算和输出:从共享内存区读取电梯请求,计算下一目标楼层,从而确定电梯的下一状态。接收服务请求:接收电梯请求,将请求保存到内存。*//主线程main(){DWORDThreadID;//创建线程(对应于函数input()),用于接收电梯输入;HANDLEhRead=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)getInput,NULL,0,&ThreadID);//进行变量初始化工作线程在电梯控制系统中的使用*while(1){state_trans();();//根据自动机模型决定此刻电梯的状态print_message();/*输出电梯此刻的状态*/control();/*根据控制策略确定下一目标楼层,这在 state_trans()中要用到*/time_count();/*时间片推进一个*/}}线程在电梯控制系统中的使用*//接收输入线程voidgetInput(void){charch;while(1){ ch=getchar();//加入代码:将ch 翻译 阿房宫赋翻译下载德汉翻译pdf阿房宫赋翻译下载阿房宫赋翻译下载翻译理论.doc 成相应请求并保存;time_count();//时间片推进一个;}}线程在电梯控制系统中的使用*提纲1.软件概要设计和模块化2.使用线程实现任务并发3.时间控制函数*4.1-计时函数while(1){state_trans();();//根据自动机模型决定此刻电梯的状态print_message();/*输出电梯此刻的状态*/control();/*根据控制策略确定下一目标楼层,这在 state_trans()中要用到*/time_count();/*时间片推进一个*/}}*4.1-计时函数 clock_tclock(void);ANSI标准库中的time.h头文件,其中定义了日期和时间的处理函数。 这个函数返回从“启动程序”到“程序中调用clock()函数”之间的CPU时钟计时单元(clocktick)数,在MSDN中称之为挂钟时间(wal-clock)。其中clock_t是用来保存时间的数据类型,长整型。 clocktick:CPU时钟计时单元,时间长短由CPU控制。一个clocktick不是CPU的一个时钟周期,而是C/C++的一个基本计时单位。 常量CLOCKS_PER_SEC,它表示一秒钟会有多少个时钟计时单元。 可以使用 公式 小学单位换算公式大全免费下载公式下载行测公式大全下载excel公式下载逻辑回归公式下载 clock()/CLOCKS_PER_SEC来计算一个进程自身的运行时间。*4.1-计时函数 #include“stdio.h”#include“stdlib.h”#include“time.h”intmain(void){   long    i=10000000L;   clock_tstart,finish;   double  duration;   /*测量一个事件持续的时间*/   printf(“Timetodo%ldemptyloopsis”,i);   start=clock();   while(i--)      ;//什么都不做   finish=clock();   duration=(double)(finish-start)/CLOCKS_PER_SEC;   printf("%fseconds\n",duration);   system("pause");}*4.1-计时函数下述循环将持续运行1秒钟clock_tstart,finish;doubleduration;start=clock();duration=0.0;while(duration<1.0){ finish=clock(); duration=(double)(finish-start)/CLOCKS_PER_SEC;}*4.2-线程休眠函数 线程休眠函数:Sleep(int); Sleep(1000)Windows下表示1000毫秒,也就是1秒钟;Linux下表示1000秒,Linux下使用毫秒级别的函数可以使用usleep。 Sleep函数是使调用Sleep函数的线程休眠,线程主动放弃时间片。当经过指定的时间间隔后,再启动线程,继续执行代码。Sleep函数并不能起到定时的作用,主要作用是延时。#include<stdio.h>#include<windows.h>//注意头文件一定要包含intmain(){ inti=9; while(i>1){ Sleep(1000);//线程被挂起1秒,相当于机器运行到这里停顿1秒,再继续向下运行;printf("A"); i--;} system("pause");return0;}****LPVOID是一个Void类型的指针,也就是说你可以将任意类型的指针赋值给LPVOID类型的变量(一般作为参数传递),然后在使用的时候在转换回来DWORD是32位无符号整数
本文档为【程序设计实践6w-概要设计和模块化】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_597436
暂无简介~
格式:ppt
大小:783KB
软件:PowerPoint
页数:0
分类:建筑/施工
上传时间:2020-09-18
浏览量:11