《代码大全》读书笔记——第14、15、16章

本文探讨了如何通过合理组织代码结构和优化控制流程提升软件质量。内容覆盖直线型代码组织、条件语句使用及循环控制等方面,旨在帮助开发者编写更易读、维护的程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  这次准备连续写三章的读书笔记,因为这三章讲得都是很基础但又容易让人忽略的细节问题。

 

第14章 组织直线型代码

14.1 必须要有明确顺序的语句。

  设法组织代码,使得依赖关系变得非常明显。要非常明显,非常是重点。例如下面的子程序就是具备明显的依赖关系:

InitExpenseData(), ComputeExpenseData(), PrintComputeDataResult();后面的一个子程序总是需要依赖前面的子程序。

14.2 顺序无关的语句

  使代码易于自上而下地阅读。言下之意,就是要让别人能够按照常规逻辑顺序阅读你的代码。比如下面的代码:

 

ContractedBlock.gifExpandedBlockStart.gif代码
MarketingData marketData;
marketData.ComputeQuarterly();
marketData.ComputeAnnual();
marketData.Print();

SalesData salesData;
salesData.ComputeQuarterly();
salesData.ComputeAnnual();
salesData.Print();

 

  把相关的语句组织在一起。如果按照这种规定来编写代码,那么你的代码看起来就一个代码块非常明显地区别于其他代码块。

 

第15章 使用条件语句

  这一章看似根本没什么可以讲,可是相信里面讲得东西你不一定都能做到。

15.1 if语句

  首先写正常代码路径,再处理不常见情况。

  把正常情况的处理放在if后面不要放在else后面。可是我有时候就颠倒过来了,因为一般错误处理情况代码比较少,我放在前面,看起来自己觉得比较舒服。可是如果遇到嵌套的if,那就必须把正常情况放在if后面,因为这样看起来逻辑性会比较强,可读性也比较强。如:

 

ContractedBlock.gifExpandedBlockStart.gif代码
if (status == Status_success)
{
// do something
if (status == Status_success)
{
// do something
if (status == Status_success)
{
// do something
}
else
{
// error control
}
}
else
{
// error control
}
}
else
{
// error control
}

 

 

if-then-else 语句

  利用布尔函数调用简化复杂的检测。这点稍微有点经验的人都知道,当你的if-else语句判断需要做大量工作的时候,把判断代码抽象成一个布尔函数来调用,并把最常见的情况放在最前面,确保所有情况都考虑到了。

 

15.2 case语句

  为case选择最有效的顺序。可以按字母、数字、执行频率来排列顺序。

  不要为了使用case而可以制造一个变量。东西都是如此,太刻意的结果往往是不好的结果。该用case则用case,不该用case就用if-else语句。

  把default语句只用于检查默认情况。有多少人写switch-case不把default加进去?反正我是看过好几次了,应该利用default来检测错误,除非你真的考虑全面确定不会出现意外情况了,你确定??所以一般还是老老实实把default写进去来检测错误。

  另外,避免复杂的case嵌套,别让自己费脑子,更别让维护你代码的人有撞墙的冲动。

 

第16章 控制循环

16.1 选择循环的种类

  什么时候使用带退出的循环?如果把循环条件检测放在循环开始或者结束处,那就需要写出一个半循环的代码。

  看看下面重复的代码:

 

ContractedBlock.gifExpandedBlockStart.gif代码
score = 0;
GetNextRating(
&ratingIncrement);
rating
= rating + ratingIncrement;

while (score < targetScore)
{
GetNextScore(
&ScoreIncrement);
score
= score+ ScoreIncrement;
GetNextRating(
&ratingIncrement); // 重复代码
rating = rating + ratingIncrement;
}

接下里使用半循环改写,让代码易于维护:

 

 

ContractedBlock.gifExpandedBlockStart.gif代码
score = 0;

while (true)
{
GetNextRating(
&ratingIncrement);
rating
= rating + ratingIncrement;

if (score < targetScore)
{
break;
}

GetNextScore(
&ScoreIncrement);
score
= score+ ScoreIncrement;

}

 

 

16.2 循环控制

  避免循环出现错误发生的两种方法:一是减少能影响循环各种因素的数量。也就是说,你的循环应该足够的简单。二是把循环内部看作一个子程序,把控制尽量放到循环体外,把循环执行条件表达清楚。即:将循环看作一个黑盒子,外面的程序不知道循环里面做了什么,只知道循环的控制条件,这是最理想的情况。

进入循环:

  1. 只从一个位置进入。一般人都会这样做,除非你嫌你的程序太简单,搞一个goto进入到循环里;

  2. 把初始化代码放在循环前面。呃,这点和我做得不同,我一般是用到变量之前才进行初始化。但是书中谈到要按照就近原则,把相关代码放在一起;

  3. 用while(true)表示无限循环,或者for( ; ; )也可以;

  4. 在适当情况多使用for循环。我也是倾向于for,因为for循环给人的感觉比较清晰,不容易出错。


处理好循环:

  1. 用'{', '}'把循环语句括起来;

  2. 避免空循环。这点我倒是没注意,有时候就写了空循环,如下面:

 

while ( (ch = getchar()) != EOF)
{
;
}

  实际上循环控制中包括了两条语句,为了让代码更加清晰,可写成:

 

 

do
{
ch
= getchar();
}
while (ch != EOF);

  一个循环只做一件事:

 

  符合UNIX的哲学:一个工具只做一件事,并且做好。

 

退出循环:

  使循环条件看起来很明显。

  不要为了终止循环而胡乱改动for循环的下标。有些程序员为了贪图方便是会写出这样的代码来的。比如下面:

 

for (int i = 0; i < 100; ++i)
{
if ( ... )
i
= 100;
// ...
}

  一旦你写了for循环,循环计数就不是你能控制的。如果你想对循环更多的控制,考虑改用while。

 

  避免出现依赖于循环下标最终取值的代码。我犯过这样的错误,也是为了贪图方便:

 

ContractedBlock.gifExpandedBlockStart.gif代码
for (recordCount = 0; recordCount < MAX_RECORDS; ++recordCount)
{
if ( entry[recordCount] == testValue )
break;
}
if (recordCount < MAX_RECORDS)
return true;
else
return false;

  这里通过recordCount来检测循环是否执行到最后面一次了。这样的代码也可理解,但是阅读你代码的人并一定能很快地理解你的代码。考虑使用一个标志:

 

found = false;
for (recordCount = 0; recordCount < MAX_RECORDS; ++recordCount)
{
if (entry[recordCount] == testValue)
{
found
= true;
break;
}
}
考虑使用安全计数器。这个也可以尝试,但是我一般也没用到。

 

使用循环变量:

  在嵌套循环中使用有意义的变量名来提高可读性。太多的程序都是用i, j, k这样的变量来写了,我之前也曾这样写,上一个项目开始就没这样写过了,取个好的名字总是能让代码看起来清爽很多。

  把循环下标变量的作用域限制在本循环内。也就说,循环下标在这个循环内用到后,在循环外面都没再用到了。例如上面那个利用循环下标来判断是否找到了值的例子。

 

16.3 轻松创建循环——由内而外

  其实我们大部分人对循环的思考还是这种由内而外的思维方式的,即先想这循环内要做什么事,具体哪些,逻辑顺序排好了之后剩下的只是在外面加一个for或者while了。

 

END

 

转载于:https://www.cnblogs.com/python_newbie/archive/2010/06/24/1763039.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值