王朝网络
分享
 
 
 

程序结构的7个证明原理

王朝厨房·作者佚名  2007-01-05
宽屏版  字体: |||超大  

程序结构应遵循7个证明原理,以确保程序的正确性、健壮性、灵活性、可重用和可读性等。

1. 单纯原理

所谓单纯性原理是指变量或指针等的使用遵循单一化的原则,即为不同的用途使用不同的变量或指针。采用了单纯原理,程序就可以明确的反映实际的问题。

如下面的程序,从一个文件中读入数据放到另一个文件中:

FILE* fp = NULL;

fp = fopen(m_strSrcFilePath, "r");

/* 读数据 */

fclose(fp);

/* 对数据进行处理 */

fp = fopen(m_strDesFilePath, "w");

/* 写数据 */

同一个指针变量fp在一个子程序中被用来作为两个不同文件的指针,虽然没有错误,但容易造成对fp理解困难,所以最好这样:

FILE* fpSrc = NULL; /* 源文件 */

FILE* fpDes = NULL; /* 目标文件 */

fpSrc = fopen(m_strSrcFilePath, "r");

/* 读数据 */

fclose(fp);

/* 对数据进行处理 */

fpDes = fopen(m_strDesFilePath, "w");

/* 写数据 */

2. 同型原理

同型原理是指相同逻辑的地方应该有相同的结构;能复用的代码就不要重写,用宏或者子程序实现。

例如下面这两个循环:

for(i = 0; i < m_aLinkMan.GetSize(); i++);

for(i = 0; i <= m_aLinkMan.GetSize()-1; i++);

仔细一看,会发现这两个循环其实是一样的,但对它们为什么形式不同会感到费解,引起阅读的障碍。

3. 对称原理

对称原理是指成对的操作应该成对地出现,并且出现在对称的位置上。比如:内存的申请与释放、文件的打开与关闭、if语句是否需要相应的else语句等。各系统、组成成分或模块都应遵循对称原理。

在Linux下,对称原理主要表现为以下几点:

malloc等分配内存的函数和free函数必须成对出现,而且必须保证释放掉指针不再被使用。

open/fopen等打开文件的函数和close/fclose函数必须成对出现,而且必须保证关闭的文件描述符或者流指针不再被使用。

使用signal或者sigaction设置信号处理程序时,应该先保存旧的信号处理程序,等处理完毕进行恢复。

还有其他一些函数也必须成对使用,如mmap/munmap,pthread_mutex_init/ pthread_mutex_destroy,sem_init/sem_destroy等等。

对于程序中的模块、函数,如有必要,也应该保持对称。

4. 层次原理

层次原理是形状的层次美原理。例如,意识到事物的主从关系,前后关系,本末关系等层次关系,追求事物应有的形态。必须使各个层次详细化、数据抽象化。层次的规定要彻底。

例如有如下代码:

struct p1 {};

struct p2 {

struct p1 *pp1;

};

struct p2 *pp2;

可以看出结构体p1和p2之间又很明显的层次关系,分配内存时,应先为pp2分配内存,然后为pp2->pp1分配内存;释放时,应该先释放pp2->pp1的内存,然后再释放pp2的内存。

再例如,进行多线程编程时,经常会需要进行互斥或者是信号量操作。那么应该先调用pthread_mutex_lock设置mutex进行互斥,然后再调用sem_wait进行信号量操作。若是顺序弄反了,则会引入一个race condition,从而可能产生死锁。

以上的例子只是比较简单的情况,在程序中可能存在非常复杂的情况,要注意判别。

5. 线性原理

线性原理是指事物的形状是由直线描绘出来的。例如,某个功能,是由几个功能的重叠组合加以实现的。因此,在程序中应该尽量不使用GOTO,SCHEDULE,POST/WAIT等功能。

6. 明证原理

逻辑的明证性原理,即应该努力的说明一些不太清除的逻辑,并且使其具有说服力。

实例:检查接收到的数据中带有的数据序号的连续性。数据序号是用2个byte表示的,从0开始,之后每个递增1,达到 0xffff后,再重头开始。还有,在0xffff上加上1就会变成0。

/*

* nowseq : 接受通知后的数据编号

* oldseq : 接受通知前的数据编号

* 已接受通知的数据编号,不等于接受通知前的数据编号加一,或者

* 被通知前的数据的编号为0xffff,现在已接受通知的编号不为0

*/

if ((nowseq != oldseq + 1)|| (oldseq == 0xffff&& nowseq != 0 )) {

错误处理;

}

这个程序好像是正确的,可是,它有很多否定形的逻辑式,所以比较难以理解。首先,用肯定形式(也就是正常的条件)表示,再加上”!”,作为错误的条件,这样做可以使人放心。按照这样的做法操作,程序会形成下述情况,比原本的程序易懂。

if (!((nowseq == oldseq + 1) || (nowseq == 0 && oldseq == 0xffff))) {

错误处理;

}

原程序中有逻辑错误。也就是, nowseq是0,oldseq是0xffff的时候,满足了if的第一个条件项的nowseq!=oldseq+1,所以虽然是正确的情况却被当成了错误。

7. 安全原理

安全原理是指意识到必然性的原理。例如,忽略没有必然性或者含糊不清的地方,用安全的方法、思想来设计。

举例,有调用程序(Caller)和被调用程序(Callee),两者间调用接口用的参数list是P。Caller没有把P内的Pi域中的初值设定为'0',所以Callee侧是异常操作。

这个故障是在修正程序的时候产生的,调查故障的原因,发现原程序中也有相同的调用部分,那里是正确的代码。也就是说,把P全部清为0,(由此,Pi域的初值就设定为'0' ),然后调用Callee。

修正程序,通过追加一个调用,修正的负责人模仿先前的调用部分,进行了编码,认为把P全体清为0是没有必要的,(可能是想把程序的步骤减少),于是,P全体清0的步骤被省略了。可是,不幸的是, Pi中也混入了错误。

这个例子中的问题是没有照搬正确操作的代码。虽然曾经把它清为0,可是不能保证之后它一直为0。使用前,把参数list清为0,是coding的基本原则。这样做是安全的,所以符合安全原理。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有