做者 谢恩铭,公众号「程序员联盟」。 转载请注明出处。 原文:www.jianshu.com/p/49fdba563…git
《C语言探索之旅》全系列程序员
上一课是 C语言探索之旅 | 第一部分第七课:运算那点事 。github
在以前的课程中,咱们已经知道世界上有不少编程语言,有些相互之间很相似,其中很多都受了 C语言的启发。编程
事实上,C语言是很早以前被发明的(1972 年左右),因此它也成了不少近代编程语言的参考模板。bash
咱们说编程语言类似,是说他们都汲取了它们的前辈的编程基础。编程语言
说到编程基础,那就有不少了。其中,咱们已经学过的有:变量,运算。这一课咱们来学习条件表达式。学习
简单来讲,条件表达式使咱们能够测试变量。测试
打个比方,咱们能够这样说: “假如变量的值等于 7,就执行这样那样的操做。”ui
若是 C语言里面不能作“等于”的判断,那该多惋惜啊。咱们还要作“小于”,“大于”,“大于等于”,“小于等于”,“不等于”的判断。编码
没必要担忧,C语言都为你预备好了。
为了学习 if…else 语句,咱们准备按照下面的顺序来进行:
在咱们学习写 if…else 表达式前,需要先了解几个基本符号,这些符号对于实现条件判断是必不可少的。
下表列出了 C语言中须要用心记住的几个符号:
符号 | 含义 |
---|---|
== | 等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
!= | 不等于 |
判断“等于”须要两个等号(
==
)! 一个很常见的错误是只写一个等号,在 C语言中一个等号和两个等号具备不一样的含义。一个等号表示赋值,两个等号才是判断是否相等。
if 表示“若是,假如”。
逻辑是这样的:
若是 变量的值是这样 则 执行以下操做
因此单一的 if 语句是这样写的:
格式以下:
if (/* 条件 */)
{
// 若是条件为真,所要执行的操做
}
复制代码
咱们把上面注释的地方换成实际的代码,写一个程序测试一下:
#include <stdio.h>
int main(int argc, char *argv[])
{
int age = 20;
if (age >= 18)
{
printf("你成年了!\n");
}
return 0;
}
复制代码
解释:
int age = 20;
复制代码
首先定义一个 int 型的变量,名字是 age(表示“年龄”),值为 20。
if 语句的括号 () 中的条件是 age >=18
,意思是“假如 age 的值大于或等于 18”。
if 语句的大括号 {} 中的语句是
printf("你成年了!\n");
复制代码
就是说当 age 的值大于或等于 18 时,显示“你成年了!”这句话。
由于程序中变量 age 的值是 20, 大于 18,因此条件为真,因此程序运行起来后显示:
你成年了!
复制代码
若是咱们把变量 age 的值改成 12,再次运行程序,什么也没显示,由于 12 小于 18,因此 age >= 18
这个条件不为真,不执行大括号里的 printf 语句。
假如咱们将上面的代码写成这样:
if(age>=18){printf("你成年了!");}
复制代码
程序也是能够正确运行的,可是很是不推荐这样的代码格式!
若是咱们的程序没有空行,没有空格,不缩进,都写在一行里,那将会使代码很是难以阅读。
因此从一开始学习编程就请养成良好的编码习惯,否则之后写一些大型程序,别人根本不知道怎么阅读你的代码,你也会迷失在本身的代码里。
推荐看林锐老师的《高质量C++/C编程指南》一书,里面提到了编码规范。
固然,每一个程序员的代码风格都不同,可是咱们推荐你们听从本系列课程中的代码格式或者一些著名公司的代码格式(例如 Google,阿里,等等),由于是比较通用的编码格式。
如今你知道怎么写单一的 if 语句了。那当条件为假时,咱们想要电脑也执行对应的操做怎么办呢?对了,此时就轮到 else 关键字出场了。
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,则打印“你还未成年,能够任性!”。
上面咱们学习了如何用单一的 if 语句,以及 if...else 语句
其实除了“假如...”(if 语句)和“不然...”(else 语句),还有else...if(“又假如”)语句,用于在 if 语句的条件不为真时对其余的状况的判断,else…if 语句放在 if 语句和 else 语句之间。
逻辑是这样的:
若是变量值为 A,则执行 if 对应操做; 若是变量值不为 A,而为 B,则执行 else...if 对应操做; 若是变量值不为 A 也不为 B,则执行 else 对应操做。
咱们也用一个实例来看一下 if,else…if 和 else 合在一块儿用的状况:
if (age >= 18) // 若是 age 变量的值大于或等于 18
{
printf("你成年了 !");
}
else if (age > 2) // 若是 age 小于 18 可是大于 2
{
printf("还好你不是太年幼。");
}
else // 若是 age 小于或等于 2
{
printf("mama, guagua, blablabla..."); // 儿语,听不懂
}
复制代码
流程是这样的:
首先判断第一个 if 语句中的括号里的表达式,若是为真,则执行第一个大括号里的语句。
若是 if 的条件不为真,则接着判断 else…if 语句的括号里的表达式,若是为真,则执行对应的大括号里面的语句。
若是 if 和 else…if 里的表达式都为假,则无需再判断,直接执行 else 语句的大括号里的命令。
在完整的条件语句块中,else…if 和 else 语句不是必须的,可是必需要有一个 if 语句。
咱们能够写任意多的 else…if 语句,可是 if 语句和 else 语句则都是最多有一个。
else 后面是没有括号 () 的,可是 if 和 else…if 后面都有括号,也就是都包含判断条件,应该不难理解吧,很合乎逻辑。
咱们也能够在条件语句的括号 () 中测试多个条件表达式。
例如,你想要测试这我的的年龄是否是介于 18 岁和 25 岁之间,就须要两个条件表达式来判断了。
为了达成咱们的目的,咱们须要用到新的符号:
符号 | 含义 |
---|---|
&& | 逻辑与 |
II | 逻辑或 |
! | 逻辑非 |
原本其实上表中的几个应该也叫作:与,或,非。但为何叫“逻辑与”,“逻辑或”和“逻辑非”呢?
那是由于以后咱们还会学到 &
,|
等符号,称为“按位或”和“按位与”。暂时不用知道什么意思,以后会学到。
为了作逻辑与判断,咱们则要用到两个 &
符号。这个符号在美式键盘上须要按下 Shift + 数字键 7。
若是咱们要作上面提到过的年龄的判断,则须要用逻辑与:
if (age > 18 && age < 25)
复制代码
两个 & 号连在一块儿表示逻辑与,就是说当两边的表达式都为真时,括号中的整个表达式才为真,因此这里只有当 age 大于 18 而且小于 25 的状况下,括号里的表达式才为真。
为了作逻辑或判断,咱们则要用到两个 |
符号。这个符号在美式键盘上须要按下 Shift + \
键。
逻辑或只要其两边的两个表达式有一个为真,整个表达式就为真。
假设咱们如今要写一个程序,目的是判断一我的是否是够资格开设银行帐户。
众所周知,要开一个银行帐户,申请人不能太年幼(咱们假定须要大于 20 岁)或者有不少钱(“有钱任性”嘛,即便是 10 岁小孩,也得让他开户。开个玩笑~)。
因此咱们的程序以下:
if (age > 20 || money > 150000)
{
printf("欢迎来到**银行 !");
}
else
{
printf("我还不够资格,悲催啊 !");
}
复制代码
因此这个测试只要申请人年龄大于 20 岁或者拥有超过 15 万现金时,就可让其开户。
咱们最后要看的符号是感叹号 !
,表示“取反”,加在表达式以前。这个符号在美式键盘上须要按下 Shift + 数字键 1。
若是表达式为真,那么加上感叹号则为假;若是表达式为假,那么加上感叹号则为真。就是跟你“唱反调”。
例如:
if (!(age < 18))
复制代码
上面的表达式表示“假如已经成年”(不小于 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++,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语言的“布尔类型”,由于 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 = age >= 18;
,其实等价于 adult = (age >= 18);
。由于 >=
这个符号的优先级比 =
符号要高。运算符的优先级,不须要死记硬背,若是实在记不住,就加上括号 () 吧。
这里的 adult 其实已是一个 C语言中的“布尔值”了。
咱们刚学的 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 表示“转换,替换”。
如下展现了用 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;
}
复制代码
switch 语句虽然没有 if...else 语句那么经常使用,可是对于判断状况不少的条件语句,用 switch 能够少写很多代码呢,并且程序也一目了然,比较清晰。
首先,写 switch
这个关键字,接着写一个括号,括号里面是要判断的变量。
case
加上变量可能的取值,再加一个冒号(:
),再加上对应取值时的操做,再加上一个 break;
。
要注意:case 后面的值只能是整型或字符型的常量或常量表达式。
default
负责处理除了各个 case 之外的状况。
多个 case 就至关于 if...else 语句里的 if 和 else...if 。
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 语句的理解:
假设你到了一个饭店,服务员给你看当日菜单:
=== 菜单 ===
- 北京烤鸭
- 锅包肉
- 地三鲜
- 梅菜扣肉
您的选择是?
而后根据你的选择作出不一样反应。应该怎么写呢?但愿不要看答案,先本身写代码试试。
下面给出完整的示例程序:
#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。
事实上,三元表达式并非那么经常使用,由于它会使代码变得难读,特别是当判断条件多且复杂的时候。
条件表达式是全部编程语言的基础内容,使电脑可以根据变量的值作出相应决定。
关键字 if,else...if,else 意味着“假如”,“又假如”,“不然”,咱们能够写多个 else...if 。
布尔变量是一种特殊的变量,它只有两种状态:真(1)和假(0)(实际上,全部非零的整数值都被看做真),咱们用整数类型 int 来储存布尔变量的值,由于 C语言其实没有定义布尔变量这种类型,而是用整数值来表明。Java、C++、C# 等语言就定义了布尔类型。
switch 语句是 if...else 语句的一个可用替换。在有多个 else...if 的状况下,可使用 switch 代替 if...else 语句,能使代码更易阅读。
三元表达式(xx ? xx : xx)是精简的条件语句,可是咱们要谨慎使用,由于它会让代码不那么易读。
今天的课就到这里,一块儿加油吧!
我是 谢恩铭,公众号「程序员联盟」运营者,慕课网精英讲师 Oscar 老师,终生学习者。 热爱生活,喜欢游泳,略懂烹饪。 人生格言:「向着标杆直跑」