文档库 最新最全的文档下载
当前位置:文档库 › 面向对象程序设计实验指导书版

面向对象程序设计实验指导书版

LIAOCHENG UNIVERSITY

面向对象程序设计实验指导书

聊城大学计算机学院

2011年3月

目录

《面向对象程序设计》课程实验教学大纲 (1)

实验一C++对C的扩充 (1)

基本信息 (1)

实验预习 (1)

实验过程 (2)

实验数据和实验结果记录 (8)

实验结果分析 (8)

实验二类和对象 (8)

8

8

9

13

13

13

13

13

14

19

19

19

19

19

20

36

36

37

37

37

37

38

38

《面向对象程序设计》课程实验教学大纲

课程名称:面向对象程序设计

英文名称:Object Oriented Programming

设置形式:非独立设课课程模块:专业核心课实验课性质:专业基础实验课程编号:609324

课程负责人:王玉亭大纲主撰人:王玉亭

大纲审核人:左风朝

一、学时、学分

课程总学时:54 实验学时:16课程学分:3二、适用专业及年级

根据学生实验出勤情况、实验态度、实验报告成绩、实验考核成绩等评定实验成绩。实验报告(含实验理论)占实验成绩的30%,实验技能(含实验态度)占实验成绩的30%,实验考核占实验成绩的40%。最终实验成绩占该课程考核总成绩的20%—30%。

七、实验教科书、参考书

1.实验教科书

自编实验指导书。

2.实验参考书

实验一C++对C的扩充

基本信息

实验课程:面向对象程序设计设课形式:非独立

课程学分:2 实验项目:C++对C的扩充

项目类型:基础项目学时:2

实验预习

并打印分解

米,宽4米

重复进行,小孩数不断减少,圈子也不断缩小。最后所剩的那个小孩就是胜利者。

请找出这个胜利者。

4、编写程序实现五子棋棋游戏。五子棋的规则为:双方各执一色棋子,轮流下

子(将子放在棋盘的任一未下子的点上),直到有一方的棋子有5个排成一线(无论是横、竖还是斜均可),则棋局结束,该方胜利。

实验条件:

1、装有Windows操作系统的微型计算机;

2、Eclipse集成开发环境和CDT插件;

3、MinGW编译环境。

实验设计方案:

1、熟悉在Eclipse集成开发环境下编辑、编译、连接和运行C++程序的方法。

2、借助流程图对程序进行“自顶向下、逐步求精”的结构化分析。

3、熟悉C++中const、引用、new、delete的用法。

4、利用“筛法”生成素数表。

5、实现模拟仿真要利用随机值函数。

实验过程

1、根据实验预习阶段的实验设计方案,编写应用程序。参考代码如下。

#include

#include

const int M = 10001; // 定义验证范围

// 函数CreatPrimeList(): 生成素数表

void CreatPrimeList(int *PrimeList, int n)

{

int i, j;

// 将PrimeList的各元素设置为从0开始的正整数

for (i = 0; i < n; i = i + 1)

{

PrimeList[i] = i;

}

// 分别从表中去掉已经确定的各素数的倍数(将其置为0)

i = 2;

while (i <= sqrt(n))

{

for (j = i + 1; j < n; j = j + 1)

{

if (PrimeList[j] != 0 && PrimeList[j] % PrimeList[i] == 0)

{

PrimeList[j] = 0;

}

}

// 确定下一个素数的位置

i = i + 1;

while (PrimeList[i] == 0)

{

i = i + 1;

}

}

}

// 函数NextPrimeNumber(): 求下一个素数

int NextPrimeNumber(int p, int *PrimeList)

{

p = p + 1;

while (PrimeList[p] == 0)

{

p = p + 1;

}

return PrimeList[p];

}

// 主函数: 在从4到M的范围内验证哥德巴赫猜想

int main()

{

int PrimeList[M]; // 说明存放素数表的数组

int x, p; // 变量x: 偶数, p: 素数

// 建立素数表

CreatPrimeList(PrimeList, M);

// 对从4到M的所有偶数验证哥德巴赫猜想

x = 4;

while (x < M)

{

// 检查偶数减去一个素数后的剩余部分是否仍为素数

p = PrimeList[2];

while (p <= x / 2 && PrimeList[x - p] == 0)

{

p = NextPrimeNumber(p, PrimeList);

}

// 输出检查结果

if (p > x / 2) // 找到了一个不能分解为两个素数和的偶数

{

std::std::cout << "Great discovery: Goldbach is wrong!" << std::endl;

}

else// PrimeList[x-p]≠0, 分解成功

{

std::std::cout << "The even number " << x << "=" << p << " + " << x - p

<< std::endl;

}

// 检查下一个偶数

x = x + 2;

}

return 0;

}

2、根据实验预习阶段的实验设计方案,编写应用程序。参考代码如下。#include

#include

#include

#include

const int SHIP = 1;

const int BAR = 2;

const int WATER = 3;

//一个醉酒者行为的模拟仿真

int drunkard()

{

int x = -10; //记录醉酒者的x坐标,开始时在酒馆门口

int y = 0; //记录醉酒者的y坐标,开始时在跳板的中央

int step = 0; //记录醉酒者一共走了多少步

while (abs(x) <= 10 && abs(y) <= 2)

{

switch (rand() % 10)

{

case 0: //向左走

y = y - 1;

break;

case 1: //向右走

y = y + 1;

break;

case 2: //向后走

x = x - 1;

break;

case 3: //向前走

case 4:

case 5:

case 6:

case 7:

case 8:

case 9:

x = x + 1;

}

step = step + 1;

}

if (x < -10)

{

std::std::cout << "After " << step

<< " steps, the man returned to the bar and drunk again"

<< std::endl;

return BAR;

}

else

{

if (x > 10)

{

std::cout << "After " << step << " steps, the man returned to the ship"

<< std::endl;

return SHIP;

}

else

{

std::cout << "After " << step << " steps, the man dropped into the water"

<< std::endl;

return WATER;

}

}

}

//反映若干个醉酒者最终行为的模拟仿真的主函数

int main()

{

srand(time(0)); //初始化随机种子

int drunkardnumber; //醉酒者总数

int shipnumber = 0; //到达船上的人数

int barnumber = 0; //返回酒馆的人数

int waternumber = 0; //掉进水中的人数

std::cout << "Please input the number of drunkard" << std::endl;

std::cin >> drunkardnumber;

for (int i = 0; i < drunkardnumber; i = i + 1)

{

switch (drunkard())

{

case SHIP:

shipnumber = shipnumber + 1;

break;

case BAR:

barnumber = barnumber + 1;

break;

case WATER:

waternumber = waternumber + 1;

break;

}

}

std::cout << "******************************" << std::endl;

std::cout << "Of all the " << drunkardnumber << " drunkards:" << std::endl;

std::cout << shipnumber << " returned to the ship" << std::endl;

std::cout << barnumber << " went to the bar and drunk again" << std::endl;

std::cout << waternumber << " dropped into the water" << std::endl;

return 0;

}

3、根据实验预习阶段的实验设计方案,编写应用程序。参考代码如下。#include

int main()

{

const int Total = 7; //小孩总数,可以改动。

int ChooseNum; //用户随机选取的数

int boy[Total]; //表示小孩的数组

for (int i = 0; i < Total; i++)

boy[i] = i + 1; //给小孩编号

}

std::cout << " Please input the number which is to be eliminated: ";

std::cin >> ChooseNum; //用户随机输入一个剔除的数

std::cout << " Before eliminating, the boys are:" << std::endl;

for (i = 0; i < Total; i++)

{

std::cout << boy[i] << "\t";

}

std::cout << std::endl;

int k = 1; //第k个离开的小孩

int n = -1; //数组下标,下一个为0表示从第一个孩子开始数数

while (true)

{

//在圈中开始剔除

for (int j = 0; j < ChooseNum;)

{

n = (n + 1) % Total;

if (boy[n] != 0) //如果该小孩还在圈中,则参加计数

{

j++;

}

}

if (k == Total) //如果已经全部剔除完成,则跳出循环

{

break;

}

boy[n] = 0;

std::cout << "After " << k << " times elimination, the boys left are:"

<< std::endl;

for (i = 0; i < Total; i++)

{

if (boy[i] != 0)

{

std::cout << boy[i] << "\t";

}

}

std::cout << std::endl;

k++;

}

// break语句跳转至此,输出胜利者编号

std::cout << "The No." << boy[n] << " boy is the winner." << std::endl;

return 0;

}

4、根据实验预习阶段的实验设计方案,编写应用程序。参考代码如下。#include

#include

const int M = 7; //规定棋盘大小

const int N = 5; //玩几子棋

void InitChess(char*);

void HumanMove(char*);

void ComputerMove(char*);

void ShowChess(char*);

char WinCheck(char*);

int main()

{

char *chess = new char[M * M];if( NULL == chess )

{

return 0;

}

char done;

std::cout<<"---Game of Chess---"<

std::cout<<"Human against the stupid computer"<

done ='*';

InitChess(chess);

do

ShowChess(chess);

HumanMove(chess);

done = WinCheck(chess); //检查是否有赢家

if(done!= '*')

{

break; //如有赢家,则跳出循环

}

ComputerMove(chess);

done = WinCheck(chess); //检查是否有赢家}while(done== '*');

ShowChess(chess); //显示棋局最终状态

if(done=='H')

{

std::cout<<"Human won!"<

}

else

{

std::cout<<"Computer won!!!!"<

}

delete[] chess;

return 0;

}

//初始化棋盘

void InitChess(char *chess)

{

for (int i = 0; i < M; i++)

{

for (int j = 0; j < M; j++)

{

chess[i + M * j] = '*';

}

}

}

//下棋人的落子

void HumanMove(char *chess)

{

int x, y;

std::cout << "Enter X,Y coordinates for your move: ";

std::cin >> x >> y;

std::cout << std::endl;

x--;

y--;

if (chess[x + M * y] != '*')

{

std::cout << "Invalid move, try again." << std::endl;

HumanMove(chess);

}

else

chess[x + M * y] = 'H';

}

//计算机落子

void ComputerMove(char *chess)

{

int i, j;

for (i = 0; i < M; i++)

{

for (j = 0; j < M; j++)

{

if (chess[i + M * j] == '*')

{

break;

}

}

if (chess[i + M * j] == '*')

{

break;

}

}

if (i * j == M * M)

{

std::cout << "Diamond cut diamond" << std::endl;

exit(0);

}

else

{

chess[i + M * j] = 'C';

}

}

//在屏幕上显示棋局

void ShowChess(char *chess)

{

for (int i = 0; i < M; i++)

{

for (int j = 0; j < M; j++)

{

std::cout << chess[i + M * j] << "\t";

}

std::cout << std::endl << std::endl;

}

}

//检查是否有赢家

char WinCheck(char *chess)

{

for (int i = 0; i < M; i++)

{

for (int j = 0; j < M; j++)

{

char t = chess[i + M * j];

int count = 1;

for (int a = i + 1, b = j + 1;

chess[a + M * b] == t && a < M && b < M; a++, b++)

{

count++;

}

if (count >= N)

{

return t;

}

count = 1;

for (a = i, b = j + 1; chess[a + M * b] == t && b < M; b++)

{

count++;

}

if (count >= N)

{

return t;

}

count = 1;

for (a = i + 1, b = j; chess[a + M * b] == t && a < M; a++)

{

count++;

}

if (count >= N)

{

return t;

}

count = 1;

for (a = i + 1, b = j - 1; chess[a + M * b] == t && a < M && b >= 0;

a++, b--)

{

count++;

}

if (count >= N)

{

return t;

}

}

}

return'*';

}

实验数据和实验结果记录

根据程序运行情况如实记录实验结果。

实验结果分析

1、分析生成素数表的“筛法”。

2、分析机构化程序设计方法。

3、写出自己的心得体会。

实验二类和对象

基本信息

实验课程:面向对象程序设计设课形式:非独立

课程学分:3 实验项目:类和对象

项目类型:基础项目学时:4

实验预习

实验目的和要求:

1、掌握声明类的方法,类和类的成员的概念以及定义对象的方法。

2、初步掌握用类和对象编制基于对象的程序。

3、学习检查和调试基于对象的程序。

4、掌握类的构造函数和析构函数的概念和使用方法。

5、掌握对象数组、对象的指针及其使用方法。

实验内容和原理或涉及的知识点:

1、用类实现顺序栈。

2、用类实现循环队列栈。

3、实现一个带有头结点的单链表,该链表可以插入整型元素。

实验条件:

1、装有Windows操作系统的微型计算机;

2、Eclipse集成开发环境和CDT插件;

3、MinGW编译环境。

实验设计方案:

1、熟悉C++程序中源文件的组织方式。

2、首先分析类的属性和行为,然后通过封装实现类。

3、实现栈时,考虑栈容量的自动增长问题。

实验过程

1、根据实验预习阶段的实验设计方案,编写应用程序。参考代码如下。

//Stack.h的内容

#ifndef STACK_H_

#define STACK_H_

class Stack

{

int *m_Elem;

int m_nTop;

const int m_nSize;

public:

Stack(int size) :

m_nTop(0), m_nSize(size)

{

m_Elem = new int[size];

}

~Stack()

{

delete[] m_Elem;

}

bool IsEmpty()

{

return m_nTop == 0;

}

bool IsFull()

{

return m_nTop == m_nSize;

}

bool Push(int e);

bool Pop(int &e);

};

#endif/* STACK_H_ */

//Stack.cpp的内容

#include"Stack.h"

bool Stack::Push(int e)

{

if (IsFull())

{

return false;

}

else

{

m_Elem[m_nTop] = e;

++m_nTop;

return true;

}

}

bool Stack::Pop(int &e)

{

if (IsEmpty())

{

return false;

}

else

{

--m_nTop;

e = m_Elem[m_nTop];

return true;

}

}

2、根据实验预习阶段的实验设计方案,编写应用程序。参考代码如下。//Queue.h的内容

#ifndef QUEUE_H_

#define QUEUE_H_

class Queue

{

int front, rear

int *data;

const int size;

public:

Queue(int s) :

front(0), rear(0), size(s)

{

data = new int[size + 1];

}

bool IsEmpty()

{

return rear == front;

}

bool IsFull()

{

return (rear+1)%(size+1) == front;

}

bool EnQueue( int v );

bool DeQueue( int &v );

~Queue()

{

delete[] data;

}

};

#endif/* QUEUE_H_ */

//Queue.cpp的内容

#include"Queue.h"

bool Queue::EnQueue(int v)

{

if (IsFull() == true)

{

return false;

}

else

{

data[rear] = v;

rear = (rear + 1) % (size + 1);

return true;

}

}

bool Queue::DeQueue(int &v)

{

if (IsEmpty() == true)

{

return false;

}

else

{

v = data[front];

front = (front + 1) % (size + 1);

return true;

}

}

3、根据实验预习阶段的实验设计方案,编写应用程序。参考代码如下。//list.h的内容

#ifndef LIST_H_

#define LIST_H_

#include

#include

class List//定义整型链表类

{

private:

class Node

{

public:

Node(const int &data = 0, Node *next = NULL) :

m_nData(data), m_pNext(next)

{

}

Node *m_pNext; //指向下一个结点的指针成员

int m_nData; //指向本结点数据的指针成员

};

public:

List(); //构造函数

~List(); //析构函数

bool Append(const int &e, int index = 0); //在inedex位置后增加节点bool Prepend(const int &e, int index = 1); //在inedex位置前增加节点bool Remove(int &e, int index = 1); //删除inedex位置处的节点

bool Find(int &e, int index = 1); //查找inedex位置处的节点

void PrintList(); //打印链表

protected:

Node *m_pFirst; //头节点

};

#endif/* LIST_H_ */

//List.cpp的内容

#include"List.h"

List::List() //构造函数

{

m_pFirst = new Node();

}

List::~List() //构造函数

{

Node * p = m_pFirst;

Node * q;

while (NULL != p) //寻找inedex位置前一个节点

{

q = p;

p = p->m_pNext;

delete q;

}

}

bool List::Append(const int &e, int index) //在inedex位置后增加节点{

if (index < 0)

{

return false;

}

Node *p = m_pFirst;

int i = 0;

while (NULL != p && i < index) //寻找inedex位置处节点

{

++i;

p = p->m_pNext;

}

if (NULL == p)

{

return false;

}

Node *q = new Node(e, p->m_pNext);

p->m_pNext = q;

return true;

}

bool List::Prepend(const int &e, int index) //在inedex位置前增加节点{

if (index < 1)

{

return false;

}

Node *p = m_pFirst;

int i = 0;

while (NULL != p && i < index - 1) //寻找inedex位置前一个节点{

++i;

p = p->m_pNext;

}

if (NULL == p)

{

return false;

}

Node *q = new Node(e, p->m_pNext);

p->m_pNext = q;

return true;

}

bool List::Remove(int &e, int index) //删除inedex位置处的节点

{

if (index < 1)

{

return false;

}

Node *p = m_pFirst;

int i = 0;

while (NULL != p && i < index - 1) //寻找inedex位置前一个节点{

++i;

p = p->m_pNext;

}

if (p == NULL || NULL == p->m_pNext)

{

return false;

}

Node *q = p->m_pNext;

p->m_pNext = q->m_pNext;

e = q->m_nData;

delete q;

return true;

}

bool List::Find(int &e, int index) //查找inedex位置处的节点

{

if (index < 1)

{

return false;

}

Node *p = m_pFirst;

int i = 0;

while (NULL != p && i < index) //寻找inedex位置处节点

{

++i;

p = p->m_pNext;

}

if (NULL == p)

{

return false;

}

e = p->m_nData;

return true;

}

void List::PrintList() //打印链表

{

Node *p = m_pFirst->m_pNext;

while (NULL != p) //寻找inedex位置处节点

{

std::cout << p->m_nData << '\t';

p = p->m_pNext;

}

std::cout << std::endl;

}

//main.cpp的内容

int main()

{

List l;

l.Append(1);

l.Prepend(10);

int s;

l.Find(s, 2);

l.Remove(s, 2);

l.PrintList();

return 0;

}

实验数据和实验结果记录

根据程序运行情况如实记录实验结果。

实验结果分析

1、分析C++程序原文件的组织方式。

2、分析new和delete的用法。

3、对抽象技术和封装技术进行分析。

4、写出自己的心得体会。

实验三继承和组合

基本信息

实验课程:面向对象程序设计设课形式:非独立

课程学分:3 实验项目:继承和组合项目类型:基础项目学时:4

实验预习

实验目的和要求:

1、了解继承在面向对象程序设计中的重要作用。

2、进一步理解继承与派生的概念。

3、掌握通过继承派生出一个新的类的方法。

4、了解虚基类的作用和用法。

5、掌握类的组合。

实验内容和原理或涉及的知识点:

1、上机分析实例程序,理解继承的概念。

2、上机分析实例程序,理解继承下构造函数和析构函数的执行顺序。

3、声明一个Shape(形状)基类,它有两个派生类:Circle(圆)和Square

(正方形)。

要求:(1)根据给出的圆心坐标和半径计算圆的面积;(2)根据给出的正方形中点坐标和一个顶点坐标计算正方形的面积。提示:Shape类的数据成员包括中心点的坐标,Circle类中新增一个数据成员,即圆的半径,Square类新增一个顶点的坐标。

4、编程实现单件模式,理解静态成员。

5、某出版系统发行图书和磁带,利用继承设计管理出版物的类。要求如下:建

立一个基类Publication存储出版物的标题title、出版物名称name、单价price 及出版日期date。用Book类和Tape类分别管理图书和磁带,它们都从Publication 类派生。Book类具有保存图书页数的数据成员page,Tape类具有保存播放时间的数据成员playtime。每个类都有构造函数、析构函数,且都有用于从键盘获取数据的成员函数inputData(),用于显示数据的成员函数display()。

实验条件:

1、装有Windows操作系统的微型计算机;

2、Eclipse集成开发环境和CDT插件;

3、MinGW编译环境。

实验设计方案:

1、进一步熟悉C++程序中源文件的组织方式。

2、首先分析类之间的继承组合,然后实现类。

实验过程

1、上机分析下面程序,理解继承的概念。

//头文件person.h的内容

#include

#include

class Person

{

private:

char m_strName[20];

int m_nAge;

int m_nSex;

public:

Person(); //构造函数

Person(const char *name, int age, char sex); //构造函数

Person(const Person &p); //拷贝构造函数

~Person() //析构函数

{

std::cout << "Now destroying the instance of Person" << std::endl;

}

void SetName(const char *name);

void SetAge(int age);

void setSex(char sex);

const char* GetName() const;

int GetAge() const;

char GetSex() const;

void ShowMe() const;

};

//源程序文件person.cpp的内容:

#include"person.h"

Person::Person() :

m_nAge(0), m_nSex(0) //构造函数

{

strcpy(m_strName, "XXX");

}

Person::Person(const char *name, int age, char sex) :

m_nAge(age), m_nSex(sex == 'm' ? 0 : 1) //构造函数

{

strcpy(m_strName, name);

}

Person::Person(const Person &p) :

m_nAge(p.m_nAge), m_nSex(p.m_nSex) //拷贝构造函数

{

strcpy(m_strName, p.m_strName);

}

void Person::SetName(const char *name)

{

strcpy(m_strName, name);

}

void Person::SetAge(int age)

{

m_nAge = age;

}

void Person::setSex(char sex)

{

m_nSex = sex == 'm' ? 0 : 1;

}

const char* Person::GetName() const

{

return m_strName;

}

int Person::GetAge() const

{

return m_nAge;

}

char Person::GetSex() const

{

return (m_nSex == 0 ? 'm' : 'f');

}

void Person::ShowMe() const

{

std::cout << GetName() << '\t' << GetAge() << '\t' << GetSex() << '\t';

}

//头文件employee.h的内容:

#include"person.h"

class Employee: public Person//雇员类定义

{

char m_strDept[20]; //工作部门

float m_fSalary; //月薪

public:

Employee();

《面向对象程序设计》课程实验指导书

Employee(const char *name, int age, char sex, const char *dept,

float salary);

Employee(const Employee &e);

~Employee()

{

std::cout << "Now destroying the instance of Employee" << std::endl;

}

void SetDept(const char *dept);

void SetSalary(float salary);

const char* GetDept() const;

float GetSalary() const;

void ShowMe() const; //显示雇员信息

};

//源程序文件employee.cpp的内容:

#include"employee.h"

Employee::Employee() :

m_fSalary(0.0)

{

strcpy(m_strDept, "xxxx");

}

Employee::Employee(const char *name, int age, char sex, const char *dept,

float salary) :

Person(name, age, sex), m_fSalary(salary)

{

strcpy(m_strDept, dept);

}

Employee::Employee(const Employee &e) :

Person(e.GetName(), e.GetAge(), e.GetSex()), m_fSalary(e.m_fSalary)

{

strcpy(m_strDept, e.m_strDept);

}

void Employee::SetDept(const char *dept)

{

strcpy(m_strDept, dept);

}

void Employee::SetSalary(float salary)

{

m_fSalary = salary;

}

const char* Employee::GetDept() const

{

return m_strDept;

}

float Employee::GetSalary() const

{

return m_fSalary;

}

void Employee::ShowMe() const

{

Person::ShowMe();

std::cout << m_strDept << "\t" << m_fSalary << std::endl;

}

//源程序文件main.cpp的内容:

#include"employee.h"

int main()

{

Employee emp1;

emp1.ShowMe();

Employee emp2("张莉", 40, 'f', "图书馆", 2000);

emp2.ShowMe();

std::cout << "调用基类GetName()返回值为: " << emp2.GetName() << std::endl;

return 0;

}

2、上机分析下面程序,理解继承下构造函数和析构函数的执行顺序。#include

相关文档
相关文档 最新文档