分享

控制流

 问见 2016-03-01

C 语言是一种 “高级” 语言,所谓的高级,就是拥有逻辑控制语句,可以使得我们实现诸如 循环、分支、跳转等操作。我们来逐一分析。

第一,循环语句。 C语言中,总共有3种循环语句,它们分别是 while 循环, do_while 循环 , 和 for 循环。

1,while循环,下面是示例代码:

int a = 0;

while( a < 100 )  // 每循环一次a加1,总共循环100次。
{
        printf("%d\n", a);
        a++;
}

上面的例子虽然简单,但已经说明白了while循环的用法了,当程序碰到 while (表达式)  时,系统会计算表达式的值,如果表达式的值为真,那么就执行后面的循环体,即后面用一对花括号包含起来的所有语句。 执行完之后,再来计算一遍这个表达式,如果还是为真,那就把循环体在执行一遍,就这样不断地重复,一直到表达式的值为假为止。如果 while(表达式)  中的表达式永远为真,那就是所谓的 死循环,永不退出。

上面的例子由于 a 的值会不断地递增,当 a 等于 100 时, 表示 a < 100 不成立,值为假,循环退出。

仔细观察 while 循环结构,你会发现,while 循环中的循环体有可能不会被执行,因为循环条件可能一开始就不成立。如果你需要你的循环体代码至少被执行一遍,那么推荐你使用另一种循环结构:

2,do-while 循环,下面是示例代码:

int a = 0;

do{
        printf("%d\n", a);
        a++;
}while( a < 100 ); // 每循环一次a加1,总共循环100次。

注意,在 do-while 循环结构中,while语句后面有一个分号,不能省略。上面这段代码的意思是:开始的时候不管三七二十一,先来打印一遍a的值,然后 加1,然后再来判断条件是否成立,成立则继续循环,不成立则退出循环。

除此之外,C语言还有第三种循环结构,也是最常用的循环结构:

3,for循环,先来看示例代码:

int a;
for(a = 0; a < 100; a++)
{
        printf("%d\n", a);
}

从代码中得知,for循环中,for语句里面有 3 个表达式,第一个表达式是 a = 0, 这个表达式仅在最开始的时候被执行一遍,然后就跟for循环没有任何关系了,这个表达式一般称为循环变量初始化表达式,示例中 a 就是循环变量,被初始化为0。 第二个表达式是 a < 0, 这个表达式相当于 while 循环和 do-while 循环中的循环条件,当这个条件为真时,执行循环体,否则退出循环,这个表达式一般称为条件测试表达式。 第三个表达式是 a++ , 这个表达式在执行完整个循环体之后执行,一般用来更新条件变量。

事实上,以上代码完全等价于:

int a;
a = 0;
for(; a < 100; )
{
        printf("%d\n", a);
        a++;
}

注意到,for 语句当中的表达式可以被移除,但是两个分号不可省略。

C语言中除了循环结构,还有分支跳转结构,它们分别是:

1, if 语句 和 if - else 语句,请看示例代码:

int a = 100;

if( a%2 == 0)
{
        printf("a 是偶数");
}
else
{
        printf("a 是奇数");
}

上述代码中,使用了if - else 语句,在if 语句中,有一个表达式 a%2 == 0, 这个表达式的值决定了程序是否执行 if 语句所包含的代码块,即第 5 行。 如果该语句为真,则执行第 5 行,否则执行 else所包含的语句,即第 9 行。

注意,else语句不可单独使用, 它必须要跟if 语句配套使用。 if 语句所带的代码块和else 语句所带的代码块是互斥的,换句话说,它们是程序执行的两路分支,非此即彼,不可同时执行。 那如果不是两路分支,而是多路分支呢? 此时可以写成 阶梯形 的if - else 语句,例如:

int color = red;

if(color == yellow)
{
        printf("黄色");
}
else if(color == blue)
{
        printf("蓝色");
}
else if(color == red)
{
        printf("红色");
}
else if(color == pink)
{
        printf("粉色");
}
else
{
        printf("不认识的颜色");
}

这段代码展示了所谓的阶梯形的 if - else 语句,用来实现多路分支,代码中的各种颜色是互斥的,运行时只会打印其中的一种。

事实上,要实现上述的多路分支,有一个更好的选择:switch。请看打印颜色的另一个版本代码:

int color = red;

switch(color)
{
case yellow:
        printf("黄色");
        break;
case blue:
        printf("蓝色");
        break;
case red:
        printf("红色");
        break;
case pink:
        printf("粉色");
        break;
default:
        printf("不认识的颜色");
}

这段代码实现跟上面 阶梯形 if - else 代码完全一样的功能,但是明显更加简洁易读,其主要的语法要点有:

1, switch(表达式) 语句中的那个表达式的类型必须是一个整型(包括字符型)

2, case语句后面的表达式必须是一个整型常量。比如100, 200, 或者yellow,blue等宏常量或者枚举常量,或者'A', 'X', 等字符常量。

3, case语句是一个入口标签,程序会先计算switch语句的值,然后跟下面的所有case语句相比较,如果相等则执行下面的代码,否则跳过。 另外, case 标签是只管进去不管出来的,换句话讲,如果要让 color 的值为 yellow 时只打印“黄色”,那在第 6 行下面必须有一句break 语句,否则,程序将会将“蓝色”也打印出来,直到遇到右花括号或者break语句为止。

4, default语句是可选的。 如果有这条语句,它的意思是:假如所有的情况都不匹配,那么就执行default的语句。

最后,C语言中还有一位“臭名昭著”的家伙: goto,在任何书籍中都被警告为会破坏程序逻辑的语句,编程者少用为妙。情况到底是怎样的呢?

goto 语句在语法结构上,确实跟刚刚提到的那些“正常”的控制流不同,它几乎不受约束,它可以跳转到任意你所指定的位置,这样做的后果是程序代码太自由,滥用将会使得整个程序面临无法阅读的境地,但是goto语句并不可怕,翻开LINUX源代码,你不仅可以看到goto语句的身影,而且它出现的频率还相当地高,但是用的多不代表用的广,goto语句往往只被用在一个地方:出错处理。

C语言跟C++比较,缺少所谓的异常捕获机制,在工程中,为了更好地管理代码,往往会将出错处理代码统一放在一个地方,程序中当发现有错误的时候,就可以使用goto 语句直接跳转到该代码处进行处理。这么做的好处是,程序中出错的地方可能被深层嵌套在函数或者循环语句当中,要一层一层地返回无疑极其繁琐, goto语句的直接跳转特性使得这一切都不再是问题。

linux

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多