北京邮电大学信息与通信工程学院
计算机实习计划书
信息与通信工程学院20##级
20##年 暑期
1、教学目标
北京邮电大学信息与通信工程学院20##级暑期计算机实习,是在学习C++大学基础教程的基础上开设的,目的是使学生们进一步综合运用C++的基本概念和语法,学习C++面向对象的设计思想,并且初步学会MS Visual C++的集成开发环境的使用。
计算机实习的时间为两个星期,在这三星期内,学生们将学习复杂应用程序的设计和使用、文件流的读写、相关API的使用等,并提交一个完整的C++的作品。充分培养学生的合作意识,培养学生们发现问题、解决问题的能力,充分发挥学生的想象力、创造力,激发学生主动学习的潜能。
2、相关知识
2.1相关数据类型
实例使用的数据类型包含在库文件 <windows.h>中,该库文件主要用来描述windows环境下常用的数据结构,宏和其他数据类型。
2.1.1、相关数据结构
Ø HANDLE:句柄
实际上是一个无符号的整型数,作为窗口的唯一标识ID,控制台的黑屏也是一个窗口,也需要这样的一个HANDLE来标识。
Ø BOOL逻辑
实际结构:typedef int BOOL;
Ø BYTE字节
实际结构:typedef unsigned char BYTE;
Ø WORD字
实际结构:typedef unsigned short WORD;
Ø DWORD双字
实际结构:typedef unsigned long DWORD;
2.1.2、颜色标识
实例中用来描述颜色的数据结构是WORD,根据下列宏定义可以常用的各种前景色和背景色。
前景色:
Ø 红色:FOREGROUNT_RED
Ø 绿色:FOREGROUND_GREEN
Ø 蓝色:FOREGROUND_BLUE
Ø 颜色加重显示:FOREGROUND_INTENSITY
背景色:
Ø 红色:BACKGROUND_RED
Ø 绿色:BACKGROUND_GREEN
Ø 蓝色:BACKGROUND_BLUE
Ø 颜色加重显示:BACKGROUND_INTENSITY
根据系统提供的三元色进行组合,可以得到混合后的文本和背景颜色。
前景色:
Ø 黄色:FOREGROUNT_RED | FOREGROUND_GREEN
Ø 青色:FOREGROUNT_BLUE | FOREGROUND_GREEN
Ø 紫色:FOREGROUNT_BLUE | FOREGROUND_RED
Ø 白色:FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN
背景色:
Ø 黄色:BACKGROUNT_RED | BACKGROUNT _GREEN
Ø 青色:BACKGROUNT _BLUE | BACKGROUNT _GREEN
Ø 紫色:BACKGROUNT _BLUE | BACKGROUNT _RED
Ø 白色:BACKGROUNT _RED| BACKGROUNT _BLUE| BACKGROUNT _GREEN
2.2常用的系统函数
实例使用得系统函数大都来自文件<conio.h>,该文件包括控制台的键盘输入输出操作。常用的系统函数如下所示:
Ø kbhit()
检测是否有按键按下,系统函数直接调用。
Ø getch()
获取按键的值,但不在屏幕回显,系统函数直接调用。
Ø getche()
获取按键的值,但在屏幕回显,系统函数直接调用。
Ø Sleep(DWORD n)
使程序休眠n毫秒,系统函数直接调用。
Ø void srand(unsigned int seed )
随机数的种子函数。
Ø int rand()
产生伪随机数序列。
2.3教师的前期工作
鉴于学生们学习C++的时间较短,了解的相关知识相对较少,为了方便同学们快速上手进行编程,需要教师提前作一些准备工作。使用控制台编程需要了解很多复杂的系统函数,因此,教师提前将这些系统函数进行了加工,封装成简单的函数提供给学生调用,包含这些函数的文件如下:
这些文件由教师提供:
Ø 头文件 colorConsole.h(附件1)
Ø 源文件 colorConsole.cpp(附件2)
这两个文件中实现了下面两个函数,函数接口如下:
1)HANDLE initiate();
输入参数:无
输出参数:HANDLE
函数功能:初始化控制台窗口,并获取该窗口的句柄;该函数只在程序初始化时执行一次。
2)BOOL textout(HANDLE hOutput, int x, int y, WORD wColors[],int nColors, LPTSTR lpszString );
输入参数: 窗口句柄 HANDLE hOutput
设置窗口横坐标 int x
设置窗口列坐标 int y
设置文本和背景色序列 WORD wColors[]
设置颜色序列的数目 int nColors
设置输出的字符串 LPTSTR lpszString )
输出参数:true 表示执行成功,false表示失败
函数功能:在控制台窗口指定的(x,y)位置输出指定颜色的字符串。
实际编程中,学生们需要按照以下步骤进行:
1、 将colorConsole.h文件添加到新建的工程中
2、 将colorConsole.cpp文件添加到当前工程中
3、 新建一个源文件main.cpp,将#include “colorConsole.h”自己编写主程序中的代码调用封装后的,极大的简化了编程难度。
2.4编程技巧
2.4.1、显示彩色字符串
编程步骤:
1)初始化获取窗口句柄
2)设置颜色
3)设置坐标
4)输出指定字符串
例1:显示红蓝相间的彩色字符串Happy Birthday!
void main(void)
{
HANDLE handle;
handle = initiate();
WORD wColors[2];
wColors[0]=FOREGROUND_RED|FOREGROUND_INTENSITY;
wColors[1]=FOREGROUND_BLUE;
textout(handle,10,10,wColors,2,"Happy Birthday!");
}
2.4.2、闪烁的彩色文字
闪烁原理:
1)写一遍彩色文字
2)延时200ms
3)写一遍空文字
4)延时100ms
反复该过程,则文字不断闪烁。
例2:彩色字符串Happy Birthday!不断闪烁
void main(void)
{
HANDLE handle;
handle = initiate();
WORD wColors[2];
wColors[0]=FOREGROUND_RED|FOREGROUND_INTENSITY;
wColors[1]=FOREGROUND_BLUE;
while(1)
{
textout(handle,10,10,wColors,2,"Happy Birthday!");
Sleep(200);
textout(handle,10,10,wColors,2, " ");
Sleep(100);
}
}
2.4.3、移动的彩色文字
移动原理:
1)写一遍彩色文字
2)延时100ms
3)写一遍空文字
4)改变坐标位置
反复该过程,则文字不断移动。
例3:水平移动彩色字符串Happy Birthday!
void main(void)
{
HANDLE handle;
handle = initiate();
WORD wColors[2];
wColors[0]=FOREGROUND_RED|FOREGROUND_INTENSITY;
wColors[1]=FOREGROUND_BLUE;
for(int x=0; x<65 ; row++)
{
textout(handle,x,10,wColors,2,"Happy Birthday!");
Sleep(100);
textout(handle,x,10,wColors,2," ");
}
}
2.4.4、检测键盘输入
检测原理:
1)检测是否有按键
2)有:键盘处理
3)无:屏幕处理
反复该过程,则文字不断移动。
例4:移动字符串的过程中,按下任意键暂停,再次按下时继续移动
void main(void)
{
HANDLE handle;
handle = initiate();
WORD wColors[2];
wColors[0]=FOREGROUND_RED|FOREGROUND_INTENSITY;
wColors[1]=FOREGROUND_BLUE;
int x=0;
bool flag=false;
while(x<65)
{
if (_kbhit())
{
_getch();
flag=!flag;
textout(handle,x,10,wColors,2,"Happy Birthday!");
}
if (flag)
{
textout(handle,x,10,wColors,2,"Happy Birthday!");
Sleep(100);
textout(handle,x,10,wColors,2," ");
x++;
}
}
}
3、教师范例
3.1范例题目一
制作一个投骰子游戏。程序运行界面如图1所示。
图1 筛子游戏界面
3.1.1程序功能
如图1所示:
Ø 游戏运行,可以显示不同点数的筛子;
Ø 游戏开始,按下“回车键”,则筛子随机出现不同的点数,产生动画效果;
Ø 按下“回车键”,筛子停止变化,记录点数;
Ø 按下“空格键”,更换游戏者,重复上述2、3步骤;
Ø 按下“q键”,游戏结束。
该游戏可以多人参加,每人可以投多次,每人每次的筛子点数自动累加,点数最高者胜。
3.1.2实现步骤
1)搭建程序框架
Ø 新建一个空的工程,工程名称game;
Ø 将colorConsole.h(附件1)和colorConsole.cpp(附件2)拷贝到工程当前目录,添加到工程中;
Ø 新建一个主文件main.cpp,将#include “colorConsole.h”代码添加到main.cpp中。
2)代码实现(源代码见附件3)
Ø 一个辅助函数
void rolldice(HANDLE hOutput, int n, int col , int row, WORD wColors[]);
输入参数:
输出屏幕:hOutput
筛子点数:n
屏幕位置:列col行row
文字颜色:wColors[]
输出参数:
无
功能:
在屏幕指定位置输出指定点数和指定颜色的筛子
Ø 主函数
功能:检测按键,根据不同的按键实现不同的功能,算法思想如下面的为代码所示。
void main()
{
屏幕初始化;
显示6个黄色的不同点数的筛子;
在屏幕底部显示菜单;
while(1)//游戏开始
{
if (检测到按键)
{
if(检测是否按下“回车键”)
{
标志位取反;
if(当前标志为false)
{
停止投筛子;
显示当前点数的筛子;
rolldice(handle,i+1,row,col,wColors);
记录并显示游戏者和点数;
}
}
else if (检测是否按下“空格键”)
{
计数器清零;
游戏者人数加1;
}
else if (检测是否按下“q或Q键”)
break;
}
if (标志位是true)
{
随机投筛子;
}
}
}//游戏结束
3)程序编译调测运行
不需要额外的设置,常规调试运行即可。
3.2范例题目二
制作一个指法测试游戏。程序界面如图2所示。
图2 指法测试游戏
3.2.1程序功能
如图2所示:
Ø 游戏运行,可以显示5行40列的随机字符;
Ø 按下“任意键”,游戏开始,开始计时;
Ø 从左到右,键入字符,如果与相应位置显示的字符相同,则正确字符数加1,否则错误字符数加1;
Ø 1分钟后程序自然停止,统计正确/错误字符数;并弹出窗口询问是否继续
该游戏可以用于自测指法,在规定时间内正确字符数越多,则指法越好。
3.2.2实现步骤
1)搭建程序框架
Ø 新建一个空的工程,工程名称Finger;
Ø 将colorConsole.h(附件1)和colorConsole.cpp(附件2)拷贝到工程当前目录,并添加到工程中;
Ø 新建一个主文件main.cpp,将#include “colorConsole.h”代码添加到main.cpp中。
2)代码实现
Ø 辅助变量
const int TOP = 4;
const int LEFT = 10;
const int RIGHT = 62;
const int BOTTOM = 20;
const int TIME = 60;
char ch[5][40]={0}; //产生5行40列随机字符
Ø 六个辅助函数
1、void init (HANDLE handle)
输入参数:输出屏幕:handle
输出参数:无
功 能:初始化界面
2、void randCharacter (HANDLE handle)
输入参数:输出屏幕:handle
输出参数:无
功 能:产生5行40列随机的字符
3、void stat (HANDLE handle)
输入参数:输出屏幕:handle
输出参数:无
功 能:统计正确的字符数,并计时。
4、void clearScreem (HANDLE handle)
输入参数:输出屏幕:handle
输出参数:无
功 能:清屏,重新开始练习
5、int GetTime (HANDLE handle)
输入参数:输出屏幕:handle
输出参数:无
功 能:计算练习指法的时间
6、void WinOK (HANDLE handle)
输入参数:输出屏幕:handle
输出参数:无
功 能:确认对话框
Ø 主函数
功能:检测按键,根据不同的按键统计,算法思想如下面的为代码所示。
void main()
{
屏幕初始化;
窗口初始化;
产生随机字符;
输出菜单提示;
while(1) //测试开始
{
统计正确/错误字符数
loop:
一次测试结束,询问是否继续
if(否)
程序停止运行;
else if(是)
{
清屏;
重新产生随机字符
}
else
goto loop;
}
} //测试结束
3)程序编译调制运行
不需要额外的设置,常规调试运行即可。
4、实习要求
4.1基本要求
4.1.1、内容要求
作品的内容可以是下面4种中的任意一种:
Ø 可以制作一个小游戏,比如俄罗斯方块、贪吃蛇、时钟、投筛子等;
Ø 可以制作一个课件,比如模拟汉诺塔游戏的过程;
Ø 可以制作一个管理系统,比如学生成绩管理、学生基本信息管理等;
Ø 其它你认为有兴趣的作品。
4.1.2、作品功能要求
基本要求:
Ø 能够应用文件流进行磁盘文件的读写:比如游戏分数的保存等
Ø 能够应用面向对象的设计思想和方法
Ø 能够使用多文件结构
Ø 能够播放音频文件,增强游戏的效果
4.2可选课题
鉴于部分同学对于Windows编程非常感兴趣,并且C++基础较好,尝试完成下面的课题(选作可选课题中的任何一个,就不需要在做基本要求中的内容了)。
4.2.1、完成一个简单计算器
简单计算器的界面如图3所示,功能可以参见Windows操作系统的附件中的计算器的功能,能够完成基本的算术运算。
图3 简单计算器
研究步骤:
1) 学习Windows编程框架,了解消息机制
2) 学习各种控件的使用,尤其是对话框、按钮、编辑框等
3) 学习菜单的使用
4) 如果时间允许,可以将简单计算器,扩展为如图4所示的科学计算器。
图4 科学计算器
4.2.2、完成一个简单的信息管理系统
简单的信息管理系统主要能够完成对信息的读取、增、删、改、查、保存等功能,比如一个简单学生信息管理系统界面如图4所示,基本功能如下:
(1)读取文件中的学生信息,能够按照学生类别显示;
(2)能够增加、删除、修改学生信息
(3)能够按照学号精确查询学生信息
(4)能够统计不同类别、不同性别的学生人数
(5)更新后的学生信息数据保存在文件中
图5 简单学生管理系统
研究步骤:
1) 学习Windows编程框架,了解消息机制
2) 学习各种控件的使用,尤其是对话框、按钮、编辑框等
3) 学习菜单的使用
4) 学习IO流的使用
5) 可以对各种信息进行管理,比如学生成绩管理系统、通讯录、图书管理系统等
4.2.3、完成一个画图软件
简单的画图软件的形式和功能可以参考Windows操作系统中“附件”里的画图软件,如图6所示。
图6 画图软件
该软件能够完成如下基本功能:
(1)能够绘制直线、曲线;
(2)能够绘制各种形状,比如矩形、椭圆形等
(3)能够绘制各种实心形状,比如实心矩形、实心椭圆等
(4)能够添加文字
(5)能够设置不同的绘制颜色
研究步骤:
1) 学习使用单文档的(Single document)程序结构
2) 学习使用MFC中CDC类系列的使用,包括CPen类、CBrush类等
3) 学习使用鼠标消息处理函数的使用
4) 有能力的同学可以扩展画图软件的功能,比如能够显示磁盘上已有的图片文件、能够具备“橡皮擦”的功能,进行擦除、能够保存绘制后的图形等等
4.2.4、自选题目
学生根据自身的情况,可以自由选择感兴趣的题目,要求一要写出具体的想法以及预期完成的结果,二要征得实验教师的同意。
下面给出一些题目可供参考。
1) 可以实现一个简单的Windows游戏,比如:碰碰球游戏,游戏者可以控制木板的左右移动,迎接下落的小球,小球与模板碰撞后弹起,反复运行,直到小球下落后木板无法接起,游戏结束。参考程序如图7所示。
图7 碰碰球游戏
2) 可以实现Josephus问题的求解,Josephus问题是:n个小孩围成一圈,任意假定一个数m,从第一个小孩起,顺时针方向数,每数到第m个的小孩时,该小孩便离开。小孩不断离开,圈子中的人数不断减少,最后一个离开的小孩是胜利者,请问最后一个离开的小孩的编号?实现可参考程序如图8所示。
图8 Josephus问题的求解
3) 可以学习使用OpenGL等工具库实现一个动画制作,题目任意。
4) 可以学习数据库的使用,完成一个基于数据库的信息管理系统。
5) 可以学习Socket类的使用,完成一个基于网络的应用,比如一个即时消息系统、文件传输系统等。
6) 可以学习如何实现一个屏幕保护程序
7) 可以学习任何你感兴趣的相关程序设计的知识,完成一个完整的作品。
5、参考资料
可以参考以下资料。
1) vc经典教程.chm 电子版
2) C++到Visual C++ 6.0精彩100例,应甫臣、刘迎辉编,《电脑爱好者杂志出版社》,20##年
3) Visual C++ 课程设计案例精选,严华峰等编著,《中国水利水电出版社》,20##年
5、实验报告
实验报告由4部分组成,每部分的格式和要求如下:
第一部分:封皮,包括作品名称,学生姓名、班级、班内序号、学号。
第二部分:作品功能说明,包括作品界面、使用方法、程序执行效率等。
第三部分:程序设计说明,包括
1.程序总体框架或流程图,程序实现过程中的重点和难点
2.代码分析
如果使用面向过程的设计方法,包括功能模块划分、每个模块完成的功能、各关键函数之间的调用关系、关键函数的实现思路;
如果使用面向对象的设计方法,包括关键类的功能说明、各类之间的关系、类中关键函数的实现思想;
3.调试方法,以及调试中的问题及其解决方法
第四部分:总结,包括学习体会,程序目前的功能缺陷及下一步改进的思路,对于本次实习的意见等。
6、时间安排
本次计算机实习一共3周,从8月27日开始,至9月11日结束,期间集中授课两次,每位同学上机8次,每次4个小时,共32个小时。
集中授课主要讲解计算机实习需要的相关知识,以及上机过程中出现的问题。上机期间会有辅导教师随时现场辅导。
附件1
文件ColorConsole.h
#include <windows.h>
#include <iostream>
using namespace std;
HANDLE initiate();
BOOL textout(HANDLE hOutput,int x,int y,WORD wColors[],int nColors,LPTSTR lpszString);
附件2
文件colorConsole.cpp
#include "colorConsole.h"
HANDLE initiate()
{
HANDLE hOutput;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
return hOutput;
}
BOOL textout(HANDLE hOutput,int x,int y,WORD wColors[],int nColors,LPTSTR lpszString)
{
DWORD cWritten;
BOOL fSuccess;
COORD coord;
coord.X = x; // start at first cell
coord.Y = y; // of first row
fSuccess = WriteConsoleOutputCharacter(
hOutput, // screen buffer handle
lpszString, // pointer to source string
lstrlen(lpszString), // length of string
coord, // first cell to write to
&cWritten); // actual number written
if (! fSuccess)
cout<<"error:WriteConsoleOutputCharacter"<<endl;
for (;fSuccess && coord.X < lstrlen(lpszString)+x; coord.X += nColors)
{
fSuccess = WriteConsoleOutputAttribute(
hOutput, // screen buffer handle
wColors, // pointer to source string
nColors, // length of string
coord, // first cell to write to
&cWritten); // actual number written
}
if (! fSuccess)
cout<<"error:WriteConsoleOutputAttribute"<<endl;
return 0;
}
附件3
主文件 main.cpp
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include "colorConsole.h"
//投筛子
void rolldice(HANDLE hOutput,int n,int col,int row,WORD wColors[]);
void main(void)
{
HANDLE handle;
WORD wColors[1];
int row,col;
//初始化
handle = initiate();
//生成6个不同骰子
wColors[0]=FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY;
row=col=2;
for (int i=0;i<6;i++)
rolldice(handle,i+1,col,row+6*i,wColors);
//打印屏幕底部菜单
WORD wMenuColors[1];
wMenuColors[0]=FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY;
textout(handle,1,24,wMenuColors,1, "游戏规则:");
textout(handle,11,24,wMenuColors,1,"投掷开始/结束=ENTER;");
textout(handle,34,24,wMenuColors,1,"更换游戏者=空格;");
textout(handle,53,24,wMenuColors,1,"退出=q.");
bool flag=false;
int count=1;
int sum=0;
//随机数的种子
srand( (unsigned)time( NULL ));
col=15;
row=8;
//游戏开始
while(1)
{
if (_kbhit())
{
int ch=_getch();
if (ch==13)
{
flag=!flag;
if (!flag)
{
wColors[0]=FOREGROUND_RED|FOREGROUND_INTENSITY;
rolldice(handle,i+1,row,col,wColors);
//记录游戏者和点数
char buf[20];
itoa(count,buf,10);
textout(handle,1,13+2*count,wMenuColors,1,buf);
textout(handle,3,13+2*count,wMenuColors,1,"点数:");
sum+=i+1;
itoa(sum,buf,10);
textout(handle,9,13+2*count,wMenuColors,1,buf);
}
}
else if (ch==32)//更换游戏者
{
sum=0;
count++;
}
else if (ch=='q' || ch=='Q')
break;
}
if (flag)//随机投筛子
{
i=rand() % 6;
wColors[0]=FOREGROUND_RED|FOREGROUND_INTENSITY;
rolldice(handle,i+1,row,col,wColors);
Sleep(100);
wColors[0]=0;
rolldice(handle,i+1,row,col,wColors);
}
}
}
void rolldice(HANDLE hOutput,int n,int col ,int row,WORD wColors[])
{
switch(n){
case 1: textout(hOutput,row+1,col+1,wColors,1,"●");
break;
case 2: textout(hOutput,row+1,col, wColors,1,"●");
textout(hOutput,row+1,col+2,wColors,1,"●");
break;
case 3: textout(hOutput,row, col+2,wColors,1,"●");
textout(hOutput,row+1,col+1,wColors,1,"●");
textout(hOutput,row+2,col, wColors,1,"●");
break;
case 4: textout(hOutput,row, col, wColors,1,"●");
textout(hOutput,row, col+2,wColors,1,"●");
textout(hOutput,row+2,col, wColors,1,"●");
textout(hOutput,row+2,col+2,wColors,1,"●");
break;;
case 5: textout(hOutput,row, col, wColors,1,"●");
textout(hOutput,row, col+2,wColors,1,"●");
textout(hOutput,row+1,col+1,wColors,1,"●");
textout(hOutput,row+2,col, wColors,1,"●");
textout(hOutput,row+2,col+2,wColors,1,"●");
break;
case 6: textout(hOutput,row, col, wColors,1,"●");
textout(hOutput,row, col+1,wColors,1,"●");
textout(hOutput,row, col+2,wColors,1,"●");
textout(hOutput,row+2,col, wColors,1,"●");
textout(hOutput,row+2,col+1,wColors,1,"●");
textout(hOutput,row+2,col+2,wColors,1,"●");
break;
default:cout<<"投掷骰子失败!"<<endl;
}
}