[华为云在线课程][C语言基础][三][流控制][学习笔记]

举报
John2021 发表于 2022/10/02 14:24:11 2022/10/02
【摘要】 程序语言中的控制流语句用于控制各计算操作执行的次序。 1.语句与程序块在表达式之后加上一个分号,就可以变成一个语句。在C语言中,分号就是语句结束符。用一对花括号把一组声明和语句括在一起就构成了一个复合语句(程序块),复合语句语法上等价于单条语句。 2.if-else语句if-else语句用于条件判定,语法为:if {表达式} 语句1else 语句2语句执行时,先计算表达式的值,如...

程序语言中的控制流语句用于控制各计算操作执行的次序。

1.语句与程序块

在表达式之后加上一个分号,就可以变成一个语句。在C语言中,分号就是语句结束符。
用一对花括号把一组声明和语句括在一起就构成了一个复合语句(程序块),复合语句语法上等价于单条语句。

2.if-else语句

if-else语句用于条件判定,语法为:

if {表达式}
    语句1
else
    语句2

语句执行时,先计算表达式的值,如果为真(非0),执行语句1;为假(0)且语句包含else部分,执行语句2。

3.else-if语句

在C语言中经常用到以下结构:

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

这种if语句序列是编写多路判定最常用的方法。其中的各表达式依次求值,一旦某个表达式结果为真,则执行相关的语句,并终止整个语句序列的执行。最后一个else部分用于处理所有条件均不成立的情况。
现在通过一个折半查找函数说明三路判定的用法。该函数用于判定已排序的数组 v 中是否存在某个特定的值 x。数组 v 的元素必须以升序排列。如果 v 中包含 x,则该函数返回 x 在 v 中的位置(介于0~n-1之间的一个整数);否则,该函数返回-1。
在折半查找时,首先将输入值 x 与数组 v 的中间元素进行比较。如果 x 小于中间元素,则在该数组的前半部分查找;否则,在数组的后半部分查找。

int binsearch(int x,int v[],int n)
{
    int low,high,mid;
    low=0;
    high=n-1;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(x<v[mid])
        {
            high=mid+1;
        }else if(x>v[mid])
        {
            low=mid+1;
        }
        else
        {
            //找到了
            return mid;
        }
    }
    //没找到
    return -1;
}

练习3-1:

/*
在上面折半查找例子中,while循环语句内共执行了两次测试,其实只要一次就可以。(将更多测试在循环外执行)
重写该函数,使得在循环内部只执行一次测试。
*/
#include <stdio.h>

int binsearch(int x, int v[], int n);

int main()
{
    int test[] = {2, 4, 6, 8, 10, 12, 14};
    int i;
    for (i = (sizeof(test) / sizeof(int)) - 1; i >= 0; --i)
    {
        printf("查找= %d, 下标= %d\n", test[i], binsearch(test[i], test, sizeof(test) / sizeof(*test)));
    }
    return 0;
}

int binsearch(int x, int v[], int n)
{
    int low, high, mid;
    low = 0;
    high = n - 1;
    while (low < high)
    {
        mid = (low + high) / 2;
        if (x <= v[mid])
        {
            high = mid;
        }
        else
        {
            low = mid + 1;
        }
    }
    return (x == v[low]) ? low : -1;
}
/*
查找= 14, 下标= 6
查找= 12, 下标= 5
查找= 10, 下标= 4
查找= 8, 下标= 3
查找= 6, 下标= 2
查找= 4, 下标= 1
查找= 2, 下标= 0
*/

4.switch语句

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

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

每个表达式都有一个或多个整数值常量或常量表达式标记。如果某个分支与表达式的值匹配,则从该分支开始执行。如果没有匹配,就执行default分支,default分支是可选的。

/*
用switch语句编写一个程序,统计各个数字、空白符及其它所有字符出现的次数。
 */
#include <stdio.h>

int main()
{
    int c, i, nwhite, nother, ndigit[10];
    nwhite = nother = 0;
    for (i = 0; i < 10; i++)
    {
        ndigit[i] = 0;
    }
    while ((c = getchar()) != EOF)
    {
        switch (c)
        {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            ndigit[c - '0']++;
            break;
        case ' ':
        case '\n':
        case '\t':
            nwhite++;
            break;
        default:
            nother++;
            break;
        }
    }
    printf("digits = ");
    for (i = 0; i < 10; i++)
    {
        printf(" %d", ndigit[i]);
    }
    printf(", white space = %d, other = %d\n", nwhite, nother);
    return 0;
}

break语句将导致程序立即执行从switch语句中退出。在switch语句中,case的作用只是一个符号,在某个分支中的代码执行完后,程序将进入下一分支继续执行,除非在程序中显式跳转。跳出switch语句最常用的方式使用break和return。
好处是可以把若干个分支组合在一起完成一个任务,但要注意在最后一个分支(default)后面也要加上break语句。降低犯错误的可能性。
练习3-2:

/*
编写一个函数escape(s,t),将字符串t复制到字符串s中,
并在复制过程中将换行符、指标符等不可见字符分别转换成
\n \t 等相应的可见的转移字符序列。要求使用switch语句。
在编写一个具有相反功能的函数,在复制过程中将转义字符序列
转换成实际字符。
 */
#include <stdio.h>

void escape(char *s, char *t);
void unescape(char *s, char *t);

int main()
{
    char text1[50] = "\aHello, \n\tWorld! \"Again\n";
    char text2[51];

    printf("原始字符串: \n%s\n", text1);
    escape(text2, text1);
    printf("转换后的字符串: \n%s\n", text2);
    unescape(text1, text2);
    printf("反转后的字符串: \n%s\n", text1);

    return 0;
}

void escape(char *s, char *t)
{
    int i, j;
    i = j = 0;
    while (t[i])
    {
        switch (t[i])
        {
        case '\n':
            s[j++] = '\\';
            s[j] = 'n';
            break;
        case '\t':
            s[j++] = '\\';
            s[j] = 't';
            break;
        case '\a':
            s[j++] = '\\';
            s[j] = 'a';
            break;
        case '\b':
            s[j++] = '\\';
            s[j] = 'b';
            break;
        case '\f':
            s[j++] = '\\';
            s[j] = 'f';
            break;
        case '\r':
            s[j++] = '\\';
            s[j] = 'r';
            break;
        case '\v':
            s[j++] = '\\';
            s[j] = 'v';
            break;
        case '\\':
            s[j++] = '\\';
            s[j] = '\\';
            break;
        case '\"':
            s[j++] = '\\';
            s[j] = '\"';
            break;
        default:
            s[j] = t[i];
            break;
        }
        ++i;
        ++j;
    }
    s[j] = t[i];
}

void unescape(char *s, char *t)
{
    int i, j;
    i = j = 0;
    while (t[i])
    {
        switch (t[i])
        {
        case '\\':
            switch (t[++i])
            {
            case 'n':
                s[j] = '\n';
                break;
            case 't':
                s[j] = '\t';
                break;
            case 'a':
                s[j] = '\a';
                break;
            case 'b':
                s[j] = '\b';
                break;
            case 'f':
                s[j] = '\f';
                break;
            case 'r':
                s[j] = '\r';
                break;
            case 'v':
                s[j] = '\v';
                break;
            case '\\':
                s[j] = '\\';
                break;
            case '\"':
                s[j] = '\"';
                break;
            default:
                s[j++] = '\\';
                s[j] = t[i];
            }
            break;
        default:
            s[j] = t[i];
        }
        ++i;
        ++j;
    }
    s[j] = t[i];
}

5.while循环与for循环

while (表达式)
    语句

在while循环语句中,首先求表达式的值。如果值非0,执行语句,再次求该表达式的值。直到表达式的值为0为止,然后继续执行后面的部分。下面的for循环和while循环是等价的。

for 循环语句;
for (表达式1 ; 表达式2 ; 表达式3)
    语句
//------------------------------
表达式1;
while (表达式2)
{
    语句
    表达式3;
}

for循环语句的3个组成部分都是表达式。最常见的是,表达式1与表达式3是赋值表达式或函数调用,表达式2是关系表达式。3个部分任一部分都可以省略,分号必须保留。省略了表达式1和3会变成while循环语句。省略表达式2,值就永远变成是真值,需要借助break或者return才能终止循环。
如果没有初始化或重新初始化的操作,使用while语句更自然一些;如果语句中需要执行简单的初始化和变量递增,使用for语句更合适一些。

6.do-while循环

C语言中的第三种循环,do-while循环则在循环体执行后测试终止条件,这样循环体至少被执行一次。

do
    语句
while (表达式);

7.break语句与continue语句

不通过循环头部或尾部地条件测试而跳出循环,可以使用break语句。break语句能使程序从switch语句或最内层循环中立即跳出。

/* 
函数trim用于删除字符串尾部的空格符、制表符与换行符。当发现最右边的字符为非空格符、非制表符、
非换行符时,就使用break语句从循环中退出。
 */
int trim(char s[])
{
    int n;
    for(n=strlen(s)-1 ; n>=0 ; n--)
    {
        if( s[n] != ' ' && s[n] != '\t' && s[n] != '\n')
        {
            break;
        }
        s[n+1] = '\0';
        return n;
    }
}

continue语句与break语句是相关联的,但没有break语句常用。continue语句用于使循环语句开始下一次循环的执行。在while和do-while中,continue语句的执行意味着立即执行测试部分;在for循环中,则意味着使控制转移到递增环变量部分。continue语句只用于循环语句,不用于switch语句。某个循环包含的switch语句中的continue语句,将导致进入下一次循环。

/*
这段程序用于处理数组a中的非负元素。如果某个元素的值为负,则跳过不处理。
*/
for (i=0 ; i<n ; i++)
{
    if (a[i] < 0)
    {
        continue;
    }
}

8.goto语句与标号

C语言提供了可随意滥用的goto语句及标记跳转位置的符号。大多数情况下,使用goto语句的程序段比不使用goto语句的程序段要难以理解和维护,建议尽可能少地使用goto语句。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。