为什么需要3个不同的循环:" while"," do-while"和" for"存在于c / c ++中,特别是当它们中的每一个都赋予你几乎任何其他2可以做的事情的权力时?其他语言缺少其中一种。
是否只是为了方便使用或使代码在某些情况下看起来更好,或者是否有任何特殊目的由其中任何一个专门用于其他两个无法轻松完成?如果是,那么请提及。
P.S。 - 一般来说,语言是否支持多种迭代语法只是为了增强可读性?
答案 0 :(得分:2)
这不仅仅是可读性,它还是密切相关但又独特的可维护性,简洁性和范围(特别是文件,锁,智能指针等)和性能....
如果我们考虑for
循环,那么:
允许定义一些变量 - 在for
循环自己的范围内 - 并初始化,
每次进入循环之前测试一个控制表达式(包括第一个),
有一个语句,在每次迭代后和重新测试控制表达式之前执行,假设没有break
/ return
/ throw
/ exit
/失败assert
等,无论是否执行了正文中的最后一个语句或是否执行了continue
语句;这个陈述传统上保留用于逻辑上“推进”一些状态“通过”处理,这样控制表达式的下一个测试是有意义的。
这非常灵活,并且考虑到更多本地化作用域的实用程序以确保更早的析构函数调用,可以帮助确保锁定,文件,内存等尽可能早地释放 - 隐藏在离开循环时。
如果我们考虑while
循环......
while (expression to test)
...
......它在功能上完全等同于......
for ( ; expression to test; )
...
...但是,它也意味着程序员没有控制变量应该是循环的局部变量,并且控件“要测试的表达式”固有地“进行”通过有限数量的迭代,循环永远如果测试表达式是硬编码的true
,或者更复杂的“进度”管理必须由while
控制的语句控制和协调。
换句话说,看到while
的程序员会自动意识到他们 需要更仔细地研究控件表达式 ,然后可能会更广泛地看待它们周围的范围/函数和包含的语句,以了解循环行为。
那么,do
- while
?好吧,编写这样的代码既痛苦又效率低下:
bool first_time = true;
while (first_time || ...)
{
first_time = false;
...
}
// oops... first_time still hanging around...
......与...相比。
do
...
while (...);
while loop:
int i = 23;
while (i < 99)
{
if (f(i)) { ++i; continue; }
if (g(i)) break;
++i;
}
// oops... i is hanging around
For loop:
for (int i = 23; i < 99; ++i)
{
if (f(i)) continue;
if (g(i)) break;
}
答案 1 :(得分:0)
好吧,C ++有goto
你可以使用它来实现所有三个循环,但它并不意味着它们应该被删除。实际上它只是增加了可读性。当然你可以自己实现其中任何一个。
答案 2 :(得分:0)
使用for
最容易编写一些循环,有些循环最容易使用while
编写,有些循环最容易使用do
- while
编写。因此语言提供了所有三种语言。
出于同样的原因,我们有+=
运算符之类的东西; +=
没有做任何与普通+
无关的事情,但使用它(如果适用)可以使您的代码更具可读性。
答案 3 :(得分:0)
通常,当提供用于实现类似目的的不同语言结构时,您应该选择更清楚地传达您正在编写的代码的预期目的的结构。 C提供四种不同的结构化迭代设备是有益的,因为它提供了一个很好的机会,可以清楚地传达预期的目的。
for (
初始化 ;
条件 ;
迭代步骤 )
< EM>体 这个表单传达了循环如何开始,如何调整下一次迭代的内容,以及在循环中保持什么条件。这种结构自然适合做N
次的事情。
for (int i = 0; i < N; ++i) {
/* ... */
}
while (
条件 )
正文 此表单简单地表示您希望在条件保持为真时继续执行循环。对于 iteration-step 隐含于循环工作方式的循环,它可以是一种更自然的方式来传达代码的意图:
while (std::cin >> word) {
/* ... */
}
do
正文 while (
条件 )
此表单表示循环体将至少执行一次,然后在条件保持为真时继续循环。这对于您已经确定需要执行正文的情况很有用,因此可以避免冗余的测试。
if (count > 0) {
do {
/* ... */
} while (--count > 0);
} else {
puts("nothing to do");
}
递归是另一种迭代形式,表示可以使用相同的函数处理原始问题的较小部分。这是一种表达分歧和征服策略的自然方式(如二进制搜索或排序),或处理自引用的数据结构(如列表或树)。
struct node {
struct node *next;
char name[32];
char info[256];
};
struct node * find (struct node *list, char *name)
{
if (list == NULL || strcmp(name, list->name) == 0) {
return list;
}
return find(list->next, name);
}