音乐中文网站模板,网站自适应尺寸,宜宾建设招标网站,wordpress建站视屏《构建之法》 读书笔记 娄雨禛 PB16060356 第一部分 关于结对编程的体悟与实践 在结对编程这一部分我曾讲过很多的注意点#xff0c;比如代码变量命名风格、缩进风格、注释风格#xff0c;前后语句次序风格#xff0c;等等。然而这里还有一些新的东西。代码风格这个老掉牙的…《构建之法》 读书笔记 娄雨禛 PB16060356 第一部分 关于结对编程的体悟与实践 在结对编程这一部分我曾讲过很多的注意点比如代码变量命名风格、缩进风格、注释风格前后语句次序风格等等。然而这里还有一些新的东西。代码风格这个老掉牙的话题咱们先搁置不谈而说说在结对编程中同样重要的其他注意点。 代码复审 代码复审是一门学问。良好而有序的复审将帮助我们快速排查问题和增进代码可读性而低劣的复审则纯粹在浪费时间。这里拿我在个人项目中的代码举一个例子。 1 void anothermain(char *fileString)2 {3 char *offset fileString;4 char move;5 char temp;6 7 int count;8 do9 {10 if(temp *offset)11 {12 if(temp 32 temp 126)13 {14 Characters;15 if(temp 65 temp 122)16 {17 if(temp 91 temp 96)18 {19 offset;20 continue;21 }22 else23 {24 offset;25 word[0] temp;26 }27 }28 else if(temp 49 temp 57)29 {30 offset;31 while(*offset 49 *offset 57)32 {33 Characters;34 offset;35 }36 while((*offset 49 *offset 57) || (*offset 65 *offset 90) || (*offset 97 *offset 122))37 {38 Characters;39 offset;40 }41 continue;42 }43 else44 {45 offset;46 continue;47 }48 }49 else50 {51 if(*offset 10)52 enterNum;53 offset;54 continue;55 }56 }57 else58 break;59 if(temp *offset)60 {61 if(temp 32 temp 126)62 {63 Characters;64 if(temp 65 temp 122)65 {66 if(temp 91 temp 96)67 {68 offset;69 continue;70 }71 else72 {73 offset;74 word[1] temp;75 }76 }77 else if(temp 49 temp 57)78 {79 offset;80 while(*offset 49 *offset 57)81 {82 Characters;83 offset;84 }85 while((*offset 49 *offset 57) || (*offset 65 *offset 90) || (*offset 97 *offset 122))86 {87 Characters;88 offset;89 }90 continue;91 }92 else93 {94 95 offset;96 continue;97 }98 }99 else
100 {
101 if(*offset 10)
102 enterNum;
103 offset;
104 continue;
105 }
106 }
107 else
108 break;
109 if(temp *offset)
110 {
111 if(temp 32 temp 126)
112 {
113 Characters;
114 if(temp 65 temp 122)
115 {
116 if(temp 91 temp 96)
117 {
118 offset;
119 continue;
120 }
121 else
122 {
123 offset;
124 word[2] temp;
125 }
126 }
127 else if(temp 49 temp 57)
128 {
129 offset;
130 while(*offset 49 *offset 57)
131 {
132 Characters;
133 offset;
134 }
135 while((*offset 49 *offset 57) || (*offset 65 *offset 90) || (*offset 97 *offset 122))
136 {
137 Characters;
138 offset;
139 }
140 continue;
141 }
142 else
143 {
144 offset;
145 continue;
146 }
147 }
148 else
149 {
150 if(*offset 10)
151 enterNum;
152 offset;
153 continue;
154 }
155 }
156 else
157 break;
158
159 if(temp *offset)
160 {
161 if(temp 32 temp 126)
162 {
163 Characters;
164 if(temp 65 temp 122)
165 {
166 if(temp 91 temp 96)
167 {
168 offset;
169 continue;
170 }
171 else
172 {
173 offset;
174 word[3] temp;
175 for(count 4; isLetterOrNum(*offset); offset, count)
176 {
177 Characters;
178 word[count] *offset;
179 }
180 word[count] \0;
181 NumOfWords;
182 SolveTheWord(word);
183 }
184 }
185 else if(temp 49 temp 57)
186 {
187 offset;
188 while(*offset 49 *offset 57)
189 {
190 Characters;
191 offset;
192 }
193 while((*offset 49 *offset 57) || (*offset 65 *offset 90) || (*offset 97 *offset 122))
194 {
195 Characters;
196 offset;
197 }
198 continue;
199 }
200
201 else
202 {
203 offset;
204 continue;
205 }
206 }
207 else
208 {
209 if(*offset 10)
210 enterNum;
211 offset;
212 continue;
213 }
214 }
215 else
216 break;
217
218
219 }
220 while(*offset ! \0);
221 } 这是我在进行匆忙的数据结构转型时书写的非常潦草的代码。虽然潦草但还是包含了我的很多想法比如进肯能利用“流式操作”减少机器的循环流程提高代码效率尽管这样会使代码变得非常难读。很快我就意识到了这样的操作虽然节省了机器执行的时间却大大浪费了我自己的时间。这段代码的可读性非常的差以至于我自己常常被绕晕。其中杂乱的命名方式就不多说了简直不忍卒读。由于是一次个人作业又到了马上要提交的截止日期我只关心这段程序的执行结果是否正常作用是判断是否为一个单词并进行储存因此在最后输出结果正确之下我就没有再对它进行优化和修改。 而如果这换成一次结对编程将会怎样呢 是的代码复审就登场了。那么下面我就结合这个例子简要说说应该怎样利用复审改进代码。 Step1“自己改你说我看”不符合共同协定的编码风格的地方一律修改 我们需要在一开始就商定好代码风格比如哪些地方需要换行变量的命名规则等等。 然后先过自己这一关——自己对代码进行修改。比如在上面的例子中函数名为anothermain这是什么鬼意思这种根本不知其所以然的命名必须根除。还有像enternum这样的变量也会让人摸不着头脑应该改为characterNum这种规范的命名。 在自己认为没有大毛病之后还需要对方对自己进行挑错。在这里挑错要注意一个原则不要在鸡蛋里挑骨头要本着找出有意义的错误的原则认真查错。比如“这样的函数命名会不会和以后的命名冲突从而引起歧义” Step2探讨潜在的逻辑问题预防“逻辑灾害”的发生 上面这段代码的逻辑完全是给机器看的对于人类阅读者来说几乎看不下去。这时候虽然程序在执行的时候结果没有问题代码还是得改。把从头执行到尾的“流式操作”改为稍微慢一些却容易阅读地多的代码我们可以增加一些执行很小功能的函数然后反复调用它们。这样将得到容易阅读得多的代码。 Step3修改完后也不松懈继续进行经验总结 总结这个步骤是让我们“事半功倍”的不二捷径。它不容忽视 在修改之后代码变成了下面这样。 1 void WordCheck(FILE *fp)2 {3 bool stop false;4 bool isEmpty false;5 char ch; // ch gets the character one by one6 short check 0; // to check if the first four characters are letters7 short i 0;8 9 ch fgetc(fp);
10 if(ch EOF)
11 isEmpty true;
12
13 for(; !stop; ch fgetc(fp)) // if it is not the end of the text
14 {
15 if(ch 32 ch 126)
16 characterNum;
17 if(ch \n)
18 lineNum;
19
20 if(check 4) // to check the first four characters
21 {
22 if(ch EOF)
23 {
24 stop true;
25 if(isEmpty false)
26 lineNum;
27 }
28
29 else if(IsLetter(ch) true)
30 {
31 check;
32 tempWord[i] ch;
33 i; // search for the next
34 }
35 else
36 {
37 i 0;
38 check 0;
39 ClearTemp();
40 }
41 }
42 else // first four characters are all letters, ready to store
43 {
44 if(IsSeparator(ch) || ch EOF) // have met a separator, store the word
45 {
46 i 0; // roll back to the beginning in the next search
47 check 0; // roll back to the beginning in the next search
48
49 wordNum; // have found another word
50 StoreWord(); // store the word
51 ClearTemp(); // prepare for the next search
52
53 if(ch EOF)
54 {
55 stop true;
56 if(isEmpty false)
57 lineNum;
58 }
59 }
60
61 else // have not met a separator, keep searching
62 {
63 tempWord[i] ch;
64 i; // search for the next
65 }
66 }
67 }
68 } 根据运行结果显示修改后的代码运行时间是原来的两倍但我们却获得了清爽得多的函数。这应该是一个好的结果至少在对速度的要求不高的情况下。 然而如果我们进行过程序优化就会发现这是一个很令人诧异的结果——代码的运行时间变成了原来的两倍这究竟是怎么回事呢 原来在新的函数中我采取了反复调用子函数的措施来精简代码。而在我的子函数中我为了继续精简代码又套用的新的子函数这里进行了两次的套用。而在判断是否为一个单词并进行储存的时候这种层层调用的次数是超乎想象的。正是这里头的反复嵌套大大拖慢了程序的运行速度。 接下来是进行修改在不损失代码简洁性的前提下进行代码优化其中主要是性能优化。我首先要做的是把两层的函数嵌套改为一层。 注意在这里我并没有把子函数放上来是出于阅读的简洁性和直观性——直接把我的实践结论告诉大家而不是用代码和大家继续兜圈子。 通过将两层的函数嵌套改为一层我的子函数从原来的16行变成了42行可以说复杂了不少但接下来我们看一下运行效率。 代码的运行时间大约是最初运行时间的 1.4 倍。 这个结果比第一次优化的结果好了不少但没有达到本次代码优化的最终目的——在不损失性能的前提下进行感官上阅读体验的提升。当然我也已经知晓了代码变慢的原因——函数嵌套和函数调用花去了太多无用的时间接下来的优化步骤也明晰了。 转载于:https://www.cnblogs.com/RainLou/p/9008681.html