VC++实验报告
班号:
学号:
姓名:
实验一VC++开发环境的熟悉和C++基础知识实验
一、实验目的
1. 掌握C++语言的特点。
2. 掌握C++的各种数据类型及基本运算。
3. 掌握C++各种控制结构及使用技巧。
4. 掌握C++的函数、数组、指针的相关概念和使用方法。
5. 灵活运用C++相关基础知识进行综合程序设计。
6. 回顾面向过程程序设计方法。
7. 熟悉Visual C++的开发环境
8.掌握用应用程序向导创建一个控制台应用项目的方法。
9.掌握源代码文件的新建、打开、保存和关闭等基本操作。
10.掌握Visual C++项目的编译、连接和执行。
11.掌握代码简单语法错误修正和调试的一般过程。
二、实验知识点概念
注意C++中同C的不同之处,包括数据类型,输入输出等相关的差异。
三、实验题目
1. 采用插入排序法,输入10个整数按升序排序后输出。要求编写一个通用的插入排序函数,它带有三个参数,第一个参数是含有n个元素的数组,这n要插入的整数。该函数的功能是将一个整数插入到数组中,然后进行排序。另外还需要一个用于输出数组元素的函数,要求每一行输出5个元素。
2. 有5个学生,每个学生的数据结构包括学号、姓名、年龄、C++成绩,数学成绩和英语成绩、总平均分,从键盘输入5个学生的学号、姓名、3门课的成绩,计算3门课的总平均分,最后将5个学生的数据输出。要求各个功能用函数实现。
3. 对程序加入断点简单调试。
四、程序思路)
五、程序源代码
第一题
Func.cpp:
#include <iostream>
using namespace std;
1
void InputNum(int *p)
{
int i;
cout<<"请输入个整数:"<<endl; for(i=0;i<10;i++)
{
cin>>*p;
p++;
}
p=p-10;
int j;
int k;
for(i=0;i<10;i++) {
for(j=i;j<10;j++) {
if(*(p+i)>*(p+j)) {
k=*(p+i);
*(p+i)=*(p+j); *(p+j)=k; }
}
}
for(i=0;i<10;i++)
{
cout<<*p<<' ';
p++;
}
cout<<endl;
}
void Output(int *p,int n) {
int i;
for(i=0;i<n;i++)
{
cout<<*p<<' ';
2
p++;
if(0==((1+i)%5))
cout<<endl;
}
}
void Find(int *p,int n,int x) {
int i;
for(i=n-2;i>=0;i--)
{
if((x<*(p+i)))
{*(p+i+1)=*(p+i);*(p+i)=x;}
}
}
#include <iostream>
using namespace std;
const int N=15;
void InputNum(int *) ;
void Output(int *p,int n) ;
void Find(int *p,int n,int x) ;
void main()
{
int Num[N];
int n(10);
int x;
InputNum(Num);
for(;N!=n;)
{
cout<<"请输入要插入的整数:"; cin>>x;
3
Num[n]=x;
n++;
Find(Num,n,x);
Output(Num,n);
cout<<endl;
}
getchar() ;
getchar() ;
}
2 第二题
stu.h:
#include <iostream>
using namespace std;
class stu
{
public:
char num[11];
char name[10];
int age;
int c;
int m;
int e;
float ave;
void input(int i)
{
cout<<"第"<<i+1<<"个同学:";
cin>>num>>name>>age>>c>>m>>e; }
void output()
{
cout<<num<<' '<<name<<' '<<age<<' ''<<ave<<' '<<endl;
}
4 <<c<<' '<<m<<' '<<e<<'
void c_ave()
{
ave=(float)((e+m+c)/3);
}
};
Main.cpp:
#include <iostream>
#include "stu.h"
using namespace std;
const int N=5;
void main()
{
stu s1[N];
int i;
cout<<"请输入学号,姓名,年龄,c++,数学,英语成绩:"<<endl; for(i=0;i<N;i++)
{
s1[i].input(i);
}
for(i=0;i<N;i++)
{
s1[i].c_ave();
}
cout<<"学号,姓名,年龄,c++,数学,英语成绩,平均成绩分别为:"<<endl; for(i=0;i<N;i++)
{
s1[i].output();
}
getchar();
getchar();
}
六、用户使用说明(输入 / 输出规定)
5
七、调试分析&运行结果
实验二Windows SDK程序设计
一、实验目的
1. 掌握Windows程序运行基本原理。
2. 掌握使用SDK(Windows API)方式编写Windows应用程序方法。
3. 掌握用应用程序向导创建一个Windows应用项目的方法。
二、实验知识点概念
Windows程序设计不同于DOS下的程序设计,它是一种事件驱动的程序设计模式,主要是基于消息的。
三、实验题目
编写一窗口应用程序,能实现简单的画线功能。
四、程序思路
1 窗口的创建:
(1)设计窗口类
(4)显示窗口
(3)创建窗口
(2)注册窗口类
五、程序源代码
/*----------简单画线窗口程序-----------------*/
#include <windows.h>
#include <stdio.h>
6
LRESULT CALLBACK WinStProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
HINSTANCE hInst;
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
wndcls.hIcon=LoadIcon(NULL,IDI_INFORMATION);
wndcls.hInstance=hInstance;
wndcls.lpfnWndProc=WinStProc;
wndcls.lpszClassName="实验二"; "
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls);
hInst=hInstance;
HWND hwnd;
hwnd=CreateWindow("实验二","实验二",WS_OVERLAPPEDWINDOW, 50,50,600,400,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
7
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
int xpos=0,xxpos=0,ypos=0,yypos=0;
LRESULT CALLBACK WinStProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps);
TextOut(hDC,0,0,"画线",strlen("画线"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否真的结束?","QUIT",MB_YESNO)) {
DestroyWindow(hwnd);
}
break;
case WM_LBUTTONDOWN:
xpos = LOWORD(lParam);
ypos = HIWORD(lParam);
break;
8
case WM_LBUTTONUP:
xxpos = LOWORD(lParam);
yypos = HIWORD(lParam);
HDC hDc;
hDc=GetDC(hwnd);
MoveToEx(hDc,xpos,ypos,NULL);
LineTo(hDc,xxpos,yypos);
ReleaseDC(hwnd,hDc);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
六、用户使用说明(输入 / 输出规定)
画线时,在窗口内,在起点位置按住鼠标左键,在结束位置松开鼠标左键
七、调试分析&运行结果
9
10
实验三 类和对象实验
一、实验目的
1. 掌握类的定义方法,能合理指定类中成员的访问权限。
2. 学习对象的说明和使用方法。
3. 灵活运用类和对象的相关知识进行综合程序设计。
二、实验知识点概念
类是对同一类事物的抽象描述,其数据成员用于描述该类事物的属性,成
员函数完成修改、获取属性值或实现基于属性的某些操作。类不占用存储空间。对象是类的实例,对象占用存储空间。C++中类与结构体并没有本质的区别,结构体中也可以定义成员函数,也可以指定各个成员的访问权限。两者的唯一差异在于:结构中成员的缺省访问权限是公有的,而类中成员的缺省访问权限是私有的。
三、实验题目
定义整数集合数set,该类包括以下数据成员:
int elem[N];
int num;
包含以下成员函数:
Set();//默认构造函数
Set(int a[],int s); //以数组a的元素和位置s构造一个集合
void empty();//清空集合
int isempty();//判断是否为空集合
int member(int a);//判断a是否为集合元素
int add(int a); //将a添加到集合中
int del(int a); //从集合中删除元素a
int equ(Set & set);//判断两个集合是否相等 Set intersection(Set & set);//求两个集合的交集
Set merge(Set & set);// 求两个集合的并集
void copy(Set & set);//集合复制
void disp();//输出集合元素
11
四、程序思路
1,定义类
2,定义成员函数
3,实例化对象
4,主函数中调用成员对数组进行操作
五、程序源代码
#include <iostream>
using namespace std;
#include <iostream>
using namespace std;
const int N=100;
class Set
{
public:
int elem[N]; //保存整数集合数据
int num; //记录数组中元素个数
Set(); //默认构造函数
Set(int a[],int s); //以数组a的元素和位置s构造一个集合 void empty(); //清空集合
int isempty(); //判断是否为空集合
int member(int a); //判断a是否为集合元素
int add(int a); //将a添加到集合中
int del(int a); //从集合中删除元素a
int equ(Set & set2); //判断两个集合是否相等
Set intersection(Set & set2);//求两个集合的交集 Set merge(Set & set2);// 求两个集合的并集
void copy(Set & set2);//集合复制
void disp(); //输出集合元素
};
Set::Set(){num=0;}
12
Set::Set(int a[], int s) {
num=0;
for(int i=0;i<s+1;i++) {
elem[num++]=a[i]; }
}
void Set::empty(){num=0;}
int Set::isempty() {
if(0==num)
return 1; else
return 0; }
int Set::member(int a) {
for(int i=0;i<num;i++) {
if(a==elem[i]) return 1; }
return 0;
}
int Set::add(int a) {
if(member(a)==0) {
elem[num++]=a; return 1; }
return 0;
}
int Set::del(int a) {
if(member(a)==0) return 0; if(isempty())
13
return 0;
int i=0;
for(;i<num;i++)
if(a==elem[i])
break;
for(;i<num-1;i++)
elem[i]=elem[i+1];
num--;
return 1;
}
int Set::equ(Set & set2)
{
if(num==set2.num)
{
for(int i=0;i<num;i++)
{
if(member(set2.elem[i])==0 ) return 0;
}
return 1;
}
else
return 0;
}
Set Set::intersection(Set & set2) {
Set set3;
for(int i=0;i<this->num;i++) {
if(1==set2.member(this->elem[i])) set3.add(this->elem[i]) ; }
return set3;
}
Set Set::merge(Set & set2)
{
Set set3(set2.elem,set2.num-1); for(int i=0;i<this->num;i++) {
14
if(0==set2.member(this->elem[i])) set3.add(this->elem[i]) ; }
return set3;
}
void Set::copy(Set & set2)
{
num=set2.num ;
for(int i=0;i<num;i++)
{
elem[i]=set2.elem[i];
}
}
void Set::disp ()
{
for(int i=0;i<num;i++)
cout<<elem[i]<<" ";
cout<<endl;
}
void main()
{
int a1[7]={1,2,4,3,5,7,8};
int a2[6]={1,-2,3,4,5,7};
Set set3(a1,3);
Set set(a1,4);
Set set2(a2,4);
cout<<"显示集合"<<endl<<" set元素:"; set.disp() ;
cout<<"set2元素:";
set2.disp() ;
cout<<"set3元素:";
set3.disp() ;
cout<<endl<<"set3是否为空集合:"; if(set3.isempty()==1)
cout<<"yes";
15
else
cout<<"no";
cout<<endl<<"清空集合set3";
set3.empty();
cout<<endl<<"set3是否为空集合:"; if(set3.isempty()==1)
cout<<"yes";
else
cout<<"no";
cout<<endl<<endl<<"5是否为集合set的元素:"; if(set.member(5)==1)
cout<<"yes";
else
cout<<"no";
cout<<endl<<endl<<"将添加到set中:"; set.add(7);
set.disp() ;
cout<<endl<<"set与set2交集:";
set3=set.intersection(set2);
set3.disp() ;
cout<<endl<<"set与set2并集:";
set3=set.merge(set2);
set3.disp() ;
cout<<endl<<"set2复制给set1:"<<endl; set.copy(set2);
cout<<" set元素:";
set.disp() ;
cout<<"set2元素:";
set2.disp() ;
getchar();
}
六、用户使用说明(输入 / 输出规定)
集合中,元素不重复,与位置无关
16
七、调试分析&运行结果
、
实验四 继承和派生实验
一、实验目的
继承与派生是面向对象的特性,是面向对象程序设计模拟客观世界的手段之一,通过实验要求掌握:
1. 掌握类的继承与派生关系及实现方法,理解类的层次结构。
2. 掌握派生类构造函数初始化基类成员和对象成员的方法。
3. 灵活运用继承和派生的相关知识进行综合程序设计。
二、实验知识点概念
类的继承是新的类从已有类那里得到已有的特性。从已有的类产生新类的过程就是类的派生。在继承过程中,原有的类或已经存在的用来派生新类的类称为基类或父类,而由已经存在的类派生出的新类则称为派生类或子类。 根据派生类所拥有的基类数目不同,可以分为单继承和多继承。一个类只有一个直接基类时,称为单继承;而一个类同时有多个直接基类时,则称为多继承。
17
三、实验题目
编写一个程序实现小型公司的工资管理。该公司主要有4类人员:经理、兼职技术人员、销售员和销售经理。要求存储这些人员的编号、姓名和月工资,计算月工资并显示全部信息。月工资计算办法是:经理拿固定月薪8000元,兼职技术人员按每小时100元领取月薪,销售员按该当月销售额的4%提成,销售经理即拿固定月工资也领取销售提成,固定月工资为5000元,销售提成为所管辖部门当月销售总额的5%。
四、程序思路
1.定义抽象类:工资管理 其中,
2派生类:经理,兼职技术人员,销售员,销售经理
3,定义指向抽象类的二维数组指针,实现对各个派生类及其各对象的操作 4,利用类的虚函数及纯虚函数实现不同类型员工工资计算,人数计算,输出等功能,对同一消息进行不同的响应
五、程序源代码
pay_class.h:
class pay
{
public:
int ID;//编号
char name[20];//名字
float salary;//工资
pay(){};
void input_ID_name();
virtual void input_more(){};
18
void output(); virtual void puttype(){}; virtual int getnum()=0; };
class mgr:public pay// 经理 {
public:
mgr(){ }
void input_more();
int getnum();
void puttype();
private :
static int num;
};
class tec:public pay// 技术人员{
public:
tec():pay_perhour(100){ } int getnum();
void input_more();
int hours;
void puttype();
private:
int pay_perhour;
static int num;
};
class sal:public pay 销售人员 public:
sal(){}
int getnum();
void input_more();
float sale;
void puttype();
private:
static int num;
};
19
class smg:public pay// 销售经理 {
public:
smg(){ }
int getnum();
void input_more();
float sale;
void puttype(){};
private :
static int num;
};
cliass_func.cpp:
#include <iostream>
using namespace std;
#include "pay_class.h"
void pay::input_ID_name()
{
cout<<"请输入编号和名字:"; cin>>ID>>name;
}
void pay::output()
{
cout<<" "<<ID<<" ""<<salary<<endl;
}
int mgr::num =0;
void mgr::puttype()
{cout<<"经理 :"<<endl;} void mgr::input_more()
{
salary=8000;
num++;
}
int mgr::getnum()
20 <<name<<"
{
return num;
}
void tec::input_more()
{
cout<<"请输入工作时间:";
cin>>hours;
salary=(float)pay_perhour*hours;//每小时元 num++;
}
int tec::getnum()
{
return num;
}
void tec::puttype()
{cout<<"兼职技术:"<<endl;}
int sal::getnum()
{
return num;
}
void sal::puttype()
{cout<<"销售人员:"<<endl;}
void sal::input_more()
{
cout<<"请输入销售额:";
cin>>sale;
salary=sale*0.04;
num++;
}
int smg::num =0;
void puttype()
{cout<<"销售经理:"<<endl;}
21
int smg::getnum()
{
return num;
}
void smg::input_more()
{ cout<<"请输入销售额:"; cin>>sale;
salary=sale*0.05+5000.0; num++;
}
global_fuc.cpp:
#include <iostream>
#include "pay_class.h"
using namespace std;
const int N=3;
pay **select(pay *pa[][N])
{
char type;
pay **p=NULL;
for (;p==NULL;)
{
cout<<"请选择员工职位:"; cin>>type;
switch(type)
{
case '1':
p=pa[0];
break;
case '2':
p=pa[1];
break;
case '3':
p=pa[2];
break;
22
case '4':
p=pa[3];
break;
default:cout<<"<<<<类型错误,请重新选择>>>>\n\n";
}
};
return p;
}
void creat_object(pay *pa[][N])
{
char an;
pay **pr;
pay *p=NULL;
cout<<"是否输入员工信息(y/n)";
cin>>an;
if('y'==an)
{
cout<<"1:经理 2:兼职技术员 3:销售员 4:销售经理"<<endl;
}
for(;an=='y';)
{
pr=select(pa);
p=*(pr+(pr[0])->getnum());
p->input_ID_name();
p->input_more();
cout<<"是否继续输入员工信息(y/n)";
cin>>an;
}
}
void display(pay *pa[][N])
{
char an;
23
int tnum;
pay **pr;
pay *p=NULL;
cout<<endl<<"是否显示员工信息(y/n):\n";
cin>>an;
if('y'==an)
{
cout<<"职位 编号 姓名 工资"<<endl; for(int i=0;i<4;i++)
{
pr=pa[i];
p=*pr;
pr[1]->puttype();
tnum=p->getnum() ;
for(int j=0;j<tnum;j++)
{pr[j]->output();}
}
}
}
main.cpp:
#include <iostream>//包含头文件
#include "pay_class.h"
using namespace std;
const int N=3;
pay **select(pay *pa[][N]);
void creat_object(pay *pa[][N]);
void display(pay *pa[][N]);
void main(
{
mgr mgrp[N];
tec tecp[N];
sal salp[N];
smg smgp[N];
pay *p_pay[4][N];
24
for(int i=0;i<N;i++) p_pay[0][i]=&mgrp[i]; for(int i=0;i<N;i++)
p_pay[1][i]=&tecp[i]; for(int i=0;i<N;i++)
p_pay[2][i]=&salp[i]; for(int i=0;i<N;i++)
p_pay[3][i]=&smgp[i];
creat_object(p_pay);
display(p_pay);
getchar();
}
六、用户使用说明(输入 / 输出规定)
七、调试分析&运行结果
运行结果:
25
实验五 多态性和虚函数实验
一、实验目的
1. 了解多态性在C++中的体现。
2. 掌握虚函数的应用。
3. 了解抽象类。
二、实验知识点概念
? 多态性
? 多态是指同样的消息被不同类型的对象接收时导致不同的行为,所谓消息是指对类的成员函数调用,不同的行为是指不同的实现,也就是调用了不同的函数。
? 多态性可分为四类:重载多态、强制多态、包含多态和参数多态。
? 多态从实现的角度来讲可以划分为两类:编译时的多态和运行时的多态。编译时的多态性是在编译的过程中确定了同名操作的具体操作对象,也就是通过重载函数来实现的。运行时的多态性是在程序运行过程中才动态地确定操作所针对的具体对象,就是用虚函数来实现的。 ? 虚函数
? 虚函数是重载的另一种表现形式,它是一种动态的重载方式,它提供了一种更为灵活的多态性机制。虚函数允许函数调用与函数体之间的联系在运行时才建立,也就是在运行时才决定如何动作,即所谓的“动态连接”。
? 一般虚函数成员的定义语法是:
? virtual 函数类型 函数名(形参表)
? 虚函数的定义实际就是在原有的普通函数成员前面使用virtual关键字来限定,虚函数声明只能出现在类定义中的函数原型声明中,而不能在成员的函数体中。
? 运行过程中的多态需要满足三个条件,首先类之间应满足赋值兼容规则,其二是要声明虚函数,第三是要由成员函数来调用或者是通 26
过指针、引用来访问虚函数。
?
三、实验题目
编写一个程序实现图书和杂志销售管理。当输入一系列图书和杂志销售记录后,将销售良好(图书每月售500本以上,杂志每月售2500本以上)的图书和杂志名称显示出来。
四、程序思路
1,定义 类
2,定义 派生类
3,主函数:
五、程序源代码
#include <iostream>
using namespace std;
const int B=5;
const int M=5;
class sale_manage
{
public:
char name[50];
int sale;
void input()/
{
cin>>name>>sale;
}
void output()
{
cout<<name<<endl;
}
virtual void ifgood()=0;
};
27
class magazine:public sale_manage {
public:
void ifgood()
{
if(sale>2500)
output();
}
};
class books: public sale_manage
{
public:
void ifgood()
{
if(sale>500)
output();
}
};
void main()
{
int i;
books book[B];
magazine mag[M];
cout<<"输入图书名及销售量:"<<endl; for(i=0;i<B;i++)
book[i].input();
cout<<"输入杂志名及销售量:"<<endl; for(i=0;i<M;i++)
mag[i].input();
cout<<"销售良好的图书及杂志:"<<endl; for(i=0;i<B;i++)
book[i].ifgood();
28
for(i=0;i<M;i++)
mag[i].ifgood();
getchar();
}
六、用户使用说明(输入 / 输出规定)
七、调试分析&运行结果、
实验六 Windows程序开发实验
一、实验目的
1、掌握使用Visual C++开发Windows程序的基本方法
2、理解Windows程序原理。
3、了解MFC类库及MFC应用程序框架。
二、实验知识点概念
1、Windows程序设计是基于事件驱动的程序设计模式。
2、类库是一个可以在应用程序中使用的互相关联的C++类的集合。与一般类库不同,Microsoft基本类库(MFC)是一个Windows应用程序框架,它定义了应用程序的结构并实现了标准的用户接口。MFC提供了管理窗口、菜单、 29
对话框的代码,可以实现基本的输入/输出和数据存储。
二、实验题目
1. 利用MFC应用程序向导分别生成单文档、多文档、对话框应用程序,观察三种应用程序分别有哪些类组成?这些类有什么作用,分别继承哪些MFC基类?
(1)单文档:
class CAboutDlg : public CDialog
class CMainFrame : public CFrameWnd
class CMy6单文档App : public CWinApp
class CMy6单文档Doc : public CDocument
class CMy6单文档View : public CView
(2)多文档:
class CAboutDlg : public CDialog
class CMainFrame : public CMDIFrameWnd
class C多文档App : public CWinApp
class C多文档Doc : public CDocument
class C多文档View : public CView
(3)对话框应用程序:
class CAboutDlg : public CDialog
class C对话框App : public CWinApp
class C对话框Dlg : public CDialog
作用:
CFrameWnd // Provides the functionality of a Windows single document interface (SDI) overlapped or pop-up frame window, along with members for managing the window.
CDialog // The base class used for displaying dialog boxes on the screen. CMDIFrameWnd // Provides the functionality of a Windows multiple document interface (MDI) frame window, along with members for managing the window.
CWinApp //The base class from which you derive a Windows application object.
CDocument // Provides the basic functionality for user-defined document classes.
CView // Provides the basic functionality for user-defined view classes.
2. 创建一个单文档工程项目,在该项目中添加一个口令对话框(如图所示),口令为自己设定的一个值,以防止非法用户侵入。
30
口令对话框
(1)设计思路与步骤
1,添加资源,模态对话框
2,在创建主窗口前先显示该对话框
3,按下“确定”键,获取消息。
4,获得编辑框控件文本,比较与口令是否相同
是,程序继续执行
否,退出程序
5,按下“取消”键,直接退出
(2)源代码(只写明自己添加的代码)
CTestDlg dlg;
dlg.DoModal();
void CTestDlg::OnEnChangeEdit2()
{
}
void CTestDlg::OnOk()
{
OnOK();
CString str;
if(GetDlgItem(IDC_EDIT2)->GetWindowTextW(str),str=="1111") {
}
else
{
MessageBox(L"口令错误",L"错误",0);
CTestDlg dlg;
dlg.DoModal();
}
}
31
void CTestDlg::OnCancel() {
OnCancel();
exit(0); }
32