高级语言C++程序设计高级编程-期末考试 - 答案
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
高级语言C++程序设计-高级编程-考试试卷—答案
姓名: ________________ 成绩__________________
第一题选择(
1. 设x和y均为bool量,则x&&y为真的条件是( A )
A)它们均为真B)其中一个为真C)它们均为假D)其中一个为假
2. 假定a为一个整型数组名,则元素a[4]的字节地址为( C )
A)a+4 B)a+8 C)a+16 D)a+32
3. 下面的哪个保留字不能作为函数的返回类型( C )
A)void B)int C)new D)long
4. 在编译指令中,宏定义使用哪个指令( B )
A)#include B)#define C)#if D)#else
5. 设存在函数int max(int,int)返回两参数中较大值,若求22,59,70三者中最大值,下列表达式不正确的是:(C )
A)int m = max(22,max(59,70));B)int m = max(max(22,59),70);
C)int m = max(22,59,70);D)int m = max(59,max(22,70));
6. 对于int *pa[5];的描述中,正确的是:( D )
A)pa是一个指向数组的指针,所指向的数组是5个int型元素
B)pa是一个指向某数组中第5个元素的指针,该元素是int型变量
C)pa[5]表示数组的第5个元素的值,是int型的值
D)pa是一个具有5个元素的指针数组,每个元素是一个int型指针
7. 对C++语言和C语言的兼容性,描述正确的是:( A )
A)C++兼容C B)C++部分兼容C C)C++不兼容C D)C兼容C++
8. 下列的各类函数中,不是类的成员函数。
( C )
A)构造函数B)析构函数C)友元函数D)拷贝初始化构造函数
9. 在类定义的外部,可以被访问的成员有( C )
A) public和protected类成员B)private的类成员
C) 仅public的类成员D)public和private的类成员
10. 关于类和对象不正确的说法是:( C )
A)类是一种类型,它封装了数据和操作B)对象是类的实例
C)一个类的对象只有一个D)一个对象必属于某个类
11. 在C++中用( D )能够实现将参数值带回。
A)数组和指针B)指针和引用C)仅指针D)数组, 指针和引用
12. 在公有继承的情况下,基类的成员(私有的除外)在派生类中的访问权限( B )
A)受限制B)保持不变C)受保护D)不受保护
13. 关于构造函数的说法,不正确的是:( A )
A)没有定义构造函数时,系统将不会调用它B)其名与类名完全相同
C)它在对象被创建时由系统自动调用D)没有返回值
A)参数个数B)参数类型C)函数名称D)函数的返回值类型
15. 下列描述中,正确的是:( D )
A)所有的运算符号都可以重载。
B)基类类型的指针可以指向子类,子类类型的指针也可以指向基类。
C)可以在类的构造函数中对静态数据成员进行初始化。
D)动态联编要满足两个条件:被调用的成员函数是虚函数;用指针或引用调用虚函数。
第二题:C++类与MFC用户界面编程(22分)
自定义如下的taper 圆锥体类并对其进行使用:该类具有私有数据成员r 与h,分别表示圆锥体的底圆半径和高;并提供构造函数以及计算侧面积、全面积和体积的各公有成员函数。
而后编制主函数,对taper 类进行使用:说明taper 类对象,输入底圆半径与圆锥体的高,而后负责计算出该圆锥体的侧面积、全面积以及体积并将各结果显示出来。
圆锥体的侧面积= pi*rL
圆锥体的全面积= pi*r(L+r)
圆锥体的体积= (pi*r2h)/3
其中的L = sqrt(r*r + h*h)
class taper { //自定义类taper
double r, h; //私有数据成员- 底圆半径r,高h
public:
taper ( double r0= , double h0 =0); //构造函数- 带来底圆半径与高
void setData(double r0, double h0);
double arealateral (); //计算侧面积的公有成员函数
double areawhole(); //计算全面积
double volume(); //计算体积
};
画出所设计的用户界面; 写出类taper的头文件和源文件所有内容; 写出对话框类头文件中添加的变量和消息响应函数; 写出对话框类源文件中的数据交换函数, 消息映射, 以及点击按钮响应函数.
解答:
//taper.h
#pragma once
const double PI = 3.14;
class taper { //自定义类taper
double r, h; //私有数据成员- 底圆半径r,高h
public:
taper(); //构造函数- 带来底圆半径与高
void setData(double r0, double h0);
double areawhole(); //计算全面积
double volume(); //计算体积
};
//taper.cpp
#include"stdafx.h"
#include"taper.h"
taper::taper() { //构造函数
r = 0;
h = 0;
}
void taper::setData(double r0, double h0)
{
r = r0;
h = h0;
}
double taper::arealateral() { //计算侧面积:πrL
return (PI * r * sqrt(r*r + h*h));
}
double taper::areawhole() { //计算全面积:πr(L+r) double L = sqrt(r*r + h*h);
return (PI * r * (L + r));
}
double taper::volume() { //计算体积:(πr2h)/3
return PI * r * r * h / 3;
}
// MFCTaperDlg.h :
private:
double m_rInput;
double m_hInput;
double m_areaSideOutput;
double m_areaALLOutput;
double m_volumeOutput;
taper obj;
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButtoncal();
// MFCTaperDlg.cpp :
void CMFCTaperDlg::DoDataExchange(CDataExchange* pDX) {
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_rInput);
DDX_Text(pDX, IDC_EDIT3, m_areaSideOutput);
DDX_Text(pDX, IDC_EDIT4, m_areaALLOutput);
DDX_Text(pDX, IDC_EDIT5, m_volumeOutput);
}
BEGIN_MESSAGE_MAP(CMFCTaperDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTONCAL, &CMFCTaperDlg::OnBnClickedButtoncal)
END_MESSAGE_MAP()
void CMFCTaperDlg::OnBnClickedButtoncal()
{
UpdateData(TRUE);
obj.setData(m_rInput, m_hInput);
m_areaSideOutput = obj.arealateral();
m_areaALLOutput = obj.areawhole();
m_volumeOutput = obj.volume();
UpdateData(FALSE);
}
第三题:类派生多态性及多线程编程(28分)
求函数y=4.0/(1+x*x)的定积分, 由用户输入积分的上界和下界, 以及积分区段数, 通过点击启动多线程菜单, 分别利用矩形法和梯形法同时求出积分结果. 利用CEvent事件工具, 实现2个线程的合理时间输出. 事件的作用是: 等待各自子线程执行完毕, 然后把运算结果推送到界面上.
要求, 画出输入输出界面; 将基类以及两派生类的代码全部写出; 将CMFCThreadIntegralDlg.cpp中按钮消息响应函数, 工作者线程函数, 动态联编函数写出.
解答: 界面设计如下:
//inte_algo.h
class inte_algo { //基类inte_algo
protected:
float a, b; //a、b 为积分区间的左右边界
int n; //n 表示把[a,b]区间划分成多少个小区段进行积分
float h, sum; //h 表示步长,sum 表示积分结果值
public:
inte_algo(float left, float right, int steps)
{
//基类构造函数,由参数带来的left、right 将赋给表示积分区间
//左右边界的a 与b,而将steps 赋给表示划分多少个小区段的n
a = left;
b = right;
n = steps; h = (b - a) / n; //算出步长h
sum = 0.0; //sum 初值为0
}
virtual double integrate(void)=0; //基类中说明了一个虚函数integrate
//应为纯虚函数, 否则报错: 无法解析的外部符号integrate
float function(float x){ //欲积分的函数
return 4.0 / (1 + x*x);
}
};
//rectangle.h
#pragma once
#include"inte_algo.h"
class rectangle :public inte_algo { //派生类rectangle
public:
rectangle(float left, float right, int steps)
:inte_algo(left, right, steps){
}
virtual double integrate(){ //派生类rectangle 的虚函数定义
//计算定积分的公式为:sum=( f(a)+f(a+h)+f(a+2h)+...+f(a+(n–1)h) )h
float al = a; // al 为调用f 函数时的实参值,依次取值a、a+h、a+2h、...
for (int i = 0; i < n; i++) { //共在n 个点处计算函数值
sum += function(al);
al += h; //al 每次增加一个步长h
};
sum *= h;
//cout << sum << endl; //显示积分结果sum
return sum;
}
};
//ladder.h
#pragma once
#include"inte_algo.h"
class ladder :public inte_algo { //派生类ladder
public:
ladder(float left, float right, int steps)
:inte_algo(left, right, steps){
}
virtual double integrate(){ //派生类ladder 之虚函数定义
//计算公式:sum=( f(a)+2f(a+h)+2f(a+2h)+...+2f(a+(n-1)h)+f(b) )h/2
float al = a; //al 为调用f 函数时的实参值,依次取值a、a+h、a+2h、...
sum = (function(a) + function(b) / 2.0); //对边界点a、b 进行特殊处理
for (int i = 1; i < n; i++) { //还要在n-1 个点处计算函数值
al += h;
sum += function(al);
};
sum *= h;
//cout << sum << endl;
return sum;
}
};
// MFCThreadIntegralDlg.cpp :
double integrateFunc(inte_algo * p) {
double d = p->integrate(); //根据p 所指向的对象的不同,调用不同派生类的integrate return d;
}
int n = 0;
double m1 = 0.0, m2 = 0.0;
CEvent event1, event2;
UINT WorkThread1(LPVOID param)
{
rectangle *tempobj1 = (rectangle *)param;
m1 = integrateFunc(tempobj1);
event1.SetEvent();
return 1;
}
UINT WorkThread2(LPVOID param)
{
ladder *tempobj2 = (ladder *)param;
m2 = integrateFunc(tempobj2);
event2.SetEvent();
return 1;
}
void CMFCThreadIntegralDlg::OnBegin()
UpdateData (TRUE );
rectangle rec (m_lowerbound , m_upperbound
, m_count );
ladder lad (m_lowerbound , m_upperbound , m_count );//ladder 类对象lad
AfxBeginThread (WorkThread1, &rec );//也可将I/O 参数放到一个结构体内
AfxBeginThread (WorkThread2, &lad );
event1.Lock ();
m_thread1Res = m1;
event1.Unlock ();
UpdateData (FALSE );
event2.Lock ();
m_thread2Res = m2;
event2.Unlock ();
UpdateData (FALSE );
}
第四题:GDI 及数据可视化编程(20分)
利用下面的迭代公式, 计算实数x 的立方根y =
100次.
0121;(2)3n n n x y x y y y +==+ 实现在用户界面上输入x 的值, 点击计算按钮后, 通过编辑框输出求得的x 立方根, 并通过GDI 编程, 将每次迭代过程的数据画到界面上, 实现迭代过程的可视化.
要求: 将所设计的界面画出(包括输入的x 值(为88), 以及计算出的结果); 将按钮的相应函数写出(包括求立方根的过程, 以及利用GDI 编程输出)
解答: 界面为:
void CMFCGDICuberootDlg ::OnBnClickedButtoncal ()
{
CRect rectPicture ;
m_PICDraw .GetClientRect (&rectPicture );
CDC *pDC = m_PICDraw .GetDC ();
float fDeltaX ; // x 轴相邻两个绘图点的坐标距离
float fDeltaY ; // y 轴每个逻辑单位对应的坐标值
int nX ; // 在连线时用于存储绘图点的横坐标
int nY ; // 在连线时用于存储绘图点的纵坐标
CPen newPen ; // 用于创建新画笔
CBrush newBrush; // 用于创建新画刷
CBrush *pOldBrush; // 用于存放旧画刷
const int COUNT = 30;
// 计算fDeltaX和fDeltaY
fDeltaX = (float)rectPicture.Width() / (COUNT - 1); //分为199段, 200个点
fDeltaY = (float)rectPicture.Height() / 80;//分为80段//分为Height个段比较好
newBrush.CreateSolidBrush(RGB(255, 255, 255)); // 创建白色新画刷
pOldBrush = pDC->SelectObject(&newBrush); // 选择新画刷,并将旧画刷的指针保存到pOldBrush pDC->Rectangle(rectPicture);// 以白色画刷为绘图控件填充白色,形成白色背景
pDC->SelectObject(pOldBrush);// 恢复旧画刷
newBrush.DeleteObject();// 删除新画刷
/////////////////////////////////////////////////////////画粗红色虚线(真值)
newPen.CreatePen(PS_DASH, 3, RGB(255, 0, 0));// 创建实心画笔,粗度为2,颜色为红色
pOldPen = pDC->SelectObject(&newPen);
// pDC->MoveTo(rectPicture.left, rectPicture.bottom - 3.14 / 5 * rectPicture.bottom);
// pDC->LineTo(rectPicture.right, rectPicture.bottom - 3.14 / 5 * rectPicture.bottom);
pDC->SelectObject(pOldPen); // 恢复旧画笔
newPen.DeleteObject(); // 删除新画笔
/////////////////////////////////////////////////////////画立方根的计算值
UpdateData(TRUE);
float Yn1, Yn, cubeRes[COUNT];
Yn = m_x;
Yn1 = (2 * Yn + m_x / pow(Yn, 2)) / 3;
for (int i = 0; i<COUNT;i++)
{
Yn = Yn1;
Yn1 = (2 * Yn + m_x / pow(Yn, 2)) / 3;
cubeRes[i] = Yn1;
}
m_cuberoot = cubeRes[COUNT - 1];
UpdateData(FALSE);
newPen.CreatePen(PS_SOLID, 1, RGB(0, 0, 255));// 创建实心画笔,粗度为1,颜色为蓝色
pOldPen = pDC->SelectObject(&newPen);// 选择新画笔,并将旧画笔的指针保存到pOldPen
// 将当前点移动到绘图控件窗口的左下角,以此为波形的起始点
pDC->MoveTo(0, rectPicture.bottom - cubeRes[0] / m_x* rectPicture.bottom);
// 计算数组中每个点对应的坐标位置,并依次连接,最终形成曲线
for (int i = 0; i < COUNT; i++)
{
nX = rectPicture.left + (int)(i * fDeltaX);
nY = rectPicture.bottom - cubeRes[i] /m_x * rectPicture.bottom; //把纵轴折合到5
pDC->LineTo(nX, nY);
}
newPen.DeleteObject(); // 删除新画笔
ReleaseDC(pDC);//释放DC, 否则程序跑上一段时间后,会因为资源耗尽而非正常结束}。