我们都知道,循环体可以有五种,while、do while、for、goto和递归。
虽然理论上任何循环都可以用其他四种转换,但是因为goto在安全性以及在功能上能够被取代的特点,所以一般不会用到;而递归的特殊性和编写的困难性使递归的登场次数也屈指可数。
那么,当我们需要用到循环的时候,在剩下的循环体中该如何进行选择呢?我们将讨论这几种循环体根本上的差异。
首先我们看下面这个例子:
用for循环实现简单的文件遍历,然后复制字符
char *newpath = "D:\\test\\10_new.txt";
void main()
{
FILE *pfr = fopen(path,"r");
FILE *pfw = fopen(newpath, "w");
for (int ch = fgetc(pfr); !feof(pfr); ch = fgetc(pfr))
{
fputc(ch, pfw); // for循环
}
下面是用while实现同样的功能:
while (!feof(pfr))
{
char str[256] = { 0 };
fgets(str, 255, pfr);
fputs(str, pfw);
}
接下来是do while
do // 不能处理结尾的EOF
{
int ch = fgetc(pfr); ————1赋值语句一
fputc(ch, pfw); ————2赋值语句二
} while (!feof(pfr)); ————3判断条件
在实验的过程中我们发现,do while并不能实现文件结尾EOF的复制,这是为什么呢?不是说几种循环是可以互相转换的吗?于是我诞生了以下的猜想:
将以上语句进行编号,分别为赋值语句1 2和判断条件 3,接下来我们看一下几种方法的语句执行顺序:
**do & while 的执行顺序为 123 123 123
while 的执行顺序为 312 312 312
这两者改变了3的判断条件出现的位置
for 的执行顺序为 132 132 132
将判断条件3插入到了两个执行语句之间**
也就是说,虽然能够用不同的循环体来进行循环,但这三种循环体的执行顺序还是有差别的,这在某些程序的某些细节上就能体现出来,虽然我们是可以通过一定的方法来强制保证几种方法有一致的功能。
同时,我们也注意到,三种循环体在12执行顺序确定的条件下,完全包含了123 132 312三种可能的执行情况,那么,我们就可以根据这个执行顺序来选择我们所需要的循环体。