首页 > 代码库 > 【C语言探索之旅】 第一部分第六课:条件表达式

【C语言探索之旅】 第一部分第六课:条件表达式

技术分享


内容简介


1、课程大纲

2、第一部分第六课:条件表达式

3、第一部分第七课预告:循环语句


课程大纲


我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案。还会带大家用C语言编写三个游戏。


C语言编程基础知识


  • 什么是编程?

  • 工欲善其事,必先利其器

  • 你的第一个程序

  • 变量的世界

  • 运算那点事

  • 条件表达式

  • 循环语句

  • 实战:第一个C语言小游戏

  • 函数

  • 练习题

  • 习作:完善第一个C语言小游戏


C语言高级技术


  • 模块化编程

  • 进击的指针,C语言王牌

  • 数组

  • 字符串

  • 预处理

  • 创建你自己的变量类型

  • 文件读写

  • 动态分配

  • 实战:“悬挂小人”游戏

  • 安全的文本输入

  • 练习题

  • 习作:用自己的语言解释指针


用基于C语言的SDL库开发2D游戏


  • 安装SDL

  • 创建窗口和画布

  • 显示图像

  • 事件处理

  • 实战:“超级玛丽推箱子”游戏

  • 掌握时间的使用

  • 用SDL_ttf编辑文字

  • 用FMOD控制声音

  • 实战:可视化的声音谱线

  • 练习题


数据结构


  • 链表

  • 堆,栈和队列

  • 哈希表

  • 练习题



第一部分第六课:条件表达式


上一课《运算那点事》结束后,今天我们来学习《条件表达式》,这一课和下一课《循环语句》是重点,希望大家和小编一起认真学习。当然,其实每一课都要认真学习,好吧,我又说废话了 O(∩_∩)O


在之前的课程中,我们已经知道世界上有很多编程语言,有些相互之间很类似,其中不少都是受了C语言的启发。


事实上,C语言是很早之前被发明的(1972年左右),所以它也成了很多近代的编程语言的参考模板。


我们说编程语言相似,是说他们都汲取了它们的前辈的编程基础。


说到编程基础,那就有很多了。其中,我们已经学过的有:如何创建变量,做运算。这一课我们来学习条件表达式。


if…else条件表达式

条件表达式使我们可以测试变量。

打个比方,我们可以这样说: 要是变量的值等于10,那就执行什么什么操作。

但要是C语言里面不能做“等于”的判断,那该多可惜啊。我们还要做“小于”,“大于”,“大于等于”,“小于等于”,“不等于”的判断。

不必担心,C语言都为你预备好了。


为了学习if…else语句,我们准备按照下面的顺序来进行:

  1. 预先需要了解的几个符号

  2. if语句

  3. else语句

  4. else…if语句

  5. 多个条件

  6. 一些需要避免的错误


在我们学习写if…else表达式前,须要先了解几个基本符号,这些符号对于实现条件判断是必不可少的。


几个需要了解的符号

下表列出了C语言中需要用心记住的几个符号


符号

含义

==

等于

>

大于

<

小于

>=

大于等于

<=

小于等于

!=

不等于


注意: 判断“等于”需要两个等号(==)!一个很常见的错误是只写一个等号,在C语言中一个等号和两个等号不是一个含义,一个等号是表示赋值,两个等号才是判断是否相等。


单一的if语句


逻辑:

如果 变量的值是这样

执行如下操作


所以单一的if语句是这样写的:

  1. 先写一个if

  2. 接着写一个括号(),在这个括号中写条件

  3. 接着写一个大括号{},在大括号中写在()中条件为真时所要执行的操作


格式如下:

if (/* 条件 */)
{
 // 如果条件为真,所要执行的操作
}


我们把上面注释的地方换成实际的代码,来写一个程序测试一下:

#include <stdio.h>

int main(int argc, char *argv[])
{
   int age = 20;
 
   if (age >= 18)
   {
     printf ("你成年了!\n");
   }
   
   return 0;
}


解释:

  1. int age = 20;  首先定义一个int型的变量,名字是age(英语: 年龄),值为20

  2. if语句的括号()中的条件是 age >=18,意思是“假如age的值大于或等于18”

  3. if语句的大括号{}中的语句是 printf ("你成年了!\n");  就是说当age的值大于或等于18时,显示“你成年了!”这句话


因为程序中变量age的值是20, 大于18,所以条件为真,所以程序运行起来后显示:

你成年了!


如果我们把变量age的值改为12,再次运行程序,什么也没显示,因为12小于18,所以age >= 18 这个条件不为真,不执行大括号里的printf语句


啰嗦一下代码的格式

假如上面的代码我们写成

if (age >= 18) {  printf ("你成年了!"); }

程序也是可以正确运行的,但是非常不推荐这样的代码格式!

如果我们的程序没有空行,没有空格,不缩进,都写在一行里,那将会使代码非常难以阅读。

所以从一开始学习编程就请养成良好的编码习惯,不然以后写一些大型程序,别人根本不知道怎么阅读你的代码,你也会迷失在自己的代码里。

推荐看林锐老师的《高质量C++/C 编程指南》一书,里面有提到编码规范,可以去网上下载PDF。

当然每个程序员的代码风格都不一样,但是我们推荐大家遵从本系列课程中的代码格式,因为是比较通用的编码格式。


else语句

现在你知道怎么写单一的if语句了,那当条件为假时,我们要电脑也执行对应的操作怎么办呢?对了,就轮到else关键字出场了。

但是else语句一定要跟if语句配合才能使用,独立的else语句是不可用的!


【至于关键字,是电脑语言里事先定义的,有特别意义的标识符,有时又叫保留字,是有特别意义的变量。

C语言有不少,比如int,float,char,double,if,else,等,暂时我们不多涉及,可以去了解一下。

之前关于变量的那一课,变量的命名,其实忘记讲了一点: 变量的名字不要跟关键字重名】


所以一个完整的if...else语句的格式是

if (/* 条件 */)
{
 // 条件为真的时候,所要执行的操作

}
else // 如果上面()里的条件为假
{
 // 条件为假的时候,所要执行的操作
}


再用之前测试年龄的例子,来写一下实际的程序

if (age >= 18) // 如果age变量的值大于或等于18
{
 printf ("你成年了!");
}
else  // 如果age变量的值小于18
{
 printf ("你还未成年,可以任性 !");
}


如果age的值大于或等于18,则打印“你成年了!”,如果age的值小于18,则打印“你还未成年,可以任性!”。


else...if语句

上面我们学习了如何用单一的if语句,以及if...else语句

其实除了“假如...”(if语句)和“否则...”(else语句),还有else...if(“又假如”)语句,用于在if语句的条件不为真时对其他的情况的判断,else…if语句放在if语句和else语句之间


逻辑是这样的:

如果变量值为A,执行if对应操作

如果变量值为B,执行else...if对应操作

如果变量值不为A也不为B,执行else对应操作


我们也用一个实例来看一下if,else…if和else合在一起用的情况:

if (age >= 18) // 如果age(英语:年龄)变量的值大于或等于18

{

printf ("你成年了 !");

}

else if ( age > 4 ) // 如果age小于18但是大于4

{

printf ("还好你不是太年幼");

}

else // 如果age小于或等于4

{

printf ("mama, guagua, blablabla..."); // 儿语,听不懂

}


流程是这样的:

  1. 首先判断第一个if语句中的括号里的表达式,如果为真,则执行第一个大括号里的语句

  2. 如果if的条件不为真,则接着判断else…if语句的括号里的表达式,如果为真,则执行对应的大括号里面的语句

  3. 如果if和else…if里的表达式都为假,则无需再判断,直接执行else语句的大括号里的命令


在完整的条件语句块中,else…if和else语句不是必须的,但是必须要有一个if语句

我们可以写任意多的else…if语句,但是if语句和else语句则都是最多有一个。

else后面是没有括号()的,但是if和else…if后面都有括号,也就是都包含判断条件,应该不难理解吧,很合乎逻辑。


多个条件

我们也可以在条件语句的括号()中测试多个条件表达式。例如,你想要测试这个人的年龄是不是介于18岁和25岁之间,就需要两个条件表达式来判断了。


为了达成我们的目的,我们需要用到新的符号:

符号

意义

&&

逻辑与

||

逻辑或

!

逻辑非


本来其实上表中的几个应该也叫做:与,或,非,但为什么叫“逻辑与”,“逻辑或”和“逻辑非”呢?

那是因为之后我们还会学到 &,| 等符号,称为“按位或”和“按位与”。暂时不用知道什么意思,之后会学到。


逻辑与

如果我们要做上面提到过的年龄的判断,则需要用逻辑与:

if (age > 18 && age < 25)


两个 & 号连在一起表示逻辑与,就是说当两边的表达式都为真时,括号中的整个表达式才为真,所以这里只有当age大于18并且小于25的情况下,括号里的表达式才为真。


逻辑或

为了做逻辑或判断,我们则要用到两个 | 符号。逻辑或只要其两边的两个表达式有一个为真,整个表达式就为真。我承认这个符号在键盘上不容易输入。

假设我们现在要写一个程序,目的是判断一个人是不是够资格开设银行账户。众所周知,要开一个银行账户,申请人不能太年幼(我们假定需要大于20岁)或者有很多钱(有钱任性嘛,即使是10岁小孩,也得让他开户)。所以我们的程序是像以下这样:

if (age > 20 || money > 150000)

{

printf("欢迎来到**银行 !");

}

else

{

printf("我还不够资格,悲催啊 !");

}


所以这个测试只有当申请人年龄大于20岁或者拥有超过15万现金时,才让其开户。


逻辑非

我们最后要看的符号是感叹号,表示“取反”,加在表达式之前。如果表达式为真,那么加上感叹号则为假;如果表达式为假,那么加上感叹号则为真。例如:

if (!(age < 18))


上面的表达式表示“假如已经成年”。


当然,逻辑与和逻辑或可以连用,甚至多个一起用,例如:

if ((age > 18 && age < 25) || age < 4)


一些容易犯的错误


== 号

不要忘了之前讲过的 == (两个等号)是用于判断是否相等。例如:

if (age == 18)

{

printf ("你刚成年 !");

}


上例中如果错把 == (两个等号)写成了 = (单个等号),那后果很严重,表达式就变成 age = 18了。单个等号是赋值,所以age变为18,整个表达式的值变为18,就起不到判断的作用了。


一种避免这样错误的写法是“18 == age”,这样如果我们漏写了一个等号,变成“18 = age”,那编译器会报错,因为常量(18)不能做左值。关于左值和右值,可以去搜索网上的资料,简单来说“位于赋值运算符两侧的两个值,左边的就叫左值,右边的就叫右值”。


多余的分号(;)

还有一个经常会犯的错误是:在if的括号或者else...if的括号后面多加了一个分号,如下:

if (age == 18);  // 注意这个分号,本来不应该出现的

{

printf ("你刚好成年");

}


上面的代码实际上相当于

if (age == 18)

{

;

}

{

printf ("你刚好成年");

}


看到没有,分号就相当于if语句的大括号里的执行语句,而 ; 是空语句,什么也不执行。我们原先想让其在age等于18时执行的printf语句却成了一个必定会被执行的语句,不论age的值是不是等于18(大括号是可以把多个语句集合起来的分隔区域,可以拿掉大括号再来理解)。可能有点晕,好好多看几遍代码。


布尔值,条件语句的核心

我们现在更加深入地来看if...else条件语句。事实上,条件表达式(这里指括号里的表达式)在其内部是做了布尔值的判断。


布尔类型英语叫boolean,是只能取“真”或者“假”的一种变量类型。

事实上,在其他的一些编程语言,如Java,C#中,本身定义了boolean类型,只能有两个值,true(真)和false(假)。

但是C语言没有定义boolean类型,怎么办呢?不用担心,C语言把零作为假,非零的一切值都算为真。


我们可以做几个小测试来加深理解:


if (1)

{

printf("真!");

}

else

{

printf("假!");

}


以上代码执行结果是显示:

真!


可以把1换成非零的任意int型整数:5,9,13,-2,448等等,结果都会显示:

真!


if (0)

{

printf("真!");

}

else

{

printf("假!");

}


以上代码执行结果是显示:

假!


所以C语言中只有0是假,其他非零的值都被看作真。这就是C语言的“布尔类型”。


必要的一些解释

事实上,每当你在条件表达式里做判断时,如果表达式是真的,则整个表达式的值是1;如果是假的,则整个表达式的值为0。

例如:

if (age >= 18)

假如age的值为25,是大于等于18的,那么 age >= 18这个表达式的值为真,电脑其实会把它替换为1。

假如age的值为15,是小于18的,那么 age >= 18这个表达式的值为假,电脑其实会把它替换为0。


用变量来测试一下:

#include <stdio.h>


int main(int argc, char *argv[]) {

int age = 25;

int adult = 0;


adult = age >= 18;

printf("adult的值是 : %d\n", adult);


return 0;

}


运行,显示:

adult的值是 : 1


如果age为15,则显示:

adult的值是 : 0


这里的adult其实已经是一个C语言中的“布尔值”了。


switch语句

我们刚学的if...else类型的条件语句是最常用的。但是C语言还给出了if...else语句的一个替代语句:switch语句

因为,有时候,当我们的条件判断很多时,就会感觉冗余。例如下面的代码:

if (age == 2)

{

printf("宝宝,你好 !");

}

else if (age == 6)

{

printf("小朋友,你好 !");

}

else if (age == 12)

{

printf("少年,你好 !");

}

else if (age == 16)

{

printf("青少年,你好 !");

}

else if (age == 18)

{

printf("成年人,你好 !");

}

else if (age == 67)

{

printf("爷爷,你好 !");

}

else

{

printf("对你的年龄我还没有对应的问候方式");

}


之前我们也说过,程序员(IT工作者)是很懒惰的,他们不喜欢做重复,单调的工作。

因此,为了避免重复写一些代码,他们发明了新的switch语句。

以下展示了用switch语句改写的上面那个if...else语句的例子:

switch (age)

{

case 2:

printf("宝宝,你好 !");

break;

case 6:

printf("小朋友,你好 !");

break;

case 12:

printf("少年,你好 !");

break;

case 16:

printf("青少年,你好 !");

break;

case 18:

printf("成年人,你好 !");

break;

case 67:

printf("爷爷,你好 !");

break;

default:

printf("对你的年龄我还没有对应的问候方式 ");

break;

}


相比if...else,switch语句虽然用得较少,但是对于判断情况很多的条件语句,用switch是不是可以少些不少代码呢,而且程序也一目了然,比较清晰。


switch语句的格式:

  1. 首先,写switch这个关键字,接着写一个括号,括号里面是要判断的变量

  2. case加上变量可能的取值,再加一个冒号,再加上对应取值时的操作,再加上一个break;

  3. 要注意:case后面的值只能是整型或字符型的常量或常量表达式

  4. default负责处理除了各个case以外的情况

  5. 多个case就相当于if...else语句里的if和else...if

  6. default相当于if...else语句里的else


想想看,switch语句是不是很像我们去饭店用餐,服务员拿了一个酒水单给你,上面有好多饮料,就像好多个case后面的取值,你点一种饮料,服务生就去给你拿对应的饮料,这个操作就像case的冒号后面的语句。假如你什么都不要,说:还是给我来杯水吧,那服务生就只能给你拿一杯水了,就相当于default。


每个 case 语句的结尾绝对不要忘了加 break,否则将导致多个分支重叠(除非有意使多个分支重叠)。

假如上例中我们少写了一个break;,看看会变成怎样:


int age = 2;


switch (age)

{

case 2:

printf("宝宝,你好 !\n");

// 这里我们没有写 break;

case 6:

printf("小朋友,你好 !\n");

break;

case 12:

printf("少年,你好 !");

break;

case 16:

printf("青少年,你好 !");

break;

case 18:

printf("成年人,你好 !");

break;

case 67:

printf("爷爷,你好 !");

break;

default:

printf("对你的年龄我还没有对应的问候方式 ");

break;

}


上面的代码,当age的值为2的时候,显示的内容是:

宝宝,你好 !

小朋友,你好 !


很奇怪吧,这是因为没有break,程序就不跳出switch的大括号,而继续执行,“穿透”了case 6,虽然age的值是2,不等于6,但是也执行了case 6对应的语句 printf("小朋友,你好 !\n"); 又因为case 6的执行语句后面加了break,所以程序执行完 printf("小朋友,你好 !\n");就跳出了switch语句。当然有时候也有故意不加break,使得多个情况做同一个操作的,例如:

switch (age)

{

case 2:

case 6:

case 12:

case 16:

printf("未成年人,你好 !");

break;

case 18:

printf("成年人,你好 !");

break;

case 67:

printf("爷爷,你好 !");

break;

default:

printf("对你的年龄我还没有对应的问候方式 ");

break;

}


上面的代码,当age的值为2或6或12或16时,都会执行 printf("未成年人,你好 !");

是不是也很妙呢?

break关键字的作用不仅于此(用于跳出switch语句),在下一课《循环语句》中我们会更深入学习break的作用。


还有要注意的是:最后必需使用 default 分支。虽然default不加其实也不会报错,但即使程序真的不需要 default 处理,也应该保留语句,这样做并非画蛇添足,可以避免让人误以为你忘了 default 处理。要把 default 子句只用于检查真正的默认情况。


稍微有点晕?没关系,让我们用一个更完整的例子来加深对switch语句的理解:


假设你到了一个饭店,服务员给你看当日菜单:

=== 菜单 ===


1. 北京烤鸭

2. 锅包肉

3. 地三鲜

4. 梅菜扣肉


您的选择是?


然后根据你的选择做出不同反应。应该怎么写呢?希望不要看答案,先自己写代码试试。


下面给出完整的示例程序:


#include <stdio.h>


int main(int argc, char *argv[])

{

int choiceMenu;


printf("=== 菜单 ===\n\n");

printf("1. 北京烤鸭\n");

printf("2. 锅包肉\n");

printf("3. 地三鲜n");

printf("4. 梅菜扣肉\n");

printf("\n您的选择是 ? ");

scanf("%d", &choiceMenu);


printf("\n");


switch (choiceMenu)

{

 case 1:

    printf("您选了北京烤鸭。这是本店的招牌菜 !");

    break;

 case 2:

    printf("您选了锅包肉。您是东北人吧?知道宋佳吗?她最喜欢吃锅包肉了!");

    break;

 case 3:

    printf("您选了地三鲜。实惠好吃,就是油有点多.");

    break;

 case 4:

    printf("您选了梅菜扣肉。嗯,那个味道很棒!");

    break;

 default:

    printf("您没有选择餐单上的数字,难道您要饿肚子吗 ?");

    break;

}


printf("\n");


return 0;

}


以上代码可以根据用户输入的不同数字做出相应的应答。



三元表达式:精简的条件语句

除了if...else语句和switch语句,还有第三种条件语句,比switch更少用。


我们将其称为 三元表达式。

更确切地说,其实它就是一个if...else的变体,只不过我们把它写在一行里了。


因为实例总比长篇的解释来得更清晰易懂,所以我们用两个例子来说明。这两个例子的功能相同,只不过第一个使用if...else语句,第二个使用三元表达式。

假设我们有一个布尔类型的变量adult,当“成年”时它的值为真(1),当“未成年”时它的值为假(0)。我们还有一个int型变量age,要根据adult的值来改变age变量的值,下面先给出if...else的实现:

if (adult)

age = 18;

else

age = 17;


注意:上例中我把if和else对应的大括号给去掉了,在只有一句执行语句的时候,去掉大括号是可以的,两句或以上就须要加上大括号了。


上例用三元表达式实现则是这样:

age = (adult) ? 18 : 17;


三元表达式使我们可以只用一行代码来根据条件改变变量的值。

问号表示首先判断adult是不是真值,如果是真,则取问号后面的18,将18赋给age;如果为假,取冒号后面的17,将17赋给age。

这里的问号就有点像if的条件判断,冒号就像else。


事实上,三元表达式并不是那么常用,因为它会使代码变得难读,特别是当判断条件多且复杂的时候。



总结

  1. 条件表达式是所有编程语言的基础内容,使电脑能够根据变量的值做出相应决定

  2. 关键字“if”,“else...if”,“else”意味着“假如”,“又假如”,“否则”,我们可以写多个“else...if”

  3. 布尔变量是一种特殊的变量,它只有两种状态: 真(1)和假(0)(实际上,所有非零的整数值都被看作真),我们用整数类型int来储存布尔变量的值,因为C语言其实没有定义布尔变量这种类型,而是用整数值来代表;像Java,C#等语言就定义了布尔类型

  4. switch语句是if...else语句的一个可用替换,在有多个else...if的情况下,建议使用switch代替if...else语句,能使代码更易阅读

  5. 三元表达式(** ? ** : **)是精简的条件语句,但是我们要谨慎使用,因为它会让代码不那么易读



第一部分第七课预告:循环语句


今天的课就到这里,一起加油咯。

下一次我们学习第七课,来认识循环语句吧。




技术分享


程序员联盟 微信公众号*您若觉得本文不错,点击画面右上角《···》按钮“分享到朋友圈或“发送给朋友

*新朋友请关注「程序员联盟」微信搜公众号  ProgrammerLeague

小编的微信号frogoscar

小编的邮箱:    enmingx@gmail.com

微信和邮箱最常用


PS: 有朋友反映看手机端的文章太累,其实是可以用浏览器网页来看的

方法1. 点击画面右上角的《···》按钮,然后选择“复制链接”,再把链接黏贴到你的浏览器里面或用邮件发送给自己,就可以在电脑的浏览器里打开了


技术分享


方法2. 头条网www.toutiao.com,搜索我的自媒体“程序员联盟”,里面有所有文章,也可以直接进这个链接:http://www.toutiao.com/m3750422747/



新朋友如何查看所有文章:

点击“查看公众号”,再点击“查看历史消息”


技术分享


技术分享


【C语言探索之旅】 第一部分第六课:条件表达式