2021秋软工实践第一次个人编程作业

BengLuo 2021-09-20 22:43:16
这个作业属于哪个课程 构建之法-2021秋-福州大学软件工程 https://bbs.csdn.net/forums/fzuSoftwareEngineering2021?category=0
这个作业要求在哪里 2021秋软工实践第一次个人编程作业 https://bbs.csdn.net/topics/600840299
这个作业的目标按照作业要求完成代码,并在过程中学会使用git,形成自己的编码规范,最后完成博客撰写
学号031902601

Github部分

参考资料

Git自主手册 https://www.cnblogs.com/math/p/git.html
通过对于参考资料的学习以及朋友们的帮助学会了Github的部分使用,能够完成作业的要求

Github仓库地址

软工实践第一次个人编程作业地址 https://github.com/cs0501/Homework/commits/main

Commit 结果

img

PSP表格

PSP任务内容计划完成需要的实践(min)实际完成需要的时间(min)
Planning计划3045
Estimate估计这个任务需要多少时间,并规划大致工作步骤2025
Development开发--
Analysis需求分析(包括学习新技术)120100
Design Spec生成设计文档--
Design Review设计复审--
Coding Standard代码规范(为目前的开发指定合适的规范)2025
Design具体设计80100
Coding具体编码320300
Code Review代码复审3025
est测试(自我测试,修改代码,提交修改)300360
Test Report测试报告2530
Size Measurement计算工作量2020
Summary合计9651030

解题思路

    第一眼看到题目时,并没有什么思路,不过由于开始完成作业的时间比较晚,已经在群里面看到各路大仙的讨论记录,一方面让我对于作业的实现有了一定的想法,另一方面又使我对饱受探讨的 if-else 和if-else if-else结构的判断充满莫名的恐惧。
    大学以来,几乎只用过C/C++编程的我(Java水平实在不支持我完成这个作业),果断选择C++作为完成作业的编程语言(其实是没得选),就在我准备开始规划代码的实现时,突然发现我连使用C++读取文件都不会(果然菜是原罪),在经过一番学习后,完成作业的路途才走上正轨。
    对于作业要求,我的初步想法是通过逐行读入目标代码,遇到非字母的字符时进行操作,将两次非字母字符之间的字符子串与预设好的关键字数组进行比对,来判断是否为关键字并计数。

#设计实现过程

任务分解

img

代码规范

  • 缩进:同一等级下的代码前面缩进的长度相同,不同等级间差别一个Tab

  • 变量命名:尽量以与变量所要记录的内容相关的单词进行命名

  • 每行最多字符数:单纯代码每行保持在100个字符以内

  • 函数最大行数:除主函数外,其他函数最大行数不超过30行

  • 函数、类命名:尽可能保持函数功能直译并较简洁的进行命名

  • 常量:对于常量以大写命名

  • 空行规则:函数间空一行

  • 注释规则

  • 操作符前后空格

  • 其他规则

代码说明

配对函数

int pairing(string target)
{
    int head = 0, tail = 31, k;
    while (head <= tail)
    {
        k = (head + tail) / 2;
        if (target.compare(stand[k]) < 0)
        {
            tail = k - 1;
        }
        else if (target.compare(stand[k]) > 0)
        {
            head = k + 1;
        }
        else
            return k;
    }
    return -1;
}

通过二分查找来从预设的关键字数组中查找所传入的字符串,若查找成功则返回该关键字在数组中的下标,方便接下来进行switch和if-else的判断,如果查找失败,则返回 -1。

switch case 的判断与计数

pairs = pairing(word);
                if (pairs >= 0 && senten_jd % 2 == 0 && annot_jd == 0)
                {
                    if (pairs == 25)
                    { //对每个 switch 后的 case 进行计数和存储
                        if (switch_num == -1)
                            switch_num++;
                        else
                        {
                            case_nums[switch_num++] = case_num;
                            case_num = 0;
                        }
                    }
                    else if (pairs == 2)
                        case_num++; //遇到 case 时计数


if (case_num > 0)
        case_nums[switch_num++] = case_num;

将switch数量的初始值设为-1,这样第一次出现switch时不将case的数量,计入记录每个switch对应的case数量的数组(有点绕口)。不过这样处理会导致最后一个switch的case数没有计入(如果这个switch存在的话),所以在代码的最结尾加入一个判断,补充最后一个switch的case数量。

if-else和if-else if-else 结构

for (int i = 0; i < len - 1; i++)
        {
            if ((buf[i] >= 'a' && buf[i] <= 'z'))
            {
                word_[li] = buf[i];
                li++;
            }
            else if (buf[i] == '/' && buf[i + 1] == '/')
                break; //当一行中出现注释时,直接跳过这一行
            else if (buf[i] == '"')
            { //当出现引号时,改变判断状态
                senten_jd++;
                li = 0;
            }
            else if (buf[i] == '/' && buf[i + 1] == '*' && annot_jd == 0)
            { //当annot_jd为 1 时进入长注释
                annot_jd = 1;
                li = 0;
            }
            else if (buf[i] == '*' && buf[i + 1] == '/' && annot_jd == 1)
            { //当annot_jd为 0 时离开长注释
                annot_jd = 0;
                li = 0;
            }
            else if (buf[i] == '}')
            {
                while (if_jd.top() != "{")
                    if_jd.pop();
                if_jd.pop();
            }
            else
            {
                word = word_.substr(0, li);
                pairs = pairing(word);
                if (pairs >= 0 && senten_jd % 2 == 0 && annot_jd == 0)
                {
                    if (pairs == 25)
                    { //对每个 switch 后的 case 进行计数和存储
                        if (switch_num == -1)
                            switch_num++;
                        else
                        {
                            case_nums[switch_num++] = case_num;
                            case_num = 0;
                        }
                    }
                    else if (pairs == 2)
                        case_num++; //遇到 case 时计数
                    else if (pairs == 15)
                        if_jd.push("if"); //遇到 if 时将 if 入栈
                    else if (pairs == 9)
                    {
                        if (buf[i] == ' ' && buf[i + 1] == 'i' && buf[i + 2] == 'f')
                        {
                            total_num++;
                            buf[i] = buf[i + 1] = ' ';
                            if (if_jd.top() == "if")
                            {
                                if_jd.pop();
                            }
                        }
                        else
                        {
                            else_num++;
                            if (if_jd.top() == "if")
                            {
                                if_else++;
                                if_jd.pop();
                            }
                        }
                    }
                    total_num++;
                }
                if (buf[i] == '{')
                    if_jd.push("{");
                li = 0;
            }
        }
        word = word_.substr(0, li);
        pairs = pairing(word);
        if (pairs >= 0)
            total_num++;
        if (pairs == 9)
        {

            else_num++;
            if (if_jd.top() == "if")
            {
                if_else++;
                if_jd.pop();
            }
        }

我的代码是使用堆栈的方式来实现这个功能的。作业要求中说明(其实是在群里面公布的):有效的if-else和if-else if-else结构都是以else结尾的,所以我就想以else的数量来代表两种结构的总数量,然后我只要计算出if-else结构的数量,两项相减就得到了另一种结构的数量。
我的设定的规则如下:遇到 if 和 { 时将这两种字符串压入栈;遇到 } 时,若栈顶为 { 则将 { 出栈,否则不断出栈,直至栈顶出现 } 并将其出栈;遇到else if 时,若栈顶为 if ,则将该 if 出栈,并在将 else if 中 if 计入总数后将 if 抹去 ,否则只需在将 else if 中 if 计入总数后将 if 抹去;遇到else 时,将else_num 加 1,若栈顶为 if 则将 if-else 结构数加 1 。
最后 if_else 代表 if-else 结构的数量,else_num - if_else 代表 if-else if-else 结构的数量。

输出函数

void output(int l, int to, int swi, int *ca, int ie, int en)
{
    if (l > 0)
        cout << "total num: " << to << endl;
    if (l > 1)
    {
        cout << "switch num: " << swi << endl;
        cout << "case num: ";
        for (int i = 0; i < swi; i++)
            cout << ca[i] << " ";
        cout << endl;
    }
    if (l > 2)
        cout << "if-else num: " << ie << endl;
    if (l > 3)
        cout << "if-elseif-else num: " << en - ie << endl;
}

通过输入的不同level来判断需要输出哪些内容。

单元测试

代码样例运行结果

img

样例代码: 测试样例代码 https://github.com/cs0501/Homework/commit/23e3dc510278fb10c58f87dde985af8261868ad4

性能测试

img

img

img

测试过程:使用Visual Studio 2019中自带的测试功能,通过选中性能探查器,选择检测功能进行测试

img

img

覆盖率测试

img

个人总结

  • Github的学习使用,Github能够将本地仓库与线上仓库相联系更新,方便代码的更新和迭代,就是在正常上网情况下,网站偶尔会崩盘属实是有点难受

  • 代码方面,在很久没有敲代码的情况下,这次作业真的是很艰难QAQ,很多常用的函数都不太记得了,编程过程中很多地方都可以说是“面向CSDN编程”。由于开始时没有规划好,导致几种不同要求的实现都包括在了主函数里,使主函数显得很臃肿,完成后又不敢修改,怕重新拆分代码后,一个不小心就是各种编译错误,最后只能不了了之。

  • 最后,这次编程作业让我深刻认识到自己代码量的不足和编程的不熟练,作为计算机专业的学生,属实是需要多多寻找任务来提高自己的编程能力。

...全文
281 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
SoftwareTeacher 2021-09-22
  • 打赏
  • 举报
回复

这次编程作业让我深刻认识到自己代码量的不足和编程的不熟练

请加紧练习

189

社区成员

发帖
与我相关
我的任务
社区描述
福州大学软件工程教学,推行邹欣老师“构建之法”。
软件工程 高校
社区管理员
  • Dawnfox
  • REP1USONE
  • 纪华裕
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧