数组升序降序最大值最小值统计的类模板及实例

这是一个使用C++模板实现的类,用于对整型实数组进行升序、降序排序,并能计算数组的总分、平均分、最大值和最小值。类中包含构造函数、升序排序、降序排列、求和、最大值和最小值等方法。示例代码展示了如何使用该模板类进行操作。

/*
sortScore.h
*/
/*已知整型实数组长度的统计类模板及实例
算法:冒泡法
过程:
1.数组原型
2.排序
3.降序
4.分数段
4.最大值
5.最小值
其中最大值,最小值可以在排序函数中实现,
现在用单独函数实现

(c) adengou@foxmail.com 2011.8.19

win7 dev c++5.0 和 vs 2010 编译通过

使用请保留版权
*/
#include <iostream>
#include <string.h>
using namespace std;
#ifndef __sortScore_h_h
#define __sortScore_h_h
//using namespace std;

//typedef T CScore;//定义分数类型

template<class mTemp,class iTemp>
class NumSort
{
private:
 iTemp i;//步长控制
 iTemp j;//步长控制
 iTemp ArrayLength;//数组长度
 mTemp *nArray;//数组指针
 mTemp tempNumber;//用来调换数据

public:
 //学生人数
 iTemp m_stdCount;
 //总分
    mTemp m_stdTotalScore;
 //平均分
 mTemp m_stdAveScore;
 //自定义分数段人数
 iTemp m_stdSectionCount;
 //最大值,最小值
 mTemp Max, Min;
public:
 /*构造函数*/
 NumSort(mTemp arryNum[],iTemp nLen);
 //升序排序
 void UPSort(void);
 //降序排列
 void DESort(void);
 //求数组之和
 mTemp TotalSort(void);
 //最大值
 mTemp MaxSort(void);
 //最小值
 mTemp MinSort(void);
 //自定义分数段函数
 iTemp SectionScoreSelf(mTemp firstNumber,mTemp secondNumber);
};
//构造函数,变量初始化
template<class mTemp,class iTemp>
NumSort<mTemp,iTemp>::NumSort(mTemp arryNum[],iTemp nLen):m_stdCount(0),m_stdTotalScore(0.0),
 m_stdAveScore(0.0),m_stdSectionCount(0),tempNumber(0)
 {
     nArray=arryNum;ArrayLength= nLen;
  m_stdCount=ArrayLength;
 }
//原数组
template<class mTemp,class iTemp>
mTemp NumSort<mTemp,iTemp>::TotalSort(void)
{
 //总分;
  for(i=0;i!=ArrayLength;i++)
 {
  m_stdTotalScore+=nArray[i];
 }
    return m_stdTotalScore;
}
//升序数组
template<class mTemp,class iTemp>
void NumSort<mTemp,iTemp>::UPSort(void)
{
 for(i=0;i!=ArrayLength;i++)
 {
  m_stdTotalScore+=nArray[i];//求总分
  for(j=i+1;j!=ArrayLength;j++)//排序
  {
   if(nArray[i]>nArray[j])
   {
    tempNumber=nArray[i];
    nArray[i]=nArray[j];
    nArray[j]=tempNumber;
   }
  }
 }
 if(ArrayLength!=0){m_stdAveScore=m_stdTotalScore/ArrayLength;}//求平均分
 Min=nArray[i];Max=nArray[ArrayLength-1];//最小值最大值

}
//降序数组
template<class mTemp,class iTemp>
void NumSort<mTemp,iTemp>::DESort(void)
{
 for(i=0;i!=ArrayLength;i++)
 {
  for(j=i+1;j!=ArrayLength;j++)
  {
   if(nArray[i]<nArray[j])
   {
    tempNumber=nArray[i];
    nArray[i]=nArray[j];
    nArray[j]=tempNumber;
   }
  }
 }
}
//数组中最大值
template<class mTemp,class iTemp>
mTemp NumSort<mTemp,iTemp>::MaxSort(void)
{
 Max =nArray[0];
 for (i=0;i!=ArrayLength;i++)
 {
  if(nArray[i] > Max)
   Max =nArray[i];
 }
 
 return Max;
}
//数组中最小值
template<class mTemp,class iTemp>
mTemp NumSort<mTemp,iTemp>::MinSort(void)
{
 Min =nArray[0];
 for (i=0;i!=ArrayLength;i++)
 {
  if(nArray[i] < Min)
   Min =nArray[i];
 }
 return Min;
}
//分数段人数
template<class mTemp,class iTemp>
iTemp NumSort<mTemp,iTemp>::SectionScoreSelf(mTemp firstNumber,mTemp secondNumber)
{
   if(firstNumber>secondNumber){
         tempNumber=firstNumber;
   firstNumber=secondNumber;
         secondNumber=tempNumber;
 }
 m_stdSectionCount=0;
 for (int i=0;i!=ArrayLength;i++)
 {
  if(nArray[i] >= firstNumber && nArray[i]<=secondNumber)
   m_stdSectionCount+=1;
 }
 return m_stdSectionCount;
}
#endif

/*示例:
#include  "sortScore.h"
int main()
{
   long int  nLen;//数组长度
   double nGrade[]={95.0,98.7,46,98,67,58.2,101.5,67};
  
  nLen=sizeof (nGrade)/sizeof (double);
  NumSort<double,lont int> Grade(nGrade, nLen);
  Grade.TotalSort();//总分
  Grade.UPSort();//升序
  Grade.DESort();//降序
  cout<<"最大值: "<<Grade.MaxSort()<<endl;
  //Grade.MaxSort();//最大值
   cout<<"最小值: "<<Grade.MinSort()<<endl;
   Grade.MinSort();//最小值
   cout<<"参考人数: "<< Grade.m_stdCount<<endl;
    cout<<"总分: "<<Grade.m_stdTotalScore<<endl;
   cout<<"平均分: "<<Grade.m_stdAveScore<<endl;
   cout<<"分数段10-59: "<<Grade.SectionScoreSelf(10,59) <<endl;
   cout<<"分数段90-100.5: "<<Grade.SectionScoreSelf(90,100) <<endl;
   cout<<"分数段59-70: "<<Grade.SectionScoreSelf(70,59) <<endl;
   system("pause");
  return 0;
}
*/

 

南京工程学院 《C++/VC程序设计A》 课程报告 自动化 学院 自动化 专业 论 文 题 目 C++/VC程序设计A课程报告 学 生 姓 名 张可 班 级 自动化226 起 止 日 期 2025.3.4-2025.4.25 完 成 地 点 南京工程学院 成 绩 评 定 课程评语: 指 导 教 师 评 定 日 期 一、 VC++程序调试方法与冒泡排序程序设计 1、基本要求 1)、基本功能:实现冒泡排序算法,对用户输入的一组整数进行升序降序排序。 2)、具体要求:支持用户输入任意长度的整数数组。 提供选择排序方向的功能(升序降序)。 对输入数据进行合法性校验,确保所有输入均为整数。 在排序过程中显示每一步的状态,便于观察排序过程。 提供简洁的命令行交互界面。 3)、设计禁忌:不要直接在主函数中硬编码固定长度的数组。 避免使用全局变量,保持代码模块化。 不要在程序中忽略异常处理,例如输入非法字符的情况。 2、实现原理 1)、冒泡排序原理 冒泡排序的核心思想是通过多次遍历数组,每次将当前未排序部分的最大值最小值移动到相应位置:从数组的第一个元素开始,依次比较相邻的两个元素。如果前一个元素比后一个元素升序),则交换它们的位置;反之亦然。每完成一次遍历,最元素会到达数组的最后位置。对剩余未排序的部分重复上述过程,直到整个数组有序。 2)、程序调试原理与方法: F5调试显示每一步的数组状态,便于观察排序过程。 在关键位置插入断点,检查变量值是否符合预期。 测试极端情况(如空数组、单元素数组、已排序数组)。 3)、操作设置方法:通过命令行输入数组元素排序方向可以通过布尔值控制,默认为升序。 程序运行时应提示用户输入数组排序方式。 3、基本过程 1)、项目创建 出现如图1.1所示的NEW对话框,选择MFC APPWizard\[exe\],在Project name文本输入框中输入项目名:EX01后,单击OK按钮,弹出MFC AppWizard-Step 1对话框,如图1.2。 图1.1 New对话框 图1.2 MFC AppWizard-Step 1对话框 在设置好上述选项后,单击Next按钮,将弹出MFC AppWizard-Step 2 of 6对话框,如图1.3所示。 图1.3 MFC AppWizard-Step 2 of 6对话框 点击下一步,如图1.4。. 图1.4 MFC AppWizard-Step 3 of 6对话框 点击下一步,如图1.5。 图1.5 MFC AppWizard-Step 4 of 6对话框 点击下一步,如图1.6。 图1.6 MFC AppWizard-Step 5 of 6对话框 点击下一步,如图1.7。 图1.7 MFC AppWizard-Step 6 of 6对话框 图1.8 New Project Information 对话框 2)、函数代码分析 #include "stdio.h" #include "stdlib.h" #include "iostream.h" #include "string.h" void ShowNum(int a); void main() { int i=0; int j=0; int tmp=0; int ia\[10\]={10,7,9,32,29,16,78,26,83,17};//初始化数组:定义了一个包含10个整数的数组 ia, //初始值为{10, 7, 9, 32, 29, 16, 78, 26, 83, 17} int \*p=NULL; p=ia; //指针初始化:定义了一个指向整数的指针p,并将其初始化为 NULL 后 //指向数组 ia 的首地址 //for(i=0; i<10; i++) // cin>>ia\[i\]; for(i=0; i<10; i++) { for(j=0; j<10-i; j++) { if(ia\[j\]>ia\[j+1\]) { tmp=ia\[j\]; ia\[j\]=ia\[j+1\]; ia\[j+1\]=tmp;//外层循环控制排序的轮数,每一轮都会将最的未排序元素“冒 //泡”到正确的位置。内层循环比较相邻的两个元素,如果前一个 //元素于后一个元素,则交换它们的位置。10 - i 表示在第 i 轮 //之后,已经确定了 i 个最元素的位置,因此不需要再对这些位置进行比较。 } } } for(i=0; i<10; i++) ShowNum(\*p++);//使用 ShowNum 函数逐个输出排序后的数组元素。 //\*p++ 表示先取指针 p 所指向的值,然后将指针 p 增加 1。 return; } void ShowNum(int a) { cout<<"num is"<<a<<endl; return;//用于输出一个整数 a,并在后面加上换行符 } 这段代码展示了如何使用冒泡排序算法一个整数数组进行排序,并通过自定义的ShowNum函数输出排序结果。 3)、调试 程序如下设置断点,按F5运行,按F10运行下一步,可以在窗口中看到名称相对应的值,由此验证程序是否正确。 设置断点,按F5运行,按F10运行下一步 经过一次循环后,最后一个元素的数是最的 调试到最后一步,得到结果正确。 运行结果 4、结果与总结 通过实现冒泡排序算法,我们成功地对一组随机生成的整数进行了排序,将输入数组为 {10, 7, 9, 32, 29, 16, 78, 26, 83, 17},经过冒泡排序后,数组将变为 {7, 9, 10, 16, 17, 26, 29, 32, 78, 83}。程序会依次输出这些排序后的数字。冒泡排序虽然不是最高效的排序算法,但它易于理解和实现,非常适合用于学习排序算法的基础概念。同时,通过这次实践,我们掌握了如何编写C++代码,并学会了利用调试工具定位和解决问题。 二、GDI接口与WINDOWS图形程序设计 1、基本要求 1)、基本功能:实现一个简单的图形应用程序,能够在窗口上绘制基本图形(如矩形、圆弧、直线等),并支持用户交互。 2)、具体要求:使用WinAPI编写图形程序,结合GDI完成绘图任务。 支持多种图形元素的绘制(包括矩形、圆弧、直线)。 提供颜色选择功能,允许用户指定绘制图形的颜色。 在窗口中显示画图当前选中的图形样式和颜色。 3)、设计禁忌: 不要直接在主函数中硬编码固定的窗口小或图形属性。 避免使用全局变量,保持代码模块化。 不要在程序中忽略异常处理,例如窗口创建失败的情况。 避免重复代码,尽量使用封装良好的函数或类来组织代码。 2、实现原理 1)、GDI原理: GDI(Graphics Device Interface)是Windows操作系统提供的图形设备接口,用于在屏幕上绘制图形和文本。它提供了丰富的绘图功能,包括但不限于:绘制线条、矩形、椭圆等基本图形;设置画笔和刷子的样式、颜色;文本渲染和字体管理。 2)、程序调试原理: 与方法使用Visual Studio的调试工具(如断点、变量监视)来跟踪程序运行状态。在关键位置插入断点调试,记录程序执行的关键步骤。 3)、操作设置方法: 用户可以通过鼠标点击或拖动来选择绘图区域。提供颜色选择对话框,让用户可以自由选择绘图颜色。使用菜单或按钮来切换绘图模式(矩形、圆弧、直线)。 3、基本过程 1)、项目创建 图2.1 New对话框 图2.2 MFC AppWizard-Step 1对话框 单击Next按钮,将弹出MFC AppWizard-Step 2 of 6对话框,如图2.3所示。 图2.3 MFC AppWizard-Step 2 of 6对话框 点击下一步,如图2.4。. 图2.4 MFC AppWizard-Step 3 of 6对话框 点击下一步,如图2.5。 图2.5 MFC AppWizard-Step 4 of 6对话框 点击下一步,如图2.6。 图2.6 MFC AppWizard-Step 5 of 6对话框 点击下一步,如图2.7。 图2.7MFC AppWizard-Step 6 of 6对话框 图2.8 New Project Information 对话框 4)、步骤 双击空白矩形,添加“画图”的选项。&会变成下划线 添加画图的子菜单后得到 设置画图的直线子菜单属性,填写ID,方便后续程序里的引用。“提示”中的“\\n”前的文字会在选择时 候提醒,其后的文字会在“就绪”中显示。 设置画图的圆弧子菜单属性 设置画图的矩形子菜单属性 在“Toolbar”选择“IDR\_MAINFRAME”,添加直线、矩形、圆弧设置按钮 设置直线按钮属性 设置矩形按钮属性 设置圆弧按钮属性 按F5运行,出现设置后的新菜单 在CEX02view中添加直线对应函数响应 在CEX02view中添加矩形对应函数响应 在CEX02view中添加圆弧对应函数响应 再次按下F5运行,出现设置后的新菜单,按钮均能显示出来。 鼠标右键CEX02View,选择添加成员变量 或者直接在程序中编写,完成成员变量的初始化。 编写OnDrawLine() 函数,并分析 void CEX02View::OnDrawLine() { // TODO: Add your command handler code here CDC \*pDC=GetDC();//获取设备上下文 CPen \*OldPen=pDC->GetCurrentPen();//GetCurrentPen() 返回当前使用的画笔 CBrush \*OldBrush=pDC->GetCurrentBrush();//GetCurrentBrush() 返回当前使用的画刷。 //OldPen、OldBrush分别保存当前画笔和画刷的指针,以便在绘制完成后恢复原来的绘图状态。 CPen \*mPen=new CPen; CBrush \*mBrush=new CBrush;//创建新的画笔和画刷 mPen->CreatePen(0,8,RGB(255,0,0)); mBrush->CreateSolidBrush(RGB(0,0,255));//设置画笔和画刷 pDC->SelectObject(mPen); pDC->SelectObject(mBrush);//选择新的画笔和画刷 m\_sDrawType="Line"; m\_pStart.x=50; m\_pStart.y=30; m\_pEnd.x=150; m\_pEnd.y=80;//设置绘制操作的类型和坐标 pDC->MoveTo(m\_pStart); pDC->LineTo(m\_pEnd);//绘制线条 pDC->SelectObject(OldPen); pDC->SelectObject(OldBrush); delete mPen; delete mBrush;//恢复原来的画笔和画刷 CEX02Doc \*pDoc=GetDocument(); index=pDoc->index; pDoc->m\_aData\[index\].m\_sDrawType=m\_sDrawType; pDoc->m\_aData\[index\].m\_pStart=m\_pStart; pDoc->m\_aData\[index\].m\_pEnd=m\_pEnd; pDoc->index++;//保存绘制操作信息到文档对象 } 在CDC \*pDC=GetDC();行加断点, 在mPen->CreatePen(0,8,RGB(255,0,0));行加断点,调试 Ctrl+F10运行到m\_sDrawType="Line"; 在窗口修改name, F10运行到最后 F5运行,进行直线绘制 编写矩形代码:在视图中绘制一个矩形,并将绘制的相关信息保存到文档对象中以供后续使用 编写圆弧代码:在视图中绘制一个圆弧,并将绘制的相关信息保存到文档对象中以供后续使用 绘制矩形 绘制圆弧 右键CEX02View,选择Add Windows Message Handler 分别在CView::OnLButtonDown(nFlags, point);、CView::OnRButtonDown(nFlags, point);两行加断点调试 编写OnLButtonDown()函数 OnLButtonDown()函数在鼠标左键按下时,绘制一个红色边框蓝色填充的圆形,并将绘制信息保存到文档对象中。 编写OnRButtonDown()函数 OnRButtonDown()函数在鼠标右键按下时,绘制一个红色边框蓝色填充的矩形,并将绘制信息保存到文档对象中。 F5运行,按下左键可以画圆,右键画矩形 编写CEX02Doc函数,定义index用来记录个数。 在CEX02Doc \*pDoc=GetDocument();行加断点,按F10 运行,直到最后。 在index=pDoc->index;行加断点, 按F10 运行,直到最后。 编写OnDraw函数,在如图所示处加断点。 调试得到下图 5、结果与总结 通过实现基于GDI的图形程序,我们成功地在窗口上绘制了矩形、圆弧和直线,并且能够根据用户的选择动态调整绘图参数。GDI是Windows平台上非常强的图形接口,适用于需要高性能图形渲染的应用场景。通过本工程的操作,我们掌握了如何使用WinAPI编写图形程序,并学会了利用调试工具定位和解决问题。 三、对话框、控件以及文档读写程序设计 1、基本要求 1)基本功能:实现一个包含对话框和控件的程序,能够读取和写入文本文件。对话框中包含按钮、编辑框、标签等控件,用户可以通过这些控件与程序进行交互。 2)具体要求: 使用MFC(Microsoft Foundation Classes)框架构建对话框应用程序。 对话框中包含以下控件: 一个按钮,用于触发文件读取操作。 一个按钮,用于触发文件写入操作。 一个编辑框,用于显示或输入文本。 一个标签,用于提示用户当前操作的状态。 支持从文件中读取文本并显示在编辑框中。 支持将编辑框中的文本写入到文件中。 提供错误处理机制,确保文件操作的安全性。 3)设计禁忌: 不要在程序中硬编码文件路径,应使用文件对话框让用户选择文件。 避免直接操作文件指针,使用标准库或MFC提供的文件操作类。 不要忽略异常处理,确保文件打开和关闭的操作都正确无误。 避免在对话框中过多堆叠控件,保持界面简洁。 2、实现原理 1)冒泡排序原理: 冒泡排序是一种简单的排序算法,通过多次遍历数组,每次比较相邻的两个元素并交换它们的位置,直到整个数组有序。 时间复杂度为O(n²),空间复杂度为O(1)。 2)程序调试原理与方法: 使用Visual Studio的调试工具(如断点、变量监视)来跟踪程序运行状态。 在关键位置插入日志输出,记录程序执行的关键步骤。 测试极端情况(如文件为空、文件过)。 使用单元测试工具(如Google Test)验证程序的鲁棒性。 3)操作设置方法: 用户可以通过点击“读取”按钮选择文件并将其内容加载到编辑框中。 用户可以通过点击“写入”按钮将编辑框中的内容保存到文件中。 提供错误提示框,告知用户文件操作的结果。 3、基本过程 1)、新建工程: 出现如图3.1所示的NEW对话框,选择MFC APPWizard\[exe\],在Project name文本输入框中输入项目名:EX3后,单击OK按钮,弹出MFC AppWizard-Step 1对话框,如图3.2。 图3.1New对话框 图3.2 MFC AppWizard-Step 1对话框 在设置好上述选项后,单击Next按钮,将弹出MFC AppWizard-Step 2 of 6对话框,如图3.3所示。 图3.3 MFC AppWizard-Step 2 of 6对话框 点击下一步,如图3.4。. 图3.4 MFC AppWizard-Step 3 of 6对话框 点击下一步,如图3.5。 图3.5 MFC AppWizard-Step 4 of 6对话框 点击下一步,如图3.6。 图3.6 MFC AppWizard-Step 5 of 6对话框 点击下一步,如图3.7。 图3.7 MFC AppWizard-Step 6 of 6对话框 点击完成,如图3.8。 图3.8 New Project Information 对话框 2)、步骤 在IDR\_EX3TYPE中设置参数 在IDR\_MAINFRAME中设置工具栏按钮 F5编译 设置对话框Para Setting的属性 使用控件画出所需要的对话框样式 预览得到 查看对话框的Tab Order 设置Pen Colour:Red属性 设置Pen Colour:GRN属性 设置Pen Colour:BLU属性 设置Pen Colour:BLK属性 设置Brush Colour:Red属性 设置Brush Colour:GRN属性 设置Brush Colour:BLU属性 设置Brush Colour:BLK属性 设置edit属性 设置spin属性 设置列表框属性 创建对话框类 点击OK后,确定。创建New Class,如图 接下来,点击View创建类向导,如下图。 在上面选择Member Variables后,Control IDs:选中IDC\_BRSH\_COLR,添加成员变量m\_iBrshColr,点击OK。 选中IDC\_DRAW\_TYPE,添加成员变量m\_strDrawType,变量类型为CString点击OK。 选中IDC\_BRSH\_COLR,继续添加成员变量m\_cDrawType,变量类型为CListBox,点击OK。 Control IDs:选中IDC\_PEN\_COLR,添加成员变量m\_iPenColr,变量类型为int,点击OK。 Control IDs:选中IDC\_PEN\_WIDTH,添加成员变量m\_iPenWidth,变量类型为int,点击OK。 对添加的变量进行初始化定义 在CEX3View中加入ID\_VIEW\_PARA向导便于在对话框中进行图形的绘制 点击Edit Code,弹出如图所示的Add Member Function对话框,点击OK。 在EX3 classes里选择MParaDlg文件,可以在这里添加命令代码。 按F9设置断点,F5调试 按设置好的‘米’按钮 在CEX3View的Dump(CDumpContext &dc)里添加头文件#include "MParaDlg.h" 点击OnViewPara\[\],在//TOD0:Add your command handler code here下面添加代码 MParaDlg \*pDlg=new MParaDlg;pDlg->DoModal();delete pDlg;,并在MParaDlg \*pDlg=new MParaDlg;这一行设置断点。 F5调试,按设置好的‘米’按钮。 按F10运行下一步 再按F10运行下一步,弹出对话框。 结束调试,右键MParaDlg,选择Add Windows Message Handler,弹出窗口后,点击Add Hander这样MParaDlg就可以编辑。 点击MParaDlg里的OnInitDialog()文件,添加代码 在对话框初始化时,调用基类 CDialog的OnInitDialog方法。 向组合框控件 m\_cDrawType 添加了三种绘图类型选项:“Circle”、“Cross” 和 “Rectangle”。 根据成员变量 m\_strDrawType的值设置组合框的当前选中项: 如果 m\_strDrawType是 "Cross",则选中索引 1; 如果是 "Rectangle",则选中索引 2; 否则默认选中索引 0。 4. 返回 \`TRUE\` 表示初始化成功(除非需要将焦点设置到某个控件上,否则通常返回 \`TRUE\`)。 F5运行,弹出对话框,可以显示Circle、Cross、Rectangle三个选项。 在CEX3View中添加成员变量 在CEX3view的构造函数中初始化四个变量 获取对话框参数,在OnViewPara()中修改代码如图所示 void CEX03View::OnViewPara() { // TODO: Add your command handler code here MParaDlg \*pDlg=new MParaDlg;//创建对话框对象 pDlg->m\_iBrshColr=m\_iBrshColr; pDlg->m\_iPenColr=m\_iPenColr; pDlg->m\_iPenWidth=m\_iPenWidth; pDlg->m\_strDrawType=m\_strDrawType;//初始化对话框数据: if(pDlg->DoModal()==IDOK)//显示模态对话框并获取用户输入 { m\_iBrshColr=pDlg->m\_iBrshColr; m\_iPenColr=pDlg->m\_iPenColr; m\_iPenWidth=pDlg->m\_iPenWidth; m\_strDrawType=pDlg->m\_strDrawType;//更新视图参数 } delete pDlg;//释放对话框对象 } 通过一个模态对话框修改绘图相关的参数(如画笔颜色、线条宽度等),并在确认后更新视图的状态。这种方法提高了代码的模块化程度,使得参数管理更加清晰和易于维护。 设置断点并调试如图所示 按F10下一步运行 调试的结果如图所示 选择Pen Colour:BLU,Brush Colour:GRN,Pen Width:5,选择rectangle. 在OnInitDialog()中编写程序 BOOL MParaDlg::OnInitDialog() { CDialog::OnInitDialog();//调用基类初始化方法,调用基类 CDialog 的 OnInitDialog 方法,完成 //基本的对话框初始化工作。 // TODO: Add extra initialization here m\_cDrawType.AddString("Circle"); m\_cDrawType.AddString("Cross"); m\_cDrawType.AddString("Rectangle");//添加选项到列表框向组合框控件 m\_cDrawType 中添加了三 //个选项:“Circle”、“Cross” 和 “Rectangle”。 int i=0; if(m\_strDrawType=="Cross") i=1; else if(m\_strDrawType=="Rectangle") i=2; else i=0; m\_cDrawType.SetCurSel(i);//设置默认选中项 return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } 返回 TRUE 表示对话框初始化成功。通常情况下,除非需要将焦点设置到某个控件上,否则都应该返回 TRUE。这个函数在对话框初始化时设置组合框的选项及其默认选中项,可以在对话框中选择不同的绘图类型(如圆弧、直线或矩形),并且初始状态会根据预设的 m\_strDrawType 值自动调整。 添加消息处理函数 编写OnLButtonDown函数 // 鼠标左键按下事件处理函数 void CEX03View::OnLButtonDown(UINT nFlags, CPoint point) { // 获取设备上下文(DC) CDC\* pDC = this->GetDC(); // 获取当前视图的绘图上下文 // 保存原有的画笔和画刷 CPen\* OldPen = pDC->GetCurrentPen(); // 保存当前画笔 CBrush\* OldBrush = pDC->GetCurrentBrush(); // 保存当前画刷 // 创建新画笔(根据 m\_iPenColr 选择颜色) CPen\* mPen = new CPen; if (m\_iPenColr == 0) // 红色画笔 mPen->CreatePen(0, m\_iPenWidth, RGB(255, 0, 0)); else if (m\_iPenColr == 1) // 绿色画笔 mPen->CreatePen(0, m\_iPenWidth, RGB(0, 255, 0)); else if (m\_iPenColr == 2) // 蓝色画笔 mPen->CreatePen(0, m\_iPenWidth, RGB(0, 0, 255)); else // 默认黑色画笔 mPen->CreatePen(0, m\_iPenWidth, RGB(0, 0, 0)); // 创建新画刷(根据 m\_iBrshColr 选择颜色) CBrush\* mBrush = new CBrush; if (m\_iBrshColr == 0) // 红色画刷 mBrush->CreateSolidBrush(RGB(255, 0, 0)); else if (m\_iBrshColr == 1) // 绿色画刷 mBrush->CreateSolidBrush(RGB(0, 255, 0)); else if (m\_iBrshColr == 2) // 蓝色画刷 mBrush->CreateSolidBrush(RGB(0, 0, 255)); else // 默认黑色画刷 mBrush->CreateSolidBrush(RGB(0, 0, 0)); // 应用新画笔和画刷到DC pDC->SelectObject(mPen); pDC->SelectObject(mBrush); // 根据 m\_strDrawType 绘制图形 if (m\_strDrawType == "Cross") { // 绘制直线 pDC->MoveTo(point.x - 10, point.y - 10); pDC->LineTo(point.x + 10, point.y + 10); pDC->MoveTo(point.x - 10, point.y + 10); pDC->LineTo(point.x + 10, point.y - 10); } else if (m\_strDrawType == "Circle") // 绘制圆弧 pDC->Ellipse(point.x - 10, point.y - 10, point.x + 10, point.y + 10); else // 默认绘制矩形 pDC->Rectangle(point.x - 10, point.y - 10, point.x + 10, point.y + 10); // 7. 恢复原有画笔和画刷 pDC->SelectObject(OldPen); pDC->SelectObject(OldBrush); // 8. 释放资源 delete mPen; // 删除临时画笔 delete mBrush; // 删除临时画刷 编译后可以改变画笔、画刷的颜色,以及笔的宽度,得到如图所示 在EX03Doc中定义变量类型 添加头文件#include <afxtempl.h> 定义成员变量储存数据 进行成员变量初始化 对成员变量进行赋值操作,并获取当前文档对象指针 pDoc,并通过调用其成员函数 Add 将 tmp 对象添加到文档的 pData 数据成员中 在Mdata tmp行设置断点,按F5运行,对话框选择如下图所示 按OK后,单击鼠标左键,可以得到笔刷的值 F10运行下一步直到最后一步 添加OnDraw函数解决点击‘米’按钮后图形不能保存的问题 //获取文档指针: CEX03Doc\* pDoc = GetDocument();ASSERT\_VALID(pDoc); //获取当前视图对应的文档指针,并确保其有效性。ASSERT\_VALID是MFC提供的宏,用于检测对象是否处//于有效状态。如果文档中的pData数组为空,则直接返回,不进行绘制操作。 //初始化画刷和画笔: CPen \*OldPen = pDC->GetCurrentPen();CBrush \*OldBrush = pDC->GetCurrentBrush(); //保存当前画笔和画刷的状态,以便后续恢复。遍历数据数组: //for循环遍历文档中的pData数组,每个元素描述一个图形对象。创建画笔和画刷: CPen \*mPen = new CPen;CPen \*mBrush = new CBrush; //动态创建新的画笔和画刷对象。设置画笔属性: mPen->CreatePen(0, m\_iPenWidth, RGB(m\_iPenColr)); //根据m\_iPenColr的颜色值和m\_iPenWidth的宽度创建画笔:0表示默认样式(实线)。RGB宏用于指定//颜色值。 //设置画刷属性 mBrush->CreateSolidBrush(RGB(m\_iBrshColr)); //创建纯色画刷,颜色由m\_iBrshColr决定。选择画笔和画刷: pDC->SelectObject(mPen);pDC->SelectObject(mBrush); //绘制图形:根据m\_strDrawType的值判断绘制何种图形 //恢复原始画笔和画刷: pDC->SelectObject(OldPen); pDC->SelectObject(OldBrush); //在绘制完当前图形后,恢复之前的状态。释放资源: delete mPen;delete mBrush;//释放动态分配的画笔和画刷对象 在CEX03Doc\* pDoc = GetDocument();行加断点 F5运行,点出对话框,选择如图 再选择其他笔刷颜色,画出下图 F10下一步运行调试 F10下一步运行调试 F10下一步运行调试 添加存储和读取的相关程序以便下次打开时可以看到原来做的图 存储函数 读取函数 逐个写入图形数据 ar << pData\[i\].m\_iBrshColr; // 画刷颜色索引 ar << pData\[i\].m\_iPenColr; // 画笔颜色索引 ar << pData\[i\].m\_iPenWidth; // 画笔宽度 ar << pData\[i\].m\_strDrawType; // 图形类型字符串 ar << pData\[i\].m\_pCenter.x; // 中心点X坐标 ar << pData\[i\].m\_pCenter.y; // 中心点Y坐标 初始化临时变量 读取数据总量 ar >> j; if (j < 0) return; // 无效数据 清空现有数据pData.RemoveAll(); for函数逐个读取图形数据 pData.Add(tmp); // 添加到文档数据 程序按F5运行,画出下图 文件保存 设置断点进行分布调试,先进行图形的存储。后打开保存的图形文件进行读取显示 F10运行下一步 运行到最后一步 写出课程总结,包含对CLASS、MFC、WINDOWS应用程序、面向对象与面向过程的区别、对话框、CARRAY、DOC、VIEW、消息与响应等的理解和认识,可以有部分感想,感想部分不超过150字
05-21
### 关于C++/VC程序设计、GDI图形接口、MFC框架及相关技术 #### C++/VC++中的面向对象编程 在C++中,类和对象是核心概念之一。通过定义类来封装数据成员和成员函数,可以实现数据抽象和信息隐藏[^3]。例如,在MFC框架下开发Windows应用程序时,通常会继承自特定的基类(如`CWnd`, `CDialog`),并重载其虚函数以定制行为。 #### GDI图形接口基础 GDI(Graphics Device Interface)提供了用于绘制线条、矩形、椭圆以及其他形状的功能集合。它还支持位图操作、字体渲染等功能。下面是一个简单的例子展示如何使用GDI绘制一条直线: ```cpp void DrawLine(CDC* pDC) { CPen pen(PS_SOLID, 1, RGB(255, 0, 0)); // 创建红色实心笔 CPen* pOldPen = pDC->SelectObject(&pen); pDC->MoveTo(10, 10); pDC->LineTo(100, 100); pDC->SelectObject(pOldPen); // 恢复旧的对象 } ``` 此代码片段展示了如何创建一个CPen对象,并利用CDC指针完成基本的绘图工作[^1]。 #### MFC框架概述及其应用 Microsoft Foundation Classes (MFC) 是一组基于C++的语言扩展库,极地简化了Win32 API的应用开发过程。对于图像处理而言,可以通过加载BMP文件到内存缓冲区再显示出来;或者更进一步地实施诸如灰度转换、直方图统计之类的算法[^1]。 以下是关于销毁视图资源的一个实例说明: 当CTestView析构时调用了W32_Close_MPE1000()方法释放硬件设备句柄,这表明该类可能涉及到了视频捕获卡的操作逻辑[^2]: ```cpp CTestView::~CTestView() { W32_Close_MPE1000(); // 关闭采集卡 } ``` #### 文件读写操作 标准C++流提供了一种方便的方式来执行文件输入输出任务。比如打开文本文件进行逐行读取可按如下方式编写: ```cpp #include <fstream> #include <string> std::ifstream fin("example.txt"); if (!fin.is_open()) { std::cerr << "Failed to open file!" << std::endl; } else { std::string line; while(getline(fin,line)){ std::cout<<line<<"\n"; } fin.close(); } ``` 而针对二进制模式下的块数据传输,则需注意设置正确的标志位以及考虑字节顺序等问题[^2]。 #### 冒泡排序原理及其实现 冒泡排序是一种简单直观但效率较低的经典排序算法。它的主要思想是比较相邻两个数小关系然后交换位置直到整个序列有序为止。下面是采用模板形式通用化的版本: ```cpp template<typename T> void BubbleSort(T arr[], int n){ bool swapped=false; do{ swapped=false; for(int i=0;i<n-1;i++){ if(arr[i]>arr[i+1]){ swap(arr[i],arr[i+1]); swapped=true; } } }while(swapped&&--n>1); } ``` #### 程序调试技巧 有效的错误检测机制应该贯穿在整个编码周期之中。除了依赖IDE内置工具外,还可以主动加入断言语句验证假设条件是否成立。另外合理运用日志记录可以帮助定位难以重现的问题根源所在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值