控制流

作者: 漫游之光 | 来源:发表于2018-09-12 17:05 被阅读0次

    语句与程序块

    在表达式之后加上一个分号(;),它们就变成了语句。例如:

    x = 0;
    x++;
    printf(...);
    

    在C语言中,分号是语句的结束符。用一对花括号“{”于“}”把一组声明和语句括在一起就构成了一个复合语句(也叫做程序块),复合语句在语法上等价于单条语句。右花括号用于结束程序块,其后不需要分号。

    if-else语句

    if-else语句用于条件判定,其语法示例如下:

    if(表达式)
        语句1
    else
        语句2
    

    其中else部分是可选的。该语句执行时,先计算表达式的值,如果其值为真,则执行语句1;如果其值为假,则不执行语句1,如果其有else,则执行语句2。

    else-if语句

    else-if语句是编写多路判定最常用的方法。其中的各表达式将被依次求值,一旦某个表达式结果为真,则执行与之相关的语句,并且终止整个语句序列的执行。其结构如下:

    if(表达式)
        语句
    else if(表达式)
        语句
    else if(表达式)
        语句
    else
        语句
    

    例子:二分法查找

    /* 二分查找,在v找x,n是数组长度 */
    int binsearch(int x,int v[],int n){
        int low = 0;
        int high = n-1;
        int mid;
    
        while(low <= high){
            mid = low + (high - low)/2;/* 防止溢出 */
            if(v[mid] < x){
                low = mid + 1;
            }else if(v[mid] > x){
                high = mid -1;
            }else{
                return mid;
            }
        }
        return -1;
    }
    

    switch语句

    switch语句是一种多路判定语句,它测试表达式是否与一些常量整数值中的某一个值匹配,并执行相应的分支动作。

    switch(表达式){
        case 常量表达式:语句序列
        case 常量表达式:语句序列
        default:语句序列
    }
    

    每一个分支都由一个或多个整数值常量或常量表达式标记。如果某个分支与表达式的值匹配,则从该分支开始执行。各个分支表达式必须互不相同。如果没有哪一分支能匹配表达式,则执行标记为default的分支。default分支是可选的。如果没有default分支也没有其他分支与表达式的值匹配,则该switch语句不执行任何动作。
    例子:

    /* 把字符串t复制到s,将转义字符打出来 */
    void escape(char s[],char t[]){
        int i;
        int j=0;
        for(i=0;t[i]!='\0';i++){
            switch(t[i]){
                case '\n':
                    s[j++] = '\\';
                    s[j++] = 'n';
                    break;
                case '\t':
                    s[j++] = '\\';
                    s[j++] = 't';
                    break;
                default:
                    s[j++] = t[i];
            }
        }
        s[j] = '\0';
    }
    

    break语句将导致程序的执行立即从switch中退出。在switch语句中,case的作用只是一个标号,因此,某个分支中的代码执行完毕后,程序将进入下一个分支继续执行,除非在程序中显示地跳转。

    while循环与for循环

    在while循环语句

    while(表达式)
        语句
    

    中首先求表达式的值。如果其值为真非0,则执行语句,并再次求该表达式的值。这一循环过程一直进行下去,直到该表达式的值为假(0)为止,随后继续执行语句后面的部分。
    for循环语句:

    for(表达式1;表达式2;表达式3)
        语句
    

    它等价于下列while语句:

    表达式1;
    while(表达式2){
        语句
        表达式3
    }
    

    但当while或for循环语句中包含continue语句时,上述二者就不一定等价了。
    从语法角度看,for循环语句的3个组成部分都是表达式。最常见的情况是,表达式1与表达式3是赋值表达式或函数调用,表达式2是关系表达式。这三个组成部分的任何部分都可以省略,但分号必须保留。如果省略测试条件,即表达式2,则认为其值永远是真值。如果语句中需要执行简单的初始化和变量递增,使用for语句更合适一些,它将循环控制语句集中放在循环的开头,结构更紧凑,更清晰。
    例子:

    /* 将字符串逆序 */
    void reverse(char s[]){
        int i,j;
        char temp;
        for(i=0,j=strlen(s)-1;i<j;i++,j--){
            temp = s[i];
            s[i] = s[j];
            s[j] = temp;
         }
    }
    

    逗号运算符“,”,也是C语言优先级最低的运算符,在for语句中经常会用到它。被逗号分隔的一对表达式将按照从左往右的顺序进行求值,各表达式右边的操作数的类型和值即为其结果的类型和值。某些情况下的逗号并不是逗号运算符,不如分隔函数参数的逗号,分隔声明中变量的逗号等,这些逗号并不保证各表达式从左至右的顺序求值。

    do-while循环的语法形式如下:

    do
        语句
    while(表达式);
    

    在这一结构中,先执行循环体中的语句部分,然后再求表达式的值。如果表达式的值为真,则再次执行语句。依次类推。当表达式变为假,则循环终止。
    例子:

    /* 将n转化为对应的字符串,并存储在s中 */
    void itoa(int n,char s[]){
        int i = 0,sign = 0;
        unsigned int m;
        if(n<0){
            sign = 1;
            m = (unsigned int)(-n);
        }else{  
            m = (unsigned int)n;
        }
        do{
            s[i++] = m%10 + '0';
        }while((m/=10)>0);
        if(sign){
            s[i++] = '-';
        }
        s[i] = '\0';
        reverse(s);
    }
    

    break语句与continue语句

    break语句可用于从for,while与do-while等循环中提前退出,就如同从switch语句中提前退出一样。continue语句用于使for,while或do-while语句开始下一次循环的执行。在while与do-while语句中,continue语句的执行意味着立即执行测试部分;在for循环中,这意味着控制转移到递增循环变量部分。
    例子:

    /* 删除字符串尾部的空格、制表符和换行符 */
    void trim(char s[]){
        int n;
        for(n=strlen(s)-1;n>=0;n--){
            if(s[n]!=' '&&s[n]!='\n'&&s[n] != '\t'){
                break;
            }
        }
        s[n+1] = '\0';
    }
    

    goto语句与标号

    goto语句用于跳转到标号标记的跳转位置。标号的命名通变量命名的形式相同,标号后面要紧跟一个冒号。标号可以位于对应的goto语句所在函数的任何语句的前面。标号的作用域是整个函数。从理论上讲,goto语句是没有必要的,实践中不适用goto语句也可以容易地写出代码。但是,在某些情况下goto语句还是用得着的。最常见的用法是终止程序在某些深度嵌套的结构中的处理过程,例如一次跳出两层或多层循环。例如:

    for( ... ){
        for( ... ){
            ...
            if(disaster)
                goto error;
        }
    }
    error:
        处理错误情况
    

    建议尽可能少地使用goto语句。

    相关文章

      网友评论

          本文标题:控制流

          本文链接:https://www.haomeiwen.com/subject/jxcbgftx.html