189
社区成员
发帖
与我相关
我的任务
分享| 这个作业属于哪个课程 | 构建之法-2021秋-福州大学软件工程 https://bbs.csdn.net/forums/fzuSoftwareEngineering2021?category=0 |
|---|---|
| 这个作业要求在哪里 | 2021秋软工实践第一次个人编程作业 https://bbs.csdn.net/topics/600840299 |
| 这个作业的目标 | 按照作业要求完成代码,并在过程中学会使用git,形成自己的编码规范,最后完成博客撰写 |
| 学号 | 031902601 |
Git自主手册
https://www.cnblogs.com/math/p/git.html
通过对于参考资料的学习以及朋友们的帮助学会了Github的部分使用,能够完成作业的要求
软工实践第一次个人编程作业地址 https://github.com/cs0501/Homework/commits/main

| PSP | 任务内容 | 计划完成需要的实践(min) | 实际完成需要的时间(min) |
|---|---|---|---|
| Planning | 计划 | 30 | 45 |
| Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 20 | 25 |
| Development | 开发 | - | - |
| Analysis | 需求分析(包括学习新技术) | 120 | 100 |
| Design Spec | 生成设计文档 | - | - |
| Design Review | 设计复审 | - | - |
| Coding Standard | 代码规范(为目前的开发指定合适的规范) | 20 | 25 |
| Design | 具体设计 | 80 | 100 |
| Coding | 具体编码 | 320 | 300 |
| Code Review | 代码复审 | 30 | 25 |
| est | 测试(自我测试,修改代码,提交修改) | 300 | 360 |
| Test Report | 测试报告 | 25 | 30 |
| Size Measurement | 计算工作量 | 20 | 20 |
| Summary | 合计 | 965 | 1030 |
第一眼看到题目时,并没有什么思路,不过由于开始完成作业的时间比较晚,已经在群里面看到各路大仙的讨论记录,一方面让我对于作业的实现有了一定的想法,另一方面又使我对饱受探讨的 if-else 和if-else if-else结构的判断充满莫名的恐惧。
大学以来,几乎只用过C/C++编程的我(Java水平实在不支持我完成这个作业),果断选择C++作为完成作业的编程语言(其实是没得选),就在我准备开始规划代码的实现时,突然发现我连使用C++读取文件都不会(果然菜是原罪),在经过一番学习后,完成作业的路途才走上正轨。
对于作业要求,我的初步想法是通过逐行读入目标代码,遇到非字母的字符时进行操作,将两次非字母字符之间的字符子串与预设好的关键字数组进行比对,来判断是否为关键字并计数。
#设计实现过程

缩进:同一等级下的代码前面缩进的长度相同,不同等级间差别一个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。
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数量。
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来判断需要输出哪些内容。

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



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



Github的学习使用,Github能够将本地仓库与线上仓库相联系更新,方便代码的更新和迭代,就是在正常上网情况下,网站偶尔会崩盘属实是有点难受
代码方面,在很久没有敲代码的情况下,这次作业真的是很艰难QAQ,很多常用的函数都不太记得了,编程过程中很多地方都可以说是“面向CSDN编程”。由于开始时没有规划好,导致几种不同要求的实现都包括在了主函数里,使主函数显得很臃肿,完成后又不敢修改,怕重新拆分代码后,一个不小心就是各种编译错误,最后只能不了了之。
最后,这次编程作业让我深刻认识到自己代码量的不足和编程的不熟练,作为计算机专业的学生,属实是需要多多寻找任务来提高自己的编程能力。
这次编程作业让我深刻认识到自己代码量的不足和编程的不熟练
请加紧练习