02. Conditinal Branching - if-else, else-if
2.01 if
2.1.01 Syntax
if (表达式) 语句
2.1.02 Description
如果表达式的值为真,则执行其后的语句,否则不执行该语句。
2.1.03 Picture Show
2.1.04 Example Source
实例1. 求两个数中的最大值
#include <stdio.h>
int main (void)
{
int num_1, num_2, max;
printf("
Please input two numbers: ");
scanf(“%d,%d”, &num_1, &num_2);
max = num_1;
if (max < num_2)
max = num_2;
printf("max=%d", max);
return 0;
}
实例2. 对交换算法的研究
方法1:利用中间变量直接交换
2.02 if-else
2.2.01 Syntax
if (表达式)
语句1;
else
语句2;
2.2.02 Description
如果表达式的值为真,则执行语句1,否则执行语句2。
2.2.03 Picture Show
2.2.04 Example Source
实例1. 求两个数中的最大值
#include <stdio.h>
int main (void)
{
int num_1, num_2;
printf("
Please input two numbers: ");
scanf("%d%d", &num_1, &num_2);
if (num_1 > num_2)
printf("max = %d.
", num_1);
else
printf("max = %d.
", num_2);
return 0;
}
2.03 if-else-if
2.3.01 Syntax
if (表达式1)
语句1;
else if (表达式2)
语句2;
else if (表达式3)
语句3;
...
else if (表达式m)
语句m;
else (表达式n)
语句n;
2.3.02 Description
01. 依次判断表达式的值,则执行其对应的语句;然后跳到整个if语句之外继续执行程序;如果所有的表达式均为假,则执行语句n;然后继续执行后续程序;
02. 这种if语句序列是编写多路判定最常用的方法,其中的各表达式将被依次求值,一旦表达式结果为真,则执行与之相匹配的语句,并终止整个语句序列执行;
03. 最后一个else部分用于处理“上述条件均不成立”的情况或默认的情况,也就是当上面各条件都不满足时的情形,如果并不需要针对默认情况执行显式的操作,那可以把else 语句;这部分去掉;该部分用于捕获“不可能”的条件。
2.3.03 Picture Show
2.3.04 Example Source
实例1. 从键盘输入任意一个字符,判断字符是数字、大写字母、小写字母还是其它字符?
#include <stdio.h>
int main (void)
{
char c;
printf("
Input a character: ");
c = getchar();
if (c < 32)
printf("This is a control character.
");
else if (c >= '0' && c <= '9')
printf("This is a digit.
");
else if (c >= 'A' && c <= 'Z')
printf("This is a capital letter.
");
else if (c >= 'a' && c <= 'z')
printf("This is a small letter.
");
else
printf("This is an other character.
");
return 0;
}
01. 本例要求判断键盘输入字符的类型,可以根据输入字符的ASCII码来判断类型;
02. 由ASCII码表可知ASCII值小于32的为控制字符;
03. 在“0”和“9”之间的为数字;
04. 在“A”和“Z”之间的为大写字母;
05. 在“a”和“z”之间的为小写字母;
06. 其余则为其它字符;
07. 这是一个多分支选择的问题,用if-else-if语句编程,判断输入字符ASCII码所在的范围,分别给出不同的输出。
2.05 Diligence
01. 在三种形式的if语句中,在if关键字之后均为表达式;该表达式通常是逻辑表达式或关系表达式,但也可以是其它表达式,如赋值表达式等甚至可以是一个变量:例如:if (a = 5) 语句; if (b) 语句; 都是允许的;只要表达式值为非0,即为“真”;
02. 在if语句中,条件判断表达式必须用括号括起来,在语句之后必须加分号;
03. 在if语句中,所有的语句都单个语句,如果想在满足条件时执行一组多个语句时,必须把这一组语句用“{}”括起来组成一个复合语句,但要注意的是在“}”之后不能再加分号;
2.06 Traps & Pitfalls
01. if (a = 5)
语句;
中表达式的值永远为非0,所以其后的语句总是要执行的,这种情况也是合法的;
所以使用时如果是“==”经常会少写一个“=”那就差之千里了,当变量跟数字的比较时,把数字放前面是很明智的选择!
02. 省略else的危险
因为if-else语句的else部分是可选的,所以在嵌套的if语句中省略它的else部分将导致歧义;
解决的方法是将每个else与最近的前一个没有else配对的if进行匹配;
if (n > 0)
if (a > b)
z = a;
else
z = b;
else 部分与内层的if匹配,我们通过程序的缩进结构也可以看出来,如果不符合我们的意图,必须使用花括号强制实现正确的匹配关系;
if (n > 0) {
if (a > b)
z = a;
}
else
z = b;
03. Conditinal Selection - switch
3.01 Definition
01. C 语言还提供了另一种用于多分支选择的 switch 语句;
02. 它测试 expression 是否与一些常量整数值中的某一个值匹配,并执行相应的分支动作。
3.02 Syntax
switch (expression) {
case constant-expression_1:
statement_1;
break;
case constant-expression_2:
statement_2;
break;
... ...
... ...
case constant-expression_n:
statement_n;
break;
default:
statement_n+1;
break;
}
3.03 Description
01. 计算 switch 括号里 expression 的值,并逐个与其后的常量 expression 相比较;
02. 当 expression 的值与某个 constant-expression 的值相等时,即执行其后的语句;
03. 然后不再进行判断,继续执行后面所有 case 后的语句;
04. 各分支 expression 必须互不相同,否则编译器会报错;
05. 如果 expression 的值与所有 case 后的 constant-expression 均不相等时,则执行 default 后面的语句;
06. 如果没有default分支也没有其它分支与expression的值匹配,则该switch语句不执行任何动作;
07. 各分支及 default 分支的排列次序是任意的,所以这里可以有很多的技巧可以来把玩了;
08. 每个 switch 语句中只能出现一条 default 子句;
09. case 的作用只是一个标号,因此,某个分支中的代码执行完后,程序将进入下一分支继续执行,除非在程序中显式地跳转;
10. break 语句将导致程序的执行立即从 switch 语句中退出;
11. 也可以使用 return 或 exit 的方法跳出程序,从而跳出了循环;
12. 其中 expression 的结果必须是整型值。
3.04 Example Source
实例1. 下列语句执行后,z 的值为?
int x = 3, y = 4, z = 0;
switch (x % y + 2) {
case 0:
z = x * y;
break;
case 6:
z = x / y;
break;
case 12:
z = x - y;
break;
default:
z= x * y - x;
}
实例2. 从键盘输入任意一个字符,判断字符是控制字符、数字、大写字母、小写字母还是其它字符?
#include<stdio.h>
int main(int argv, char **argc)
{
char c;
printf("please input a character:");
c = getchar();
switch(c){
case 0 ... 32:
printf("This is a control character.
");
break;
case '0' ... '9':
printf("it's a digit.
");
break;
case 'a' ... 'z':
printf("it's a small letter.
");
break;
case 'A' ... 'Z':
printf("it's a capital letter.
");
break;
default:
printf("This is an other character.
");
break;
}
return 0;
}
注意:
01. “case 0 ... 32:”是GNU的扩展;
02. 格式为:[空格] ... [空格],是范围从0到32。
实例3.
switch (grade) {
case 'A':
printf("你的期末成绩为A,真是太有才了!");
break; // 另忘记要中断,跳出判断,不执行后面的语句
case 'B':
printf("你的期末成绩为B,还不错!");
break;
case 'C':
printf("你的期末成绩为C,你给我小心着点!");
break;
default:
printf("你未能通过考试,等着补考吧!");
}
3.04 Diligence
01. switch语句有优点,程序看起来清晰了;
02. switch语句也有缺点,一个分支执行完了必须以一个 break 语句结束,不然会进入下一个分支执行,而下一个分支并不是你想要的执行;
03. 除了一个计算需要多个标号的情况外,应尽量减少从一个分支直接进入下一个分支执行这种用法,在不得不使用的情况下应该加上适当的程序注释;
04. 最后一个分支后面加上 break 语句,这样做在逻辑上没有必要,但当我们需要向该 switch 语句添加其它分支时,这种防范措施会降低犯错误的可能性。
04. Local Jumps - goto and lables
4.01 Definition
goto 语句的作用是跳转到你指定标号的一条语句,然后从那条语句开始往下执行。
4.02 Syntax
标号: 语句;
goto 标号;
4.03 Description
01. 在你想要跳往的语句前面加个标号和冒号;
02. 标号的命名要符合标识符命名规则;
03. 标号必须与 goto 语句同处于一个函数中,但可以不在一个循环层中;
04. 通常 goto 语句与 if 条件语句连用,当满足某一条件时,程序跳到标号处运行。
4.04 Example Source
实例1. 用goto语句,求1+2+3+...+10的值?
#include <stdio.h>
int main (void)
{
int i = 1, sum = 0;
LOOP:
if (i <= 10) {
sum = sum + i;
i++;
goto LOOP;
}
printf("1+2+3+...+10 = %d
", sum);
return 0;
}
4.05 Diligence
01. goto语句是没有必要的,实践中不使用goto语句也可以很容易地写出代码;
02. goto语句使得程序丧失完整的结构,进而失去可读性;