目录前言1 循环语句的三要素2 使用不同循环语句实现六种排列组合2.1 第一种排列(ABC)2.2 第二种排列(ACB)2.3 第三种排列(BCA)2.4 第四种排列(CBA)2.5
你是否也有过下面的体会?
为什么刚开始学习C语言时很喜欢用for循环语句,但逐渐发现有经验的工程师都在用while和do-while循环(看过内核代码的小伙伴应该也注意到这点了)?
在刚开始写循环语句时总分不清什么时候用for,什么时候用while,什么时候又该使用do-while;刚把这些问题搞清楚了,觉得已经熟练掌握了所有循环语句的使用,但又时不时遇到一个新的问题——总得在循环语句中,甚至是循环语句前和循环语句后添加代码,调整语句顺序,否则最终的逻辑就不正确,甚至是出现指针的解引用错误。
当遇到这些问题时,你是否怀疑过C语言的循环语句是自带缺陷的?下面就让我们一起找出困扰我们编程的幕后黑手吧~~
实现一个循环语句的三要素是:
根据上述三个要素的执行顺序,可以得到下述6种排列组合。
编号 | 顺序 |
---|---|
1 | A -> B -> C |
2 | A -> C -> B |
3 | B -> C -> A |
4 | C -> B -> A |
5 | B -> A -> C |
6 | C -> A -> B |
你所编写的程序中都逃不出以上这六种排列组合,下面我们对其一一进行剖析。
这种顺序是我们最最熟悉的,也是最常见的。实现起来并不复杂,也是C语言循环语句最擅长处理的情况。
使用for语句实现
for (; A; C) {
B;
}
使用while语句实现
while (A) {
B;
C;
}
这种顺序我们就不是经常见到了,所以,for语句对它的支持就不是那么友好了,但是while语句没有受到任何影响。
使用for语句实现
for (; A; ;) {
C;
B;
}
使用while语句实现
while (A) {
C;
B;
}
对于这种排列,for语句彻底没脾气了,while语句也蔫儿了,do-while语句可以大显身手了。
使用for语句实现
for (B, C; A; C;) {
B;
}
使用while语句实现
B;
C;
while (A) {
B;
C;
}
使用do-while语句实现
do {
B;
C;
}while (A);
这种排列跟上一种类似。不过对for语句就更不友好了。
使用for语句实现
for (C, B; A; C,B;)
使用while语句实现
C;
B;
while (A) {
C;
B;
}
使用do-while语句实现
do {
C;
B;
}while (A);
对于这种排列,C语言的循环语句们心里都在想,这是什么鬼地方,没见过啊~~
使用for语句实现
for (B; A; ;) {
C;
B;
}
使用while语句实现
B;
while(A) {
C;
B;
}
使用do-while语句实现
它说它不在家,让我们去找break。
使用while-break语句实现
while (1) {
B;
if (!A)
break;
C;
}
这种排列和第五种类似,不使用break仍然无法解决代码重复问题。
使用for语句实现
for (C; A; C) {
B;
}
使用while语句实现
C;
while (A) {
B;
C;
}
使用while-break语句实现
while (1) {
C;
if (!A)
break;
B;
}
通过上面的实验和摸索,我们发现for语句最适合的场景就是第一种排列(ABC)的场景。在应用与其他场景时要么就退化为while,要么就束手无策了。
这就是for语句的缺陷之所在。
所以,你去看linux内核或者其他大型项目,其中的for语句都是比较少的,你所见到的基本都长成下面这两种样子。
#define MAX 100
int i;
for (i = 0; i < MAX; ++i) {
}
我是分割线。。。
for (;;) {
}
第二种应用范式一般都是用在线程死循环中,当然死循环使用while(1)也可以,只能说是大家都这么用习惯了而已,你可以选择自己喜欢的方式。
while语句适用于第一种排列(ABC)和第二种排列(ACB)场景。
这种场景的特点是——A在最开始执行。
do-while语句适用于第三种排列(BCA)和第四种排列(CBA)场景。
这种场景的特点是——A在最后执行 。
其他情况包括第五种排列(BAC)和第六种排列(CAB)场景,以及其他更复杂的场景。
这种场景的特点是——A在中间执行。
这种情景一般就采用whie-break语句来cover了。其实,该语句可以cover住所有场景。
爱刨根问题的同学可能会问,怎么会有这种场景呢?真的有需求么?
那我在此给出一个CABC真实场景的小例子吧,起到抛砖引玉的作用。
while(1){
pstr = find_cmd(fORMat_str, pstr);
if (NULL != pstr)
{
printf("----------------------------------------------------------------------------\n");
printf("|| name \t| %s \n",pstr->name);
printf("|| brief \t| %s \n",pstr->brief);
for (i = 0; i < pstr->arGC; i++)
{
if (pstr->argv[i])
printf("|| @ para%d\t| @ %s \n", i, pstr->argv[i]);
}
printf("----------------------------------------------------------------------------\n");
pstr++;
} else {
break;
}
}
文章已经很长了,最后不废话,直接上表格。
编号 | 顺序 | 合适的循环语句 |
---|---|---|
1 | A -> B -> C | for/while |
2 | A -> C -> B | while |
3 | B -> C -> A | do-while |
4 | C -> B -> A | do-while |
5 | B -> A -> C | while-break |
6 | C -> A -> B | while-break |
x | 复合场景 | while-break |
到此这篇关于C语言进阶教程之循环语句缺陷的文章就介绍到这了,更多相关C语言循环语句缺陷内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: C语言进阶教程之循环语句缺陷详析
本文链接: https://www.lsjlt.com/news/131989.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0