一个再复杂的算法程序,都是由循环、条件、顺序三种控制语句构成的(switch语句也可以转化为条件语句)。而这三种语句中,循环语句的使用是其中的关键。循环语句用来遍历和操作对应的数据结构,在遍历的过程中,完成对数据的处理和问题的解决。因此,编程对循环的熟练掌握与使用是很必要的。
通常,一个循环是从一个首地址开始,通过内存单元地址(或指针)的移动,最终达到目标地址或flag标志。
下面把常用的各类循环语句列出,方便大家在编程的时候使用:
1 数组
for (int i = 0; i < n; i++){ printf(“%d”, a[i]);}
下标是相对于数组起始地址a的偏移量,i++表示每次移动一个数据类型的内存单元长度。
for的循环次数确定,因此循环结束条件也是确定的:i < n。
i++……→n。
2 字符串
while (*str !=’0’){ str++;}
C风格字符串以数组存储字符,以"0"为结束标志,而字符串名自然是这个数组的起始地址。
下标是相对于数组起始地址a的偏移量,i++表示每次移动一个数据类型的内存单元长度。
str++……→0。
3 链表
typedef struct lnk{ int data; struct lnk* next;}*lnkPtr;lnkPtr p;……while (p){ p = p->next;}
对于链表,尾部结构会特殊处理,将next指针置为NULL,这样在循环时便可以将此作为结束标志。
链表的指针域指向相邻结点,因此指针的移动用p = p->next;表示。
对于指针的赋值,可以理解为指针指向。如p = p->next;可以理解为p指向p->next。
p = p->next……→p(NULL)
4 栈空/栈满/队空/队满
while(!stk.empty()) // 栈非空{ stk.pop(); // 出栈; // 操作出栈元素}
栈、队列有顺序栈(一般用数组实现)和链式栈(一般用单链表实现)。其循环操作类似上述的数组与链表。在出栈函数中一般定义了内存地址或指针的移动,也类似于上述的数组与链表。
stk.pop()……stk.empty()==0
5 指针大小比较
while (pStart < pEnd){ pStart++;}
pStart++……→pEnd。
6 数为正
while (size--){}//或do{}while(size--)
size--……→0。
7 反复循环直到条件成熟
while(1){ if (something is true) break;}
死循环中添加一个退出条件。
8 STL中的迭代器
list lst(4,111);list::iterator it; // 迭代器类一般定义为其容器类的内部类for(it=lst.begin(); it != lst.end(); it++) // 迭代器类中一般重载了++、*等运算符{ cout<< *it << " " ;}
迭代器类定义一般作为内部类定义在各容器类中,通常包含有一个容器元素的指针,通过重载++、*等运算符及返回迭代器的成员方法,实现一些类似行为的相同名称接口,这样,各容器类型的迭代器用法都基本一致。
it++……→lst.end()。
9 写在最后
熟练各种循环语句以及内存地址或指针的移动的写法,便会为理解或实现各种复杂的算法奠定一个较好基础。
用大圆套小圆来理解嵌套循环:
-End-