• C Primer Plus学习笔记(六)- C 控制语句:分支和跳转


    • if 语句:

    if 语句被称为分支语句(branching statement)或选择语句(selection statement)

    if 语句的通用形式:

    if (expression)
    	statement
    

    如果 expression 为真,则执行 statement;否则,跳过 statement

    与 while 循环一样,statement 可以是一条简单的语句也可以是复合语句

    if 语句 和 while语句的区别:如果满足条件可执行的话,if 语句只能测试和执行一次,而 while 语句可以测试和执行多次

    • if else语句:

    if else 语句的通用形式

    if (expression)
    	statement1
    else
    	statement2
    

    如果 expression 为真(非 0),则执行 statement1;如果 expression 为假或 0,则执行 else 后面的 statement2

    statement1 和 statement2 可以是一条简单语句或复合语句

    如果要在 if 和 else 之间执行多条语句,必须用花括号把这些语句括起来成为一个块

    如果没有花括号,else 与离它最近的 if 匹配,除非最近的 if 被花括号括起来

    if 语句用于选择是否执行一个行为,而 if else 语句用于在两个行为之间选择

    多重选择 else if:

    else if 语句的通用形式

    if (expression1)
    	statement1
    else if (expression2)
    	satement2
    else if (expression3)
    	statement3
    else
    	statement4
    

    如果 expression1 为真(非0),则执行 statement1;如果 expression2 为真(非0),则执行 statement2;如果 expression3 为真(非0),则执行 statement3;否则执行 statement4

    • 关于 _Bool 类型:

    如果在程序中包含了 stdbool.h 头文件,便可用 bool 代替 _Bool 类型,用 true 和 false 分别代替 1 和 0
    如果系统不支持 _Bool 类型,可以把 isPrime 的类型改为 int,并用 1 和 0 分别替换程序中的 true 和 false

    逻辑运算符:

    逻辑运算符 含义
    &&
    ||
    !

    假设 exp1 和 exp2 是两个简单的关系表达式:

    • 当且仅当 exp1 和 exp2 都为真时,exp1 && exp2 才为真(所有条件为真才为真)
    • 如果 exp1 或 exp2 为真,则 exp1 || exp2 为真(有一个条件为真就为真)
    • 如果 exp1 为假,则 !exp1 为真;如果 exp1 为真,则 !exp1 为假(条件为假则为真,条件为真则为假)

    备选拼写:iso646.h 头文件

    如果在程序中包含该头文件,就可以用 and 代替 &&,or 代替 ||,not 代替 !

    if (ch != 'a' && ch != 'b')
    	count++;
    
    也可以写为
    
    if (ch != 'a' and ch != 'b')
    	count++;
    

    优先级

    ! 运算符的优先级很高,比乘法运算符还高,与递增运算符的优先级相同,只比圆括号的优先级低

    && 运算符的优先级比 || 运算符高,但是两者的优先级都比关系运算符低,比赋值运算符高

    求值顺序

    C 保证逻辑表达式的求值顺序是从左往右的

    && 和 || 运算符都是序列点,所以程序在从一个运算对象执行到下一个运算对象之前,所有的副作用都会生效

    C 保证一旦发现某个元素让整个表达式无效,便立即停止求值

    while ((c = getchar()) != ' ' && c != '
    ')
    

    读取字符直至遇到第一个空格或换行符,第一个子表达式把读取的值赋给 c,后面的子表达式会用到 c 的值。如果没有求值循环的保证,编译器可能在给 c 赋值之前先对后面的表达式求值

    while (x++ < 10 && x+y < 20)
    

    && 是一个序列点,保证了在对 && 右侧的表达式求值之前,已经递增了 x

    范围

    如果要测试 score 是否在 90~100 的范围内,可以这样写:

    if (score >= 90 && score <= 100)
    

    而不是这样写:

    if (90 <= score <= 100)
    

    这样代码有语义错误

    因为会先判断 (90 <= score),结果为 1(真)或 0(假)

    • 条件运算符:?:

    条件表达式的通用形式:

    expression1 ? expression2 : expression3
    

    如果 expression1 为真(非 0),那么整个条件表达式的值与 expression2 的值相同;

    如果 expression1 为假(0),那么整个条件表达式的值与 expression3 的值相同。

    max = (a > b) ? a : b;
    

    如果 a 大于 b,那么将 max 设置为 a,否则,设置为 b

    • 循环复制:continue 和 break

    continue 语句

    3 种循环都可以使用 continue 语句

    执行到 continue 语句时,会跳过本次迭代的剩余部分,并开始下一轮迭代

    #include <stdio.h>
    
    int main(void)
    {
    	char ch;
    	
    	printf("Enter a char:
    ");
    	while (scanf("%c", &ch) == 1)
    	{
    		
    		if (ch != 'X')
    		{
    			continue;
    			printf("Error
    ");
    		}
    		else
    			printf("Right
    ", ch);
    	}
    	return 0;
    }
    

    运行结果

    前两条输入 a 和 b 的时候,并没有打印 Error,因为 continue 跳过了打印 Error

    continue 语句还可以用作占位符

    例如,循环读取并丢弃输入的数据,直到读到行末尾

    while (getchar() != '
    ')
    	;
    

    当程序已经读取一行中的某些内容,要跳转到下一行开始处时,这种用法很方便

    用 continue 语句:

    while (getchar() != '
    ')
    	continue;
    

     这个使用 continue 语句,可读性更高

    break 语句

    程序执行到循环中的 break 语句时,会终止包含它的循环,并继续执行循环后的语句

    如果 break 语句位于嵌套循环内,它只会影响包含它的当前循环

    break 和 continue 的比较:

    break:

    while ((ch = getchar()) != EOF)
    {
    	if (ch == '
    ')
    		break;    ——————————————
    	printf("Hello World!
    ");  |
    }                              |
    printf("Out While Loop
    ");  ←-|
    

    continue:

                    ————————————————|
                    ↓               |
    while ((ch = getchar()) != EOF) |
    {                               |
    	if (ch == '
    ')             |
    		continue;  ——————————————
    	printf("Hello World!
    ");
    }
    printf("Out While Loop
    ");
    

    箭头是跳转到的地方

    #include <stdio.h>
    
    int main()
    {
    	char ch;
    
    	printf("Enter a char:
    ");
    	while (scanf("%c", &ch) == 1)
    	{
    		if (ch == 'X')
    			break;
    	}
    	printf("Out While Loop
    ");
    
    	return 0;
    }
    

    运行结果

    当输入的为 X,会跳出 while 循环,继续执行 while 循环之后的语句

    • 多重选择:switch 和 break

    switch 语句的形式:

    switch (expression)
    {
    	case label1 : statement1  // 使用 break 跳出 switch
    	case label2 : statement2  // 使用 break 跳出 switch
    	default : statement3
    }
    

    可以有多个 case 标签,default 语句可选

    程序根据 expression 的值跳转到相应的 case 标签处,执行 case 标签处的语句

    然后,执行剩下的所有语句,除非执行到 break 语句进行重定向

    expression 和 case 标签都必须是整数值(包括 char 类型),标签必须是常量或完全由常量组成的表达式

    如果没有 case 标签与 expression 的值匹配,控制则跳转到 default 语句(如果有 default 语句的话)

    否则执行 switch 语句后的语句

    #include <stdio.h>
    
    int main()
    {
    	char ch;
    
    	printf("Enter a char:
    ");
    	while((ch = getchar()) != '#')
    	{
    		if ('
    ' == ch)
    			continue;
    		switch (ch)
    		{
    			case 'a':
    				printf("This is a
    ");
    				break;
    			case 'b':
    				printf("This is b
    ");
    				break;
    			case 'c':
    				printf("This is c
    ");
    				break;
    			default:
    				printf("I don't konw this char
    ");
    		}
    		printf("Test Over!
    ");
    	}
    
    	return 0;
    }
    

    运行结果

    break 语句让程序离开 switch 语句,跳转到 switch 语句后面的下一条语句

    如果没有 break 语句,就会从匹配标签开始执行到 switch 末尾

    #include <stdio.h>
    
    int main()
    {
    	char ch;
    
    	printf("Enter a char:
    ");
    	while((ch = getchar()) != '#')
    	{
    		if ('
    ' == ch)
    			continue;
    		switch (ch)
    		{
    			case 'a':
    				printf("This is a
    ");
    			case 'b':
    				printf("This is b
    ");
    			case 'c':
    				printf("This is c
    ");
    			default:
    				printf("I don't konw this char
    ");
    		}
    		printf("Test Over!
    ");
    	}
    
    	return 0;
    }
    

    运行结果

    如果只希望处理某个带标签的语句,就必须在 switch 语句中使用 break 语句

    C 语言的 case 一般都指定一个值,不能使用一个范围

    switch 在圆括号中的测试表达式的值应该是一个整数值(包括 char 类型)

    case 标签必须是整数类型(包括 char 类型)的常量或整型常量表达式(即,表达式中只包含整型常量),不能用变量作为 case 标签

    switch 语句不能用 continue 语句

    多重标签

    可以在 switch 语句中使用多重 case 标签

    #include <stdio.h>
    
    int main()
    {
    	char ch;
    
    	printf("Enter a char:
    ");
    	while((ch = getchar()) != '#')
    	{
    		if ('
    ' == ch)
    			continue;
    		switch (ch)
    		{
    			case 'a':
    			case 'A':
    				printf("This is a
    ");
    				break;
    			case 'b':
    			case 'B':
    				printf("This is b
    ");
    				break;
    			case 'c':
    			case 'C':
    				printf("This is c
    ");
    				break;
    			default:
    				printf("I don't konw this char
    ");
    		}
    		printf("Test Over!
    ");
    	}
    
    	return 0;
    }
    

    运行结果

    如果输入的是字母 a,switch 语句会定位到 case 标签为 a 的位置,由于该标签没有关联 break 语句,所以程序流会直接执行下一条语句(case 标签为 A 的语句)

    switch 和 if else

    何时选择 switch 和 if else?

    如果是根据浮点类型的变量或表达式来选择,就无法使用 switch

    如果根据变量在某范围内决定程序流的去向,使用 switch 就很麻烦,这种情况用 if 就很方便

    • goto 语句

    goto 语句也是跳转语句

    continue 和 break 都是 goto 的特殊形式

    goto 语句由两部分构成:声明标签和标签语句

    形式:

    goto label;
    label : statement
    

    goto 语句使程序控制跳转到相应标签语句

    冒号用于分隔标签和标签语句

    标签名遵循变量命名规则

    标签语句可以出现在 goto 的前面或后面

    #include <stdio.h>
    
    int main()
    {
    	int num = 12;
    
    	if (num > 13)
    		goto a;
    	goto b;
    
    	a : printf("The num is bigger than 13
    ");
    	b : printf("The num is smaller than 13
    ");
    	
    	return 0;
    }
    

    运行结果

  • 相关阅读:
    VS2005下安装boost
    NOIP2017宝藏 [搜索/状压dp]
    SCOI2008奖励关 [状压dp]
    莫队算法解析
    SCOI2005 互不侵犯 [状压dp]
    Codeforces ----- Kefa and Dishes [状压dp]
    TSP问题之状压dp法
    NOI2001炮兵阵地 [状压dp]
    状压dp入门
    「网络流24题」餐巾计划问题
  • 原文地址:https://www.cnblogs.com/sch01ar/p/9026888.html
Copyright © 2020-2023  润新知