private:
floatspeed;
inttotal;
}
intmain()
{
Vehiclea(120,4);
a.ShowMember();
Vehicleb;
a.ShowMember();
}
(1)编译该程序,修改程序错误
1、在class类里添加构造函数
Vehicle(){}
2、speed=speed;
total=total;
改为this->speed=speed;
this->total=total;
3、类的最后加分号;
4、缺少命名空间usingnamespacestd;
(2)分别在创建对象,构造函数处设置断点,调试运行。
(3)写出程序运行结果
constructoriscalled!
120|4
120|4
2.WindowsSDK应用程序编写
下面是一个SDK应用程序的示例,该程序的功能是构造一个编辑框控件和一个按钮。
编辑框用于输入一元二次方程的系数,各系数之间用逗号分隔,当单击“计算”按钮,获取方程系数,然后将求得的根通过TextOut显示在窗口客户区中。
#include
#include
#include
//求一元二次方程的根,函数返回根的个数
intGetRoot(floata,floatb,floatc,double*root)
{
doubledelta,deltasqrt;
delta=b*b-4.0*a*c;
if(delta<0.0)return0;//无根
deltasqrt=sqrt(delta);
if(a!
=0.0){
root[0]=(-b+deltasqrt)/(2.0*a);
root[1]=(-b-deltasqrt)/(2.0*a);
}else
if(b!
=0.0)root[0]=root[1]=-c/b;
elsereturn0;
if(root[0]==root[1])return1;
elsereturn2;
}
charstr[80];
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);//窗口过程
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,
LPSTRlpCmdLine,intnCmdShow)
{
HWNDhwnd;//窗口句柄
MSGmsg;//消息
WNDCLASSwndclass;//窗口类
wndclass.style=CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc=WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName="SDKWin";//窗口类名
if(!
RegisterClass(&wndclass))//注册窗口
{
MessageBox(NULL,"窗口注册失败!
","HelloWin",0);return0;
}
//创建窗口
hwnd=CreateWindow("SDKWin",//窗口类名
"实验1——Windows编程基础",//窗口标题
WS_OVERLAPPEDWINDOW,//窗口样式
CW_USEDEFAULT,//窗口最初的x位置
CW_USEDEFAULT,//窗口最初的y位置
CW_USEDEFAULT,//窗口最初的x大小
CW_USEDEFAULT,//窗口最初的y大小
NULL,//父窗口句柄
NULL,//窗口菜单句柄
hInstance,//应用程序实例句柄
NULL);//创建窗口的参数
ShowWindow(hwnd,nCmdShow);//显示窗口
UpdateWindow(hwnd);//更新窗口,包括窗口的客户区
while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);//转换某些键盘消息
DispatchMessage(&msg);//将消息发送给窗口过程,这里是WndProc
}
returnmsg.wParam;
}
LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)
{
HDChdc;
PAINTSTRUCTps;
staticHWNDhwndButton,hwndEdit;
charstrEdit[80],strA[3][80],strHint[80];
floata[3];
doubleroot[2];
inti,j,k,m;
switch(message)
{
caseWM_CREATE:
//窗口创建产生的消息
hwndEdit=CreateWindow("edit",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER,
10,60,200,25,hwnd,NULL,NULL,NULL);
hwndButton=CreateWindow("button","计算",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
240,60,80,25,hwnd,NULL,NULL,NULL);
return0;
caseWM_COMMAND:
//命令消息,控件产生的通知代码在wParam的高字中
if(((HWND)lParam==hwndButton)&&(HIWORD(wParam)==BN_CLICKED)){
//获取编辑框控件的内容,并将其转换成float数值
GetWindowText(hwndEdit,strEdit,80);//获取编辑框内容
//分隔字符串
k=0;m=0;
for(j=0;j<80;j++){
if(strEdit[j]==','){
k++;m=0;
}
else{
strA[k][m]=strEdit[j];m++;
}
}
for(i=0;i<3;i++)
a[i]=(float)atof(strA[i]);//将字符串转换成float数值
intn=GetRoot(a[0],a[1],a[2],root);
if(n<1)strcpy(str,"方程无根!
");
elsesprintf(str,"方程的解为:
%f,%f",root[0],root[1]);
InvalidateRect(hwnd,NULL,TRUE);
}
caseWM_PAINT:
hdc=BeginPaint(hwnd,&ps);
strcpy(strHint,"请输入一元二次方程的3个系数,中间用逗号分隔");
TextOut(hdc,10,40,strHint,strlen(strHint));
TextOut(hdc,10,90,str,strlen(str));
EndPaint(hwnd,&ps);
return0;
caseWM_DESTROY:
//当窗口关闭时产生的消息
PostQuitMessage(0);
return0;
}
returnDefWindowProc(hwnd,message,wParam,lParam);//执行默认的消息处理
}
(1)请仔细阅读该程序,写出该程序的设计思路。
1书写一个求一元二次方程根的函数,使其返回值为函数的个数
2注册并创建一个窗口
3消息处理-将其中不适合的类型改为float
4销毁窗口
5程序结束
(2)参考上面的代码,使用SDK方式编写一窗口应用程序,能实现简单的画线功能。
a.设计思想
所编代码只需要在函数LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)中即可,消息循环中捕捉鼠标点击的坐标的信息,再在caseWM_PAINT:
中调用画线的函数即可。
b.程序源代码(要求有详细的注释)
#include
#include
#include
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);//窗口过程
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,
LPSTRlpCmdLine,intnCmdShow)
{
HWNDhwnd;//窗口句柄
MSGmsg;//消息
WNDCLASSwndclass;//窗口类
wndclass.style=CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc=WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName="SDKWin";//窗口类名
if(!
RegisterClass(&wndclass))//注册窗口
{
MessageBox(NULL,"窗口注册失败!
","HelloWin",0);return0;
}
//创建窗口
hwnd=CreateWindow("SDKWin",//窗口类名
"实验——Windows编程基础——画线",//窗口标题
WS_OVERLAPPEDWINDOW,//窗口样式
CW_USEDEFAULT,//窗口最初的x位置
CW_USEDEFAULT,//窗口最初的y位置
CW_USEDEFAULT,//窗口最初的x大小
CW_USEDEFAULT,//窗口最初的y大小
NULL,//父窗口句柄
NULL,//窗口菜单句柄
hInstance,//应用程序实例句柄
NULL);//创建窗口的参数
ShowWindow(hwnd,nCmdShow);//显示窗口
UpdateWindow(hwnd);//更新窗口,包括窗口的客户区
while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);//转换某些键盘消息
DispatchMessage(&msg);//将消息发送给窗口过程,这里是WndProc
}
returnmsg.wParam;
}
LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)
{
HDChdc;
PAINTSTRUCTps;
staticPOINTSpt[2];//定义一个元素为两个点的数组,方便存储鼠标落下和抬起的两个点
switch(message)
{
caseWM_CREATE:
//窗口创建产生的消息
caseWM_COMMAND:
//命令消息,控件产生的通知代码在wParam的高字中
caseWM_LBUTTONDOWN:
//鼠标落下的消息
//pt[0].x=GET_X_LPRAM(lParam);
//pt[0].y=GET_Y_LPAAM(lParam);
pt[0]=MAKEPOINTS(lParam);
//lParam共32位,低字节表示光标的X坐标,高字节表示光标的Y坐标,坐标是相对于客户区域的左上角
caseWM_LBUTTONUP:
pt[1]=MAKEPOINTS(lParam);//通过宏MAKEPOINTS把参数lParam转化为点
InvalidateRect(hwnd,NULL,TRUE);//让系统发送WM_PAINT消息重绘
caseWM_PAINT:
hdc=BeginPaint(hwnd,&ps);
MoveToEx(hdc,pt[0].x,pt[0].y,NULL);//起点
LineTo(hdc,pt[1].x,pt[1].y);//终点
EndPaint(hwnd,&ps);
return0;
caseWM_DESTROY:
//当窗口关闭时产生的消息
PostQuitMessage(0);
return0;
}
returnDefWindowProc(hwnd,message,wParam,lParam);//执行默认的消息处理
}
c.调试分析&运行结果
d.用户使用说明(输入/输出规定)
鼠标左键落下拖拽后松开,即形成一条直线,当再次画线时前一直线消失,故窗口上只能存在一条直线。
实验2类和对象
一、实验目的
1.掌握类的定义方法,能合理指定类中成员的访问权限。
2.学习对象的说明和使用方法。
3.灵活运用类和对象的相关知识进行综合程序设计。
二、实验知识点概念
类是对同一类事物的抽象描述,其数据成员用于描述该类事物的属性,成员函数完成修改、获取属性值或实现基于属性的某些操作。
类不占用存储空间。
对象是类的实例,对象占用存储空间。
C++中类与结构体并没有本质的区别,结构体中也可以定义成员函数,也可以指定各个成员的访问权限。
两者的唯一差异在于:
结构中成员的缺省访问权限是公有的,而类中成员的缺省访问权限是私有的。
三、实验题目
1.设计个人信息类CPerson和学生成绩类CScore。
其中,CPerson类的数据成员是姓名和学号;CScore类的数据成员除了三门成绩外,还有一个CPerson类对象stu。
2.设计数据操作类CStack,它使用数组来动态存储CScore类对象,并模拟栈的操作:
push(压入)与pop(弹出)。
栈是一种“FILO”(先进后出)或“LIFO”(后进先出)的存储结构。
如图2-1所示,它占用一块连续的内存空间,有两个端点:
一个端点是固定的,称为栈底;另一个端点是活动的,称为栈顶。
操作只能在栈顶进行,建立一个栈先要开辟栈空间,且为了指示栈顶位置还要设定一个指针,称为栈顶指针(图2-1中的SP)。
初建栈时,栈顶指针SP指向栈底,如图2-1(a)所示。
当向栈内压入一个元素d1时,先向栈顶写入d1,再将SP++,如图2-1(b)所示。
再压入一个元素d2时,先向栈顶写入d2,再将SP++,如图2-1(c)所示。
可见,栈顶总是用于存放下一个元素。
当栈内弹出一个元素d2时,直接执行SP--,然后返回SP中的内容,如图2-1(d)所示。
这样,当再次压入新元素时,d2被覆盖。
栈
空
间
SP
d1
栈底
(a)空栈(b)压入d1
图2-1栈模型
栈
空
间
d2
d1
栈底
SP
SP
(c)压入d2(d)弹出d2
图2-1栈模型
四、程序思路
思路就是先声明一个空间足够大的对象数组到一个指针,用这个指针来访问数组。
涉及到一些初始化问题,各类的构造函数要写好。
压栈就是把对象以参数形式传给push函数,push把对象放到数组里,并把指针+1。
弹栈就是利用pop函数,把指针-1,这样就相当于栈顶元素没了。
五、程序源代码(要求有详细的注释)
#include
#include
usingnamespacestd;
constintsize=100;//数组大小
staticintcount=0;//栈内元素计数
classCPerson
{
stringname;
stringnumber;
public:
CPerson(constCPerson&person)//拷贝构造函数
{
name=person.name;
number=person.number;
}
public:
CPerson(stringnam,stringnumbe)//两参数构造函数
{
name=nam;
number=numbe;
}
public:
CPerson():
name("无人"),number("000")//无参构造函数
{}
public:
stringshowname()//取值函数
{
returnname;
}
public:
stringshownumber()//取值函数
{
returnnumber;
}
};
classCScore
{
intchinese;
intmath;
intenglish;
CPersonstu;
public:
CScore():
stu(),chinese(0),math(0),english(0)//无参构造函数及初始化列表
{}
public:
CScore(CPersonst,intchines,intmat,intmusi)//四参数构造函数
:
stu(st),chinese(chines),math(mat),english(musi)
{
//stu=st;
//chinese=chines;
//math=mat;
//english=musi;
}
publi