1. 到底使用if-else if-else还是使用switch-case?
基本上在所有的编程语言中都会有这些语句,只是表达形式可能不同。初学者可能比较疑惑的是,到底该怎样区分和使用这些语句。下面将if-else if-else语句简称为if语句,将switch-case语句简称为switch语句。
if语句和switch语句都可以用来实现判断选择的逻辑。比如说,当课程代号是0时采取一种操作,当课程代号是1时采取一种操作,···,当课程代号是n时采取一种操作,这个时候我们既可以采用if语句,也可以采用switch语句来实现这个逻辑。但是,这两种语句的使用场合还是值得一提的。一般if语句用于比较常规的判断选择场合,大部分情况下我们都使用if语句来实现判断选择的逻辑,基本上所有现实生活中的判断选择逻辑都可以使用If语句实现。程序员经常喜欢开玩笑的类似的话就是“写不出来负责的逻辑实现?那么就用简单的if else语句嵌套、拼装、组合,慢慢写就出来了。”当然,这只是一个玩笑,在实际的项目中,我们当然不能这样委曲求全,要充分考虑很多条件。不过,这个笑话也充分说明了if语句的强大,它基本上可以通过很白痴的步骤堆出很复杂的逻辑,用处很大。所以,一般情况下,在我们遇到判断选择的逻辑时,都可以考虑使用if语句来实现。这里举一个简单的例子。
/*==========================例1==========================*/
// 根据课程分数来划分不同的等级,然后进行不同的操作
int score = 0;// 分数
int num = 0;// 学号
// 根据学号获得该学生的分数
score = getStudentScore(num);
// 利用if语句划分等级
if (score >= 90 && score <= 100)
{
// A类学生,对该类学生采取一定的操作
}
else if (score >= 80 && score < 90)
{
// B类学生,对该类学生采取一定的操作
}
else if (score >= 70 && score < 80)
{
// C类学生,对该类学生采取一定的操作
}
else if (score >= 60 && score < 70)
{
// D类学生,对该类学生采取一定的操作
}
else
{
// E类学生,对该类学生采取一定的操作
}
例1展示的是一个比较常见的例子,也就是所谓的根据学生的分数对学生进行评级,这个是典型的if语句的应用。那么大家思考一下,这个逻辑能不能采用switch语句来实现呢?我可以先很清楚的告诉大家,是不能采用switch语句来实现这种逻辑的,这是因为这里的每个条件都是一个范围,比如说90分到100分,而switch只能是一个特定的值,所以这里不能采用switch语句来实现。如果要深入考虑这个问题,我们首先要知道的就是switch语句的case条件一般都是什么形式的,我们知道switch相当于选定了某个条件,case相当于对这个条件的结果进行分类,然后对不同的类采用不同的操作,看起来和if语句是类似的,但是我们需要搞清楚正在编程的语言支持case选项是什么类型的,拿C语言来说,当我们用分数来进行分类的时候,case可以选择,但是如果我们的条件是字符串、结构体等其他较为复杂的类型时,就不能采用case来进行选择,这样说起来可能比较抽象,下面我们通过一个例子来看看这个意思。
/*==========================例2==========================*/
int inputNum = 0;
printf("Please input an number:");
scanf("%d", &inputNum);
switch (inputNum)
{
case 0:
// 当输入为0时
break;
case 1:
// 当输入为1时
break;
case 2:
// 当输入为2时
break;
case 3:
// 当输入为3时
break;
default:
// 输入是其他情况
break;
}
例2中,我们通过输入一个数,来进行不同的选择。这个例子比较常见的应用场合就是给用户一个菜单,让用户根据菜单进行选择,用户需要输入一个数字或字母,从而实现菜单的功能选择,然后我们就可以使用这种形式来进行不同选择后的处理。这也是switch语句比较常见的应用场合。回到刚才的问题,我们可以看到这个switch需要用一个整数变量即inputNum进行选择,case就是这个inputNum变量所取值的不同情况。整数的取值是比较清晰的,当然这里也可以采用一个char类型,从而case可以采用'a' 、'b'等这样的条件来进行选择,但是就像例1所述一样,当需要选择的结果是一个范围,或者这里需要选择一个复杂的结构时,就不能采用switch来实现了,switch后面的选择是有一定的局限的,当然,不同的语言可能对这一特性有所扩展,这个要根据具体语言来定。
到这里基本上讲述完了if语句和switch语句的使用场合,简单来说就是,if语句对于判断选择逻辑基本是万能的,而switch语句对于这种逻辑的使用却比较局限,但是,switch语句是有其存在的价值的。首先,采用switch进行选择的时候,结果十分清晰;其次,switch的效率比If的效率要高,程序直接就可以根据条件执行到指定的case,而if语句还需要执行一个个if、else if等。比如说例1中,如果学生的分数是50分,那么判断出这个结果需要执行前面所有的if和else if语句才能执行到这个条件,而对于例2来说,如果输入是3,那么直接就执行case 3这种情况,完全不需要执行case 1和case 2的情况,相当于少执行了很多判断,这样对于大型项目来说会有较多的效率提升。
可见,switch还是有较多优点的,所以我们要根据需求进行选择,对于这两种语句需要强调几点。
(1)if语句中最好都要加上最后的else项,switch语句中最好都要加上最后的default项。原因是,虽然我们的逻辑有时候或者说根本不可能执行到else或default后面的代码,但是对于稳定的系统来说,难免有时候会出现意外的情况,这是难以预料的,当出现意外时,由于else和default这种条件的保护,使得程序不会出现难以预知的结果,这对于大型项目来说是值得考虑的。
(2)switch语句中,每个case后面。包括default后面都会有break语句,这个语句一般情况下是必须的,也就是说当执行完这个case以后,直接就break,跳出switch语句,不再顺序往下执行switch语句中的其他case,从而使得每个case之间是独立的。但是有时候我们可以使用例3这种情况,如下例所示,我们可以将0、1、2三个case进行合并。
/*==========================例3==========================*/
int inputNum = 0;
printf("Please input an number:");
scanf("%d", &inputNum);
switch (inputNum)
{
case 0:
case 1:
case 2:
// 当输入为0、1、2时
break;
case 3:
// 当输入为3时
break;
default:
// 输入是其他情况
break;
}
2. 到底使用do-while还是while-do,还是for循环?
我们先来说do-while和while-do的区别,这两个神似,但是有一个区别,这里简单说一下即可。do-while,都是先do,然后再判断while的条件是否满足,也就是do-while至少使循环体内的语句执行了一次,而while-do则是直接先判断条件是否满足,如果不满足则一次也不执行,这就是它们之间的唯一区别。举个例子就很清楚了。见例4。
/*==========================例4==========================*/
int i = 0;
do
{
// 很多操作
printf("do-while.\n");
} while (i > 1);
while (i > 1)
{
// 很多操作
printf("while-do.\n");
}
运行这个例子可以看到,屏幕上只打印了do-while,很明显,i等于0,所以两个循环的条件都是不满足的,不过do-while还是执行了一次才判断出来不满足条件。所以,在实际应用中,对于这两个循环的选择,我们只需要根据这个特性进行斟酌即可。
下面,我们统称do-while和while-do循环为while循环,与for循环进行比较。
一般情况下,while循环和for循环都可以实现所有循环的逻辑,它们之间可以相互转换,不过它们却有一定的应用场合。举例来看,如例5所示。
/*==========================例5==========================*/
int i = 0;
while (i < 5)
{
// 做一些其他的处理
// 最后再执行i的递增
++i;
}
for (i = 0; i < 5; ++i)
{
// 做一些其他的处理
// 注意,for循环的++i的实际执行位置是在for循环内部
// 的所有语句执行完毕后,也就是这里
}
从例5来看,while循环和for循环都实现了同样的功能,完全等价,但是明显for循环对于i的控制更加紧凑一些,便于管理,而对于while很容易漏掉最后的++i语句,从而出现死循环。请大家务必注意例5中for循环内部的最后一个注释,大家一定要清楚for循环的条件转换(++i)到底是在哪里执行的,这个很容易被忽略。
总之,大家可以根据需要进行选择,一般情况下,在清楚知道条件什么情况下终止的时候采用for循环,比如i<5这种条件,如果不清楚条件什么时候终止可以考虑使用while循环,比如flag == true的这种情况。