C++程序设计-第15周 数据结构扩展与GUI开发体验

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565

【目的】

1. 体验用面向对象的方法操作数组和动态链表
2. 体验窗口程序的实现

第一部分 引言
  大学中的学习死守着课本非常的没有劲。我不是说课本和课堂没用,而是说在课内的学习之余要有所拓展和扩充。大学的课程(和课本)成为一个体系,受到各种因素的制约,势必会形成一个框框,所涉及的内容可能就会形成“铁路警察,各管一段”的局面。课程和课本是有局限的,采用的是“统一”的体系,而各人形成自己的知识体系却是各有特色的。这是大学学习自由的一部分。
  大学生对课程的学习,要习惯于超越“老师讲过的”和“考试要考的”,按照学科(而不是有限学时的课程)和工程需求(而不是仅某门课程中狭窄的知识面)去学,要找到除了考试以外的目标。这个寻找和转变的过程中可能会遇到不少的困难,但却是必须的。其实,转变其实也并不难,也没有诀窍,尝试、体验、总结,直至将新的状态成为自然。
  本周的任务就基于这样的考虑。项目1-3体验用面向对象的方法操作数组和动态链表,代表的是将来在工程中更实用的对数据的操纵方法,项目4体验利用VS2008或VC++6.0中提供的向导,体验窗口程序的开发,而后会发现,我们在C++程序设计中所学的,也正是编程中的核心。

第二部分 实践项目
【项目1】建立专门的数组类处理有关数组的操作
  数组是几乎所支持的组织数据的方法。C和C++对数组类型提供了内置支持,使我们利用数组实现软件中需要的各种实用的功能。但是,这种支持仅限于用来读写单个元素的机制。C++不支持数组的抽象abstraction,也不支持对整个数组的操作。例如:把一个数组赋值给另外一个数组,对两个数组进行相等比较或者想知道数组的大小size,等等。对C++而言,数组是从C语言中继承来的,它反映了数据与对其进行操作的算法的分离,有浓厚的过程化程序设计的特征。数组并不是C++语言的一等公民。所以在实际项目中,对一个C++程序员,更多的是使用标准库中提供的Vector类型实现数组功能。这个任务也将从面向对象角度重新审视和理解数组,进而扫清自学Vector等标准类中可能存在的障碍。
  在下面代码的基础上,完成支持数组操作的类的设计,增强C++内置数组类型功能。

class MyArray
{
private:
    int *arr;		//用于存放动态分配的数组内存首地址
    int size;		//数组大小
public:
    MyArray(int sz=50);
    MyArray(int a[],int sz);	//由一个内置类型的数组初始化
    MyArray(const MyArray &A);	//复制构造函数
    ~MyArray(void);				//析构函数,注意释放空间
    MyArray&operator =(const MyArray &A); //重载“=”使得数组对象可以整体赋值
    bool operator == (MyArray& A);	//重载==,使得Array对象能整体判断两个数组是否相等(size相等且对应元素相等)
    friend ostream& operator << (ostream& out,MyArray& A);	//重载<<,输出数组
    int GetSize(void) const;	//取数组大小;
};
//以下为类成员函数的定义
……
//测试函数
int main()
{
    int a[10]= {1,2,3,4,5,6,7,8,9,10};
    int b[10]= {4,5,6,7,8,9,10,11,12,13};
    MyArray arr1(a,10);  //测试用内置的数组初始化新定义的数组对象
    MyArray arr2(b,10);
    MyArray arr3(10);   //测试只指定大小的新数组对象的初始化
    cout<<arr1;    //测试对<<的重载
    cout<<arr2;    //测试对<<的重载
    cout<<arr3;    //测试对<<的重载
    cout<<"The size of arr1 is: "<<arr1.GetSize()<<endl;   //测试GetSize()成员函数
    return 0;
}

【项目1扩展1(选做)】在MyArray基础上增加下面的成员或友元函数,扩充MyArray类的功能,并修改main函数完成测试。

//重载[],使得Array对象也可以如C++普通数组一样,用a[i]形式取出值【选做】
int& operator[](int i);
//重载+,使两个Array对象可以整体相加(前提大小相等)【选做】
MyArray operator + (MyArray& A);
//修改数组的大小,如果sz大于数组的原大小,增加的元素初始为;如果sz大于数组的原大小,舍弃后面的元素【选做】
void Resize(int sz);

【项目1扩展2(选做)】规定MyArray只能处理元素为整型的数据未免太弱了,请设计成模板类,使之适应各种类型(事实上,C++增加的标准类对些类情况均设计成了模板类)。
【项目1扩展3(选做)】可以施加于数组的操作还有很多,例如最经典的排序,还有求最大、最小、查找某一元素、截取其中的片段(取从第5个互第10个之间的所有元素,可以形成新的数组对象)、向量乘法,……。将这些操作构造为类的成员函数,开始拓展之旅吧!

【项目2】建立专门的链表类处理有关动态链表的操作
  动态链表也是程序设计中的一种非常有用的数据结构。可以说,是否能够理解有关操作的原理,决定了你是否有资格称为“科班”出身。在后续的专业基础课中,相关的内容还会从不同的角度,反复地认识,反复地实践。不过,在现阶段多些体验,也是很有必要的了。
  先阅读下面的程序,回顾一下动态链表,阅读程序过程中,请用笔画一画形成链表的过程中指针值的变化。

#include <iostream>
using namespace std;
struct Student
{	int num;
	double score;
	struct Student *next;
};
int main( )
{	Student *head=NULL,*p,*q;
	//建立动态链表
	for(int i=0;i<3;i++)
	{
		p = new Student;
		cin>>p->num>>p->score;
		p->next=NULL;
		if (i==0) head=p;
		else q->next=p;
		q=p;
	}
	//输出动态链表
	p=head;
	while(p!=NULL)
	{	cout<<p->num<<" "<<p->score<<endl;
		p=p->next;
	}
	return 0;
}

  上面一段代码产生的链表形如:

  

  现在我们通过下面的任务,用面向对象的程序设计的思维看待最简单的动态链表,初步体验有关的操作。

  现在,请在已有代码的基础上完善程序,完成动态链表的简单操作,程序运行的截图供参考。

class Student  //结点类
{
public:
	Student(int n,double s){num=n;score=s;next=NULL;}
	~Student();
	Student *next;   //指向下一个结点
	int num;
	double score;
};

class MyList  //链表类
{
public:
	MyList(){head=NULL;}
	MyList(int n,double s); //以Student(n,s)作为单结点的链表
	~MyList();
	int display();  //输出链表,返回值为链表中的结点数
	void insert(int n,double s);  //插入:将Student(n,s)结点插入链表,该结点作为第一个结点
	void append(int n,double s);  //追加:将Student(n,s)结点插入链表,该结点作为最后一个结点
	void cat(MyList &il); //将链表il连接到当前对象的后面
	int length();  //返回链表中的结点数
private:
	Student *head;   //链表的头结点
};
//以下为类成员函数的定义
……
//测试函数
int main()
{
	int n;
	double s;
	MyList head1;
	cout<<"input head1: "<<endl;  //输入head1链表
	for(int i=0;i<3;i++)
	{
		cin>>n>>s;
		head1.insert(n,s);  //通过“插入”的方式
	}
	cout<<"head1: "<<endl; //输出head1
	head1.display();

	MyList head2(1001,98.4);  //建立head2链表
	head2.append(1002,73.5);  //通过“追加”的方式增加结点
	head2.append(1003,92.8);
	head2.append(1004,99.7);
	cout<<"head2: "<<endl;   //输出head2
	head2.display();

	head2.cat(head1);   //把head1追加到head2后面
	cout<<"length of head2 after cat: "<<head2.length()<<endl;
	cout<<"head2 after cat: "<<endl;   //显示追加后的结果
	head2.display();
	return 0;
}

  运行结果示例:

  

【项目2扩展一(选做)】项目2中的结点只处理包含包含学号和分数的学生信息。如何将之用于其他应用?结点类Students也可换作描述其他事物的类。请设计建立一个动态链表,其中有5个结点,分别描述5个三角形,从头结点开始,逐个输出三角形的信息。
【项目2扩展二(选做)】上面的处理,仍然不够抽象,所以,只能就事论事地做,这是设计的大忌。实际上,结点的类型可以定义为以下模板类:

template <class T>
class Node
{
public:
	Node *next;
	T data;
};

  这样,“一劳永逸”地解决了data的类型,只要在定义类时,对T进行实例化即可。在这里,T类型中也不需要涉及有关链表中指针的内容。
  请按这种思路重写程序,为了测试,在main()函数中建立一个MyArray<double>型对象进行测试。另外,再建立一个MyArray<Triangle>型对象进行测试(Triangle为自定义三角形类)。

【项目2扩展三(选做)】本任务实现的是最简单的单向链表中的最基本的操作。从链表的类型上,还可以有双向链表(有头结点和尾结点,方便从前往后和从后往前的访问)、十字链表等,类似的方法可以构造二叉树、多叉树、图(例如,计算机网络结构可以抽象描述为图,社交网络中用户的关系也是图,顶有用的结构)。从操作角度,单链表在插入时,可以让结点保持有序;可以从链表中查找元素;很多的应用中涉及的算法需要借助于数据结构和算法的设计获得最佳的处理性能。关于这方面的内容不再以具体任务的形式给出,在后续的专业基础课中将会逐渐引出。另外,有程序设计基础,同学们是可以自己往前走一走,找相关的教材和书籍(数据结构、算法类)看一看,是否能依靠自己的力量往前走一走了。

【项目3】Josephus(约瑟夫环)问题

  n个小孩子围成一圈,从第一个小孩子开始顺时针方向数数字,到第m个小孩子离开,这样反反复复,最终只剩下一个小孩子,求第几个小孩子留下?
  提示:约瑟夫环即是一个首尾相连的链表,在建立好这个环以后,从头结点开始,每次间隔m孩子删除一个结点,直至只余下一个结点(删除了n-1个)。

  
  参考下面的代码,也可以自行设计类。

//链表结点kid,其中number为这个人的编号
struct kid
{
    int number;
    kid *next;
};

//约瑟夫环类
class joseph_ring
{
private:
    int n;//用于存放人数
    int m;//用于存放初始密码
    kid *head;//链表的头结点,初始化时指向1号孩子
public:
    joseph_ring(int nn, int mm);//创建nn个孩子,间隔为mm的约瑟夫环
    ~joseph_ring();
    void show();//运算并输出的成员函数
};
//定义joseph_ring类中的成员函数
……
int main()
{
    int n,m;
    cout<<"n=";
    cin>>n;
    cout<<"m=";
    cin>>m;
    joseph_ring j(n,m);
    j.show();
    return 0;
}

【项目4】窗口程序体验
  阅读《C++“窗口”程序设计启蒙(之二)》,按照示例的提示完成三角形面积的求解器。如果不方便使用VS2008,要在VC++6.0下进行实践体验,请看《C++“窗口”程序设计启蒙(之一)》,类似方法完成。
  要完成的任务:
  1、以示例为基础,为应用程序增加求周长的功能;
  2、设计分数类,开发一个窗口式程序,可以完成分数的四则运算。可供参考的一个界面如下图,在报告中展示主要的代码。

  拓展(选做):将上面的输入运算符的编辑框换为下拉列表框,使之只能选“+-*/”。 
  3、(选做)自己设计窗口布局,做一个利息计算器窗口程序。不一定用面向对象的编程(如《C++“窗口”程序设计启蒙(之一)》),完成功能即可。

  关于项目4的说明:本项目目标仅在于同学们进行体验。从本项目中可以看出利用向导和可视化界面,自动生成部分代码的开发方法,这可以极大的减轻开发工作量,提供了一个应用程序的框架,这是在工程中非常有利的。在专业的开发中,如果用本项目的“拖”控件方式,C#已经提供了更为方便的操作。但这种方法有时缺乏灵活性,开发出的代码没有特色,只能够满足一般性的要求,更专业的开发要求技术人员掌握MFC,直接利用类族中提供的继承关系进行开发。另外,现在已经有不少比MFC更加优秀的类库可供使用,这将作为进一步学习有关的开发技术需要解决的问题。

  

时间: 2024-11-08 21:13:42

C++程序设计-第15周 数据结构扩展与GUI开发体验的相关文章

C++程序设计-第15周数组上机实践项目

回到课程主页,链接:C++程序设计课程主页-2012级 本次上机对应的教学内容:第5章   数组 - 二维数组.字符串 [项目1-折腾二维数组]创建一个长度为5行4列的二维整型数组,通过初始化,为数组中的前两列的10个元素赋初值,然后通过键盘输入,使后两列的10个元素获得值,将所有元素值乘以3后保存在数组中.输出数组时,按行序优先输出,再按列序优先输出(输出的第一行是数组中的第一列--,其实输出的就是"转置"),再将数组"倒"着输出(即最后一行最后一列的最先输出,第

C++程序设计-第17周指针上机实践项目

回到课程主页,链接:C++程序设计课程主页-2012级 本次上机对应的教学内容:第6章 指针 指针和数组,指针和字符串等 [项目1-体会函数参数传递]1.下面三段程序都试图通过定义函数,实现实际参数在必要时的交换,哪些能够实现,哪些不能实现?通过运行程序和单步执行,让自己对这一过程更加清楚,然后请在博文中给出明确的回答,并用你自己的话展开描述(自己的话,但要用术语,用术语讲技术的事,是必须经历的一个过程.) (1) #include <iostream> using namespace std

C++程序设计-第16周字符数组及指针上机实践项目

回到课程主页,链接:C++程序设计课程主页-2012级 本次上机对应的教学内容:第5章   数组 - 字符数组,第六章 指针 指针的基本概念 第一部分 程序分析 阅读下面的程序,先写出其运行结果,再上机运行进行对比.必要时,单步执行程序,在监视(watch)窗口中观察变量的动态变化,从而掌握程序的运行机理. (1) #include <iostream> using namespace std; void prt(int*, int*, int*); int a=10, b=40, c=20;

GPS北斗双模技术应用开发研究—数据结构扩展

 GPS北斗双模技术应用开发研究-数据结构扩展             还是从gps.h头文件入手,首先 GpsSvStatus结构体需要改造,GpsSvStatus当时设计的时候是考虑存储gps卫星信息的,但是我们现在是要存储双模的数据,因此我们需要扩展这个数据结构,那怎么扩展呢?   当然要代价小一点,不能完全推倒重来的,笔者想到的就是增加一个北斗卫星数量的变量,以及北斗的epemeris.almanac.还有一个定位的mask,以前数据结构里面的成员全部用着gps存储,这样就相互独立了,但

股票基金撤资62亿15周新高

[本报讯](记者 涂若奔)虽然全球经济有回暖迹象,但不少投资者已成为「惊弓之鸟」,稍有风吹草动立刻将资金撤出套现.美国投资公司协会最新公布截至6月24日数据显示,上周投资者总共从股票共同基金中撤出8.02亿美元(约62.55亿港元),数额之多创最近15周之最.此外,瑞银报告指当前除日本外亚洲股市偏贵,吸引力已较低.有分析指,投资者信心仍未恢复,全球股市不排除会再次走跌. 投资者成「惊弓之鸟」 据美国投资公司协会公布,8.02亿美元资金主要从美国国内股票基金中撤出,数额达到6.66亿美元,其余则为

15 个必须知道的 chrome 开发工具技巧

在Web开发者中,Google Chrome是使用最广泛的浏览器.六周一次的发布周期和一套强大的不断扩大开发功能,使其成为了web开发者必备的工具.你可能已经熟悉了它的部分功能,如使用console和debugger在线编辑CSS.在这篇文章中,我们将分享15个有助于改进你的开发流程的技巧. 一.快速切换文件 如果你使用过sublime text,那么你可能不习惯没有Go to anything这个功能的覆盖.你会很高兴听到chrome开发者功能也有这个功能,当DevTools被打开的时候,按C

C++第15周项目4扩展——带姓名的多科成绩单

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565 [项目4-多科成绩单]用二维数组score[][4]保存同学们的高数.英语.C++成绩及总成绩(在此假设学生的学号为整型的连续值,用数组的行下标作学号).在此基础上,完成下面的操作:(1)设计输入成绩的函数,输入3科成绩后可以自动求出总分,并将数据全保存到数组中:(2)输出各门课及总分的最高成绩.最低成绩.平均成绩和成绩的标准偏差:(3)输出考得总分最高.最低同学的人数及

C++第15周项目1扩展1 -数组类

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565,本周题目链接:http://blog.csdn.net/sxhelijian/article/details/9018813 [项目1-扩展1]建立专门的数组类处理有关数组的操作项目1情况见:http://blog.csdn.net/sxhelijian/article/details/9052881 要求:在MyArray基础上增加下面的成员或友元函数,扩充MyArra

C++程序设计-第13周递归函数及银行系统程序设计上机实践项目

回到课程主页,链接:C++程序设计课程主页-2012级 本次上机对应的教学内容:第4章   递归函数.变量的作用域.存储类型 第一部分 练习+上机验证(不必提交上机报告) 阅读下列程序,写出程序的运行结果.上机时运行程序,与你的预期进行对照.理解. 提示:如果对运行结果不理解,请通过单步执行的手段跟踪理解. 1. 两个有递归函数的程序,要求按课堂演示,画出调用过程(1) #include <iostream> using namespace std; void f(int); int main