2. 循环体的变化操作和定位操作
————————
————————
******************
题目:有字符串a[] = "ChangeAndLocate",编写程序,使a中每个元素加1后存为字符串b并输出。
******************
代码:
#include <stdio.h>
char *str(char pb[], char pa[])
{
char *p = pb;
while (*pa != '\0')
{
*pb = *pa + 1;
//注释1:变化操作
pa++;
//注释2:定位操作
pb++;
//注释3:定位操作
}
*pb = '\0';
return (p);
}
void main(void)
{
char a[] = "ChangeAndLocate";
char b[] = "";
puts(str(b, a));
}
————————
————————
//////////
我们的讲解:
所谓循环操作,即重复的做某种操作组合。这个组合可以由1或n个基本操作组成。我觉得呢,基本操作按作用不同可分为:变化操作和定位操作。
变化操作即实现循环根本功能的语句。比如上面的代码,循环最根本的功能是为了把a中每个元素加1,对应的就是注释1处的操作。
因为变化操作只负责实现“变化”功能,但对谁变化,它可不管。所以需要定位操作语句来为变化操作定位操作对象。在上面的代码中,每变化操作一次,操作对象便后移一位,转到下一个操作对象。又因为在循环语句中,这种定位是有一定顺序的(依次来的嘛),所以可以更形象的称为“循环定位”。
所以呢,循环体由知道“干啥”的变化操作同学和知道“找谁干啥”的定位操作同学一起来决定(还有起始点和终结条件,这里不说了,可以自己思考,哈)。
for循环中,比如for(i=0; i<10; i++),i++就是定位操作。因为for循环的定位操作和变化操作在语句的书写上就是分开的,所以大家一般会感觉使用for语句比其它循环语句更清晰。借鉴这一点,我们得出下面的建议第一项。
//////////
我们的体会:
当遇到循环体复杂时,可以采取下列一些建议提高循环体的清晰度。
1. 把变化操作和定位操作分开想,分开写。最后组合到一起。比如上面的循环体中,不要写(*pb++) = (*pa++) + 1。
2. 别在for循环体内执行定位操作,效率一样,但不直观,使程序缺少易读性(换言之,程序写‘丑’了^_^)。
3. 当遇到变化操作和定位操作同时要用某一个对象进行操作时,可以设置另外一个变量来记录这个要操作的对象。然后分开进行操作。比如把单链表A、B交叉组合成单链表C时,分别指向A、B当前项的两个指针,即要让指针交叉指向下一项,又要定位到下一项。但先定位,那交叉指向时会指错;先变化,也会指错。此时就可以用一个变量记录,那么这个记录的变量和原来的变量就可以一个负责变化一个负责定位了。(本例看不懂的自己写写‘把单链表A、B交叉组合成单链表C’的算法)
4. 别什么循环都想用for循环,或者转换成for循环(喂~你用不腻啊?(⊙o⊙))。比如上面的代码中,如果不知道字符串长度,用while循环代码更清晰。前提是循环体的操作写的清晰。
5. 变化操作和定位操作在一次循环中一般是成对出现的,别少掉谁,或多了谁。要不然在下一个循环中你就掉大了^_^(把这种观念加到对链表的理解中,因为链表老要“扫描”)。
————————
————————