计算与软件工程作业三
作业要求链接 | https://edu.cnblogs.com/campus/jssf/infor_computation17-31/homework/10454 |
---|---|
课程目标 | 可以根据现有代码实现改编完成简单软件功能的开发,能够发现并完善简单地代码漏洞 |
该次作业在程序效能方面帮我实现目标 | 通过修改代码,帮助我更好的完善代码,完成对代码的检测与修补,保证代码的可靠性 |
参考文献 | https://blog.csdn.net/qq_26568205/article/details/80627825https://blog.csdn.net/dafeng_blog/article/details/25336931 https://www.cnblogs.com/wolfrickwang/p/3767306.html https://blog.csdn.net/xq_rookie/article/details/78674973?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task |
作业正文 | https:////www.cnblogs.com/wanghuiru/p/12460279.html |
代码设计:(详细代码见附录及码云链接)
1、 代码要求及所要完成的功能
输入一组测试数据,包括测试的数据个数及测试的数据。
要求输出这组数据的最大子数组的和、最大子数组开始的下标和最大子数组结束的下标。
2、 代码运行截图:
3、 代码分析
实现以上要求的算法主要有三种:暴力求解,运行时间为n²;分治算法,运行时间为nlog(n);贪心算法,运行时间为n。显然贪心算法具有优势且运行效率更高。
下面是针对该文件进行的单元测试。
单元测试:
1、单元测试的概念
单元测试是完成最小的软件设计单元(模块)的验证工作,目标是确保模块被正确的编码,使用过程设计描述作为指南,对重要的控制路径进行测试以发现模块内的错误,通常情况下是白盒的,对代码风格和规则、程序设计和结构、业务逻辑等进行静态测试,及早的发现和解决不易显现的错误。
2、单元测试包括:
接口测试:保证进出单元模块的数据流是正确的
内部数据结构:保证临时存储的数据在算法执行过程中的完整性
全局数据结构:全局数据结构对单元模块的影响应当审查
边界:才用边界值分析技术,保证模块在边界条件和极限情况下正常执行
语句覆盖:保证每个语句执行一次
错误路径:对所有处理错误的路径进行测试
3、 测试过程及要求
(1) 要求:
类开始是空的,返回都是简单的数值,例如0.
(2)过程
开始:所有单元测试都失败
改进程序,加入正确的逻辑,看到有单元测试通过,并且看到代码覆盖率的增加
重复, 直到所有单元测试都通过,代码覆盖率达到满意的结果。
4、 测试步骤
运行前面完成的类,然后在解决方案--->添加新建项目--->测试--->本机单元测试项目(完成后会出现一个UnitTest1)--->引用(添加前面类所在的cpp文件)--->unittest1.cpp项目--->属性---->VC++目录--->包含目录更改,最后编辑UnitTest1工程的unittest1.cpp。
5、 具体实现及效果截图
博客作业:
我是一名大三学生,现在已经进入大三下学期的学习,回顾近三年的大学生活,发现自己学会了很多,也有很多学的不精以及没有学习的东西。在大一的时候,首先学习了word、Excel、PPT的相关内容,能够熟练的操作这些办公软件。然后学习了c++这门编程语言,知道了各类语句、函数、类…在学习了这些之后,能进行基本的编程,可以写50行左右的代码,进行基本的数学计算。大二学习了java、数据结构这两门课程。Java这门语言和c++有些类似,但又有很大的不同。在学习了java之后,可以类比c++进行一些函数的编写,但更多的是,能进行图形界面的设计以及运用后台代码实现前台的操作。而数据结构这门课程更多的是在学习了之前的那些语言后进一步的提升,可以实现100以上代码的编写、更复杂的要求的实现。然后大三又在此基础上学习了数据库、操作系统、ASP.NET、MATLAB等课程,使我对编程有了更深一步的了解。学会了如何搭建网页、如何编写后台代码使网页上的操作得以实现,例如,搭建一个聊天室。而MATLAB的相关知识则更多用于数学计算。操作系统及数据库是关于一些操作算法和数据存储及使用。目前掌握的编程语言包括c++、java、c#,掌握的开发软件包括visualc++、matlab、数据库、NetBeans。对于未来,希望我可以提高自己的需求分析、项目系统设计能力、团队协作能力,同时提高用已学习掌握的语言编写软件、程序的能力。在目前看来自己有很多不足,希望通过这一个学期的学习与实践,能够提高更多,一天比一天进步。
预习:两人合作
一、 代码规范与代码复审
1、代码规范
现代软件产业经过几十年的发展,一个人单枪匹马完成一个软件的事情已经不可能出现了,软件都是在相互合作中完成的。这就要求我们在做一个有商业价值的项目或者在团队工作时所写代码规范。
代码规范包括:
(1)代码风格规范。代码风格的原则是:简明,易读,无二义性。要求在缩进、行宽、括号、断行与空白的{}行、分行、命名、下划线问题、大小写问题、注释方面有一定的标准。
(2)代码设计规范。在函数、沟通、错误处理(参数处理、断言)、处理c++中的类上面有这严格的要求。
其中处理c++中的类更为重点。
2、代码复审
代码复审的定义:看代码是否在“代码规范”的框架内正确地解决了问题
(1)复审的形式:
自我复审:即自己vs自己,目的是用同伴复审用同伴复审的标准来要求自己。不一定最有效,因为开发者对自己总是过于自信。如果能持之以恒,则对个人有很大好处。
同伴复审:即复审者vs开发者,这种方法简便易行。
团队复审:即团队vs开发者,有比较严格的规定和流程,用于关键的代码,以及复审后不再更新的代码。覆盖率高,但可能效率不高。
同伴复审是软件工程中最基本的复审手段。
(2)复审的目的:
(a)找出代码的错误。
(b)发现逻辑错误。
(c)发现算法错误。
(d)发现潜在的错误和回归性错误
(e)发现可能改进的地方。
(f)教育(互相教育)开发人员,传授经验,让更多的成员熟悉项目各部分的代码,同时熟悉和应用领域相关的实际知识。
(3)代码复审的步骤
复审前要确保代码必须成功地编译,程序员必须测试过代码;程序员必须提供新的代码,以及文件差异分析工具,在面对面的复审中,一般是开发者控制流程,讲述修改的前因后果,但是复审者有权在任何时候打断叙述,提出自己的意见,复审者必须把反馈意见逐一提出;对于复审的结果,双方必须达成一致的意见。复审中要从大局出发,确保更改完相类似的代码又要保证别的功能不变。代码复审后,开发者应该把复审过程中的记录整理出来。
二、结对编程
1、结对编程的概要
结对编程技术是指两位程序员坐在同一工作台前开发软件。与两位程序员各自独立工作相比,结对编程能编写出质量更高的代码。结对编程在生活中类似于越野赛车中驾驶与领航员的关系,两者有共同点——在高速度中完成任务,任务有较高的技术要求,任务失败的代价很高。
2、结对编程的好处
(a)在开发层次,结对编程能提供更好的设计质量和代码质量,两人合作能有更强的解决问题的能力。
(b)对开发人员自身来说,结对工作能带来更多的信心,高质量的产出能带来更高的满足感。
(c)在心理上, 当有另一个人在你身边和你紧密配合, 做同样一件事情的时候, 你不好意思开小差, 也不好意思糊弄。
(d)在企业管理层次上,结对能更有效地交流,相互学习和传递经验,能更好地处理人员流动。因为一个人的知识已经被其他人共享。
3、结对编程的方法
分工、交换、主动参与、平等。
三、给人提意见的方法
“影响 + 反馈”
影响的方法:断言、桥梁、说服、吸引
反馈的方法针对三个层次:最外层(行为和后果)中间层(习惯和动机)最内层(本质和基本属性)
代码托管到仓库:
码云链接:https://gitee.com/wang_hui_ru/fristwork
附录:
//FMax.cpp
#include<iostream>
#include<cstdlib>
using namespace std;
int getMax(int array[],int length)
{
int sum = 0;
int max = 0;
int startIndex = 0; //记录子数组的起始位置
int endIndex = 0; //记录子数组的终止位置
int newStartIndex = 0;
for (int i = 0; i < length; i++) //遍历整个目标数组
{
if (max < 0)
{
max = array[i];
newStartIndex = i;
}
else
{
max += array[i];
}
if (sum < max)
{
sum = max;
startIndex = newStartIndex;
endIndex = i;
}
}
return max;
}
int getstartIndex(int array[],int length)
{
int sum = 0;
int max = 0;
int startIndex = 0;
int endIndex = 0;
int newStartIndex = 0;
for (int i = 0; i < length; i++)
{
if (max < 0)
{
max = array[i];
newStartIndex = i;
}
else
{
max += array[i];
}
if (sum < max)
{
sum = max;
startIndex = newStartIndex;
endIndex = i;
}
}
return startIndex;
}
int getendIndex(int array[],int length)
{
int sum = 0;
int max = 0;
int startIndex = 0;
int endIndex = 0;
int newStartIndex = 0;
for (int i = 0; i < length; i++)
{
if (max < 0)
{
max = array[i];
newStartIndex = i;
}
else
{
max += array[i];
}
if (sum < max)
{
sum = max;
startIndex = newStartIndex;
endIndex = i;
}
}
return endIndex;
}
int main()
{
int array[]={-32,-10,33,-23,32,-12,41,-12,1,3,5,-98,70,-21,10,-9,61};
int length=17;
cout<<"最大子数组的和为:"<<getMax(array,length)<<endl;
cout<<"最大子数组开始的下标为:"<<getstartIndex(array,length)<<endl;
cout<<"最大子数组结束的下标为:"<<getendIndex(array,length)<<endl;
system("pause");
return 0;
}
//unittest1.cpp
#include "stdafx.h"
#include "CppUnitTest.h"
#include "FMax.cpp"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest1
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(TestMethod1)
{
// TODO: 在此输入测试代码
int a[]={-32,-10,33,-23,32,-12,41,-12,1,3,5,-98,70,-21,10,-9,61};
Assert::AreEqual(12,getstartIndex(a,17));
}
TEST_METHOD(getstartIndex_Test)
{
// TODO: 在此输入测试代码
int a[]={-32,-10,33,-23,32,-12,41,-12,1,3,5,-98,70,-21,10,-9,61};
Assert::AreEqual(16,getendIndex(a,17));
}
TEST_METHOD(getendIndex_Test)
{
// TODO: 在此输入测试代码
int a[]={-32,-10,33,-23,32,-12,41,-12,1,3,5,-98,70,-21,10,-9,61};
Assert::AreEqual(111,getMax(a,17));
}
};
}