目录(上)
操作符
分支语句
目录(下)
循环语句
练习
一、操作符
操作符可以粗分为关系操作符,条件操作符以及逻辑操作符。从名字上看,我们不难看出来三者的区别,分别运用关系运算,条件运算和逻辑运算,具体三者区别如何,我们继续往下看。
(一)关系操作符
关系操作符顾名思义就是表示几个元素之间关系的操作符,可以类似的理解为数学中的关系符号。比如大于(>)、小于(>)、大于等于(>=)、小于等于(=<)、相等(==)、不相等(!=),比较常见的就是这些。那既然说可以类似的理解为数学运算,那想必二者之间是有差距的,那我们继续来看看差距在哪里。
在数学中,大于等于和小于等于分别表示为“≥”“≤”,而在C语言中,这样的符号编译器无法识别。同样的,不等于在数学中我们表示为“≠”,而在C语言中只能用“!=”表示。还有一个明显的差距就是相等运算符是“==”(“=”是给变量赋值的)。
(二)条件操作符
条件操作符又叫“三目操作符”,需要接受三个操作数,像下面的形式:
exp1?exp2:exp3
条件操作符的计算逻辑是:如果exp1为真,exp2计算,计算的结果是整个表达式的结果;如果exp1为假,exp3计算,计算的结果是整个表达式的结果。
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int m = a>b ? a : b;
printf("%d\n", m);
return 0
}
我们以这段代码中的条件操作符为例,如果a>b,那么m=a,如果a<b(也就是a>b为假),那么m=b。
(三)逻辑操作符
在我们的认识中,逻辑运算无外乎就四个,与、或、非、异或。在这里异或我们不做讨论,我们只来探讨一下前三个。
!:逻辑取反运算符,也就是“非运算”,我们知道,在逻辑关系中,0为假,非0为真。那么“!0”就是真,同样的“!a”(a为任意不等于0的数)都为假。
&&:与运算符,就是并且的意思。两侧的表达式都要是真的(非0),这个表达式才为真,否则就是假。可以简单记忆为“一假则假”。
||:或运算,就是或者的意思,与“&&”不同的是,它只需要两侧表达式至少有一个是真的,这整个表达式就是真的,可以简单记忆为“一真泽真”。
讲完了操作符的相关知识,我们下面就可以继续讲解分支结构和循环结构了
二、分支结构
分支结构的语句类型比较简单的就是if语句和switch语句,if语句细分可以分为if判断语句和if-else语句。
(一)if语句
“if”可以翻译为如果,语法形式如下:
if (表达式)
语句
表达式如果判断为真(非0),那么就执行语句,如果判断为假(0),就不执行语句
我们可以举个例子,比如:判断一个人是不是成年人,我们可以这样写:
include <stdio.h>
int main()
{
int age = 0;
scanf("%d",&age);
if(age<18)
printf("您还没有成年\n");
return 0;
}
这是没有成年的,那如果那个人成年了呢,那这个代码就走不起来了,这时候我们就需要来判断一下,这个人到底成没成年,成年了我就输出成年了,没成年我就输出没有成年。这时候我们就需要表达另一个条件的语句----else。
include <stdio.h>
int main()
{
int age = 0;
scanf("%d",&age);
if(age<18)
printf("您还没有成年\n");
else
printf("您已经成年了\n");
return 0;
}
else语句就是除了if表达式中的其余条件都可以执行语句。
那么问题又来了,如果我想精确的判断一个人所处的人生时期,怎么办呢?我们先来看一下这种方法。
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age<18)
{
printf("少年\n");
}
else
{
if(age<=44)
{
printf("⻘年\n");
}
else
{
if(age<=59)
{
printf("中⽼年\n");
}
else
{
if(age<=90)
printf("⽼年\n");
else
printf("⽼寿星\n");
}
}
}
return 0;
}
我们可以看到过程非常的复杂繁琐,多次使用if-else语句还会增加阅读的困难,那有没有一种方法能让我同时表示多种条件,满足那个条件就执行哪个呢?那么这个时候,else if语句出现了。
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age<18)
printf("少年\n");
else if(age<=44)
printf("⻘年\n");
else if(age<=59)
printf("中⽼年\n");
else if(age<=90)
printf("⽼年\n");
else
printf("⽼寿星\n");
return 0;
}
这时候,我们就可以同时写出多条表达式。不难发现,方法一只有一个大的if语句,其他都是在else中嵌套。而第二种方法中,只有一个大的else语句,其他的可以近似理解为在if中嵌套。
其次,还有一个比较重要的问题就是悬空else问题,例如:
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
代码我们可以发现,输出结果并不是我们想象中的“haha”,而是无输出,为什么呢。注意,else无论和谁对齐,它都和最接近的一个if匹配,也就是说a=1那么大的if没进去,自然就没有输出结果了。
(二)switch语句
在学完了if语句后,我们先来看一个小题目
输入任何一个整数值,计算除3后的余数,这并不难,我们可以这样:
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if(n%3 == 0)
printf("整除,余数为0\n");
else if(n%3 == 1)
printf("余数是1\n");
else
printf("余数是2\n");
return 0;
}
那我们引入一个新的知识点,switch语句,语法结构是这样的:
switch (表达式)
{
case a:
printf(语句);
break;
case b:
printf(语句);
break;
case c:
printf(语句);
break;
case d:
printf(语句);
break;
}
//注意:a,b,c,d都是整型变量
大家注意到,这段代码中每一个语句后面都跟着一个break,那这个break的作用是什么呢?我们继续探讨。
switch是一个分支结构,如果去掉了break会发生什么呢?我们可以先试一下:
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch(n%3)
{
case 0:
printf("整除,余数为0\n");
case 1:
printf("余数是1\n");
case 2:
printf("余数是2\n");
}
return 0;
}
这段代码的输出结果是这样:
为什么会出现这种情况呢?原来,在switch语句中,如果没有break跳出循环。代码就会继续执行,有可能会执行其他语句,直到遇到break才会结束。当然,也不是所有的case后面都要加break,如果只最后一个case,就可以不加,因为这个执行完后会跳出结构。
我们来练习一下,题目要求是按照输入的星期输出是工作日还是休息日,如下:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch(day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("⼯作⽇\n");
break;
case 6:
case 7:
printf("休息⽇\n");
break;
}
return 0;
}
大家可以看到,这个代码非常的繁琐,那有没有一种情况和if语句一样,可以把所有剩余条件都放在一个里面呢,这个时候,default出现了。default结构如下:
switch (expression) {
case value1: statement
case value2: statement
default: statement
}
那么这段代码我们可以改写为:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch(day)
{
case 6:
case 7:
printf("休息⽇\n");
break;
default:
printf("⼯作⽇\n");
}
return 0;
}
这样是不是就简洁多了?当然,这段代码的输入排除了输入错误的情况(例如8、9之类的)。至于default能放在哪里,我们没有具体的要求,default可以放在分支中的任意位置,但是我们一般放在最后一个(不仅是为了美观,还是为了清晰的逻辑和阅读体验)
好了,分支与循环(上)就先说到这里,主要说了分支结构,我们稍后再讲循环结构。下期再见!