目录
前言:在前面的学习,我们初步了解了C语言的数据类型和变量,对于C语言以后的学习打下了基础;今天,在C语言的数据类型和变量基础之上,继续开始分支和循环语句相关的学习;
由于篇幅原因,将会分为两篇完成记录,希望大家耐心看完。
欢迎大家留下评论,发表自己的学习看法,也请大家多多指教,让我们一起来学习C语言吧。
1. if 语句
1.1 if语句具体实现
if(表达式)
语句;
//当表达式为真时,执行语句,反之不执行;(在c语言中,0为假而非0为真;)
下面通过一个简单的例题体会 for语句的执行:
例1——输入一个整数,判断是否为奇数
int main()
{
int num1 = 0;
scanf("%d", &num1);
if (num1 % 2 == 1)
printf("%d 是奇数", num1);
return 0;
}
//"=="是判断是否相等的操作符
1.2 if...else..组合
接上例——一个数不是奇数就是偶数,为了判断清楚,这里需要 if...else..语句
语法形式:
if (表达式语)
语句1;
else
语句2;
例1续——输入一个整数,判断奇数还是偶数
int main()
{
int num1 = 0;
scanf("%d", &num1);
if (num1 % 2 == 1)
printf("%d 是奇数", num1);
else//判断数值不是奇数,执行else语句
printf("%d 是偶数", num1);
return 0;
}
1.3 分支中包含多条语句
由于在一般情况下,if语句只能控制一条语句
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
printf("成年了\n");
printf("可以谈恋爱了\n");
return 0;
}
这段代码可以验证,无论输入的是什么数都会输出"可以谈恋爱了";
如果想控制多条语句,可以用{}将代码括起来;同理,else也可以用{}括起来;
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)//使用{}控制多条语句,这一块代码叫做——程序块或复合语句
{
printf("成年了\n");
printf("可以谈恋爱了\n");
}
else
{
printf("未成年\n");
printf("不可以谈恋爱\n");
}
return 0;
}
这样修改后就不会出现与实际不符的情况了;
1.4 嵌套if
在if... else...语句中,else可以与另一个if语句连用,构成多重判断。
例题2——要求输入一个整数,判断输入的整数是0,还是正数或者负数
int main()
{
int num1 = 0;
scanf("%d", &num1);
if (num1 == 0)
{
printf("输入的数字是0");
}
else if (num1 > 0) //这里的if相当于嵌套在else语句中,形成了嵌套结构
{
printf("输入的数字是正数\n");
}
else
printf("输入的数字是负数\n");
return 0;
}
上图中第2个 if ——第2个 else 的代码就是嵌套在前面的else子句中的,构成了嵌套的if语句。
同理,if语句可以嵌套在else语句中,也可以嵌套在if语句中;
1.5 利用if...else..语句实现打印不同年龄范围
例题3——
要求:
1.输入一个人的年龄
2.如果年龄<18岁,打印"少年"
3.如果年龄在18岁 至44岁打印"青年"
4.如果年龄在45岁至59岁打印"中老年”
5.如果年龄在60岁至89岁打印"老年”
6.如果90岁及以 上打印"老寿星"
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("少年");
else if (age <= 44)//从18开始
printf("青年");
else if (age <= 59)//从45开始
printf("中老年");
else if (age <= 89)//从60开始
printf("老年");
else
printf("老寿星");
return 0;
}
1.5 悬空else问题
若有多个if 和 else,原则——就近,else和最近的 if 匹配;
例题——
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("hehe\n");
else//else和最近的if匹配,即跟hehe处同一语句中
printf("haha\n");
return 0;
}
程序运行的结果可见神马也没有!!!
这就是悬空else的问题,如果有多个if和else, else 总是跟最近的if匹配。
上面中让else和第一个if 语句对齐,误以为else和第一个if匹配的, 当if语句为假时执行else语句,打印haha;但实际上else是和第二个if 进行匹配的,这样后边的if...else语句是嵌套在第一个 if语句中的,如果第一个if语句为假,嵌套if和else没机会执行,最终啥都不打印。
直观表达,修改——
int main()
{
int a = 0;
int b = 2;
if (a == 1)
{
if (b == 2)
printf("hehe\n");
else
printf("haha\n");
}
return 0;
}
//若想让else和第一个if匹配,就可以用大括号将第二个if语句括起来;
2. 关系操作符
关系操作符用于关系表达式中
-
> <大于/小于运算符
-
>= <=大于等于/小于等于运算符
-
==相等运算符
-
!=不相等运算符
关系表达式通常返回0或1,表示真假;C语言中,0表示假,非零表示真;关系表达式常用于 if 或 while结构。
再次提醒: 相等运算符==与赋值运算符=是两个不一样的运算符;
注意:多个关系运算符不宜连用;
比如例3——
如果表达年龄在44至59之间,不宜用"44 < age < 59"
int main()
{
//创建变量
int age = 0;
//输入
scanf("%d", &age);
//变量条件
if (44 < age < 59)
{
printf("中老年");
}
return 0;
}
可见,无论输入的值是否在限定范围内,都会打印"中老年"; 这就闹笑话了..
因为在这个程序中,先将 44 与存放在 age 中的10比较,显然结果为假并且关系表达式返回0;再将 0 与 59 比较,显然结果为真,打印。
修改——
int main()
{
//创建变量
int age = 0;
//输入
scanf("%d", &age);
if (age > 44 && age < 59)
{
printf("中老年");
}
return 0;
}
//在这里运用了即将要讲到的逻辑与运算符-''&&'',表示并且。
3. 条件操作符
条件操作符也叫三目操作符,需要接受三个操作数的,形式如下:
exp1 ? exp2 : exp3
注意:表达式在这可以当作操作数,因为表达式最终返回一个值,值可以作为操作数;
计算逻辑是:如果exp1为真,exp2 计算,计算的结果是整个表达式的结果;如果 exp1为假,exp3 计算,计算的结果是整个表达式的结果。
例题4——使用效果
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
if (a > 5)//
b = 3;//
else//
b = -3;//
printf("%d'n", b);
return 0;
}
将//标注的几行进行修改:
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
b = a > 5 ? 3 : -3;
//将上面四行内容用条件操作符进行替换
printf("%d\n", b);
return 0;
}
4. 逻辑操作符:&&、||、!
逻辑运算符提供逻辑判断功能,用于构建更复架的表达式主要有下盾三个运算符。
-
!——逻辑取反运算符(改变单个表达式的真假)。
-
&&——逻辑与运算,指的是并且(两侧的表达式都为真,则为真,否则为假)。
-
||——逻辑或运算符,指的是或者(两侧至少有一一个表达式为真,则为真,否则为假) 。
再次提醒: C语言中,非0表示真,0表示假;
4.1 逻辑取反运算符 !
这个运算符理解起来较简单,下面用一个程序来理解一下:
int main()
{
//创建一个变量-flag,以下面程序来理解取反运算符
int flag = 0;
if (!flag)//定义"flag"为假,则!flag为真
{
printf("我真帅! \n");
}
return 0;
}
//打印"我真帅! "
反过来,如果定义flag为真,则!flag为假,结果不打印"我真帅!";
4.2 逻辑与运算符 &&
前面已经提到,&&是并且的意思;&&是双目操作符,形式:
a && b
通过一个简单的例子理解&&的作用:
例题5——三月份到五月份是春天
int main()
{
//创建变量
int month = 0;
//输入月份
printf("月份是:");
scanf("%d", &month);
if (month > 3 && month < 5)//与运算符,当操作符两边都为真时整个表达式才为真;
{
printf("月份处于春天");
}
return 0;
}
//if中的条件意思是:month既要大于3也要小于5;
4.3 逻辑或运算符 ||
或运算符是或者的意思;它也是一个双目操作符,形式:
a || b
通过一个简单的例子理解 || 的作用:
例题6——在一年中,12月或1月或2月处于冬天
int main()
{
//创建变量
int month = 0;
printf("请输入月份:");
//输入月份
scanf("%d", &month);
//用if..else..语句来判断
if (month == 12 || month == 1 || month == 2)// 或运算符,当操作符有一边为真时整个表达式为真;
{
printf("月份处在冬天\n");
}
else
{
printf("月份不在冬天\n");
}
return 0;
}
//if中的条件的意思是:只要month满足三个条件中的一个就输出结果;
4.4 综合练习(经典例题)
例题7——实现输入一个年份,判断是否是闰年
规则:
1.能被4整除,且不能被100整除
2.能被400整除
两种方式实现
int main()
{
//创建变量
int year = 0;
//输入年份
printf("请输入年份:");
scanf("%d", &year);
//根据规则1,运用与运算符 &&; 使用if..else if..结构实现规则1,2
if (year % 4 == 0 && year % 100 != 0)
{
printf("%d是闰年\n", year);
}
else if (year % 400 == 0)
{
printf("%d是闰年\n", year);
}
else
{
printf("%d不是闰年\n",year);
}
return 0;
}
int main()
{
//创建变量
int year = 0;
printf("请输入年份: ");
//输入数值
scanf("%d", &year);
//这里运用或运算符 || 及与运算符 && ;
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
printf("%d 是闰年\n", year);
}
else
{
printf("%d 不是闰年\n", year);
}
return 0;
}
4.5 短路
C语言逻辑运算符有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值;
如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”如前面的代码:
month > 3 && month < 5
表达式中 && 的左操作数是month >= 3,右操作数是month <=5;当左操作数month >= 3的结果是0时,即使不判断month <= 5,整个表达式的结果也是0 (不是春季)。
所以,对于 && 操作符,左操作数的结果是0时,右操作数就不再执行。
对于||来说:
(month == 12 || month == 1 || month == 2)
如果month == 12,则不用再判断month是否等于1或者2,整个表达式的结果也是1 (是冬季)。 所以,|| 操作符的左操作数的结果不为0时, 就无需执行右操作数。
像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进行计算的运算称为短路求值。
5. switch语句
swith语句,另一种分支结构; switch语句可以看作一种特殊的 if... else...结构,用于判断有多个结果的情况。
switch (exp)
{
case value1:
statement
case value2:
statement
default:
statement
}
switch(exp)
的含义
-
exp
可以是:-
变量(如
switch(x)
) -
常量(如
switch(5)
) -
表达式(如
switch(x + y)
)
-
(只能是整数类型(包括char
、int
、short
、long
等)或者枚举类型)
(char 类型本质上是一种整数类型。这是因为在计算机中,字符是以 ASCII 码的形式存储的,而 ASCII 码是整数。)
-
switch
会对exp
进行求值,然后依次与各个case
的值进行比较,找到匹配的case
并执行对应的代码块;否则执行default
分支
value(值)
-
指的是
case
后面的表达式值,用于与switch
括号中的表达式进行比较 -
可以是常量、变量或表达式
-
必须是与
switch
表达式类型兼容的值 -
每个
case
的value必须是唯一的
statement(语句)
-
指的是每个
case
或default
后面跟随的代码块 -
可以是一个语句,也可以是多个语句(不需要用花括号包围)
-
通常以
break
语句结束(除非有意使用贯穿行为)
5.1 if语句和switch语句比较
例8——输入任意一个整数值,计算除3后的余数
-
if语句
int main()
{
//创建变量
int a = 0;
printf("请输入数值: ");
//输入数值
scanf("%d", &a);
//根据题目,可知,数值除3取余=0,1,2 以此写if语句的条件
if (a % 3 == 0)
{
printf("数值整除,余数0\n");
}
else if (a % 3 == 1)
{
printf("余数为1\n");
}
else
{
printf("余数为2");
}
return 0;
}
-
switch语句
int main()
{
//创建变量
int a = 0;
printf("请输入数值: ");
//输入
scanf("%d", &a);
switch (a % 3)
{
case 0:
printf("数值整除,余数为0\n");
break;
case 1:
printf("余数为1\n");
break;
case 2:
printf("余数为2\n");
break;
}
return 0;
}
在上面的的代码中,需要注意:
-
case
和后面的value
(值)之间必须有空格 -
每一个
case(
情况)语句执行完后,要加上break
,才能跳出switch语句
5.2 switch语句中的break
在前面可知,break
的作用是跳出switch语句,如果在上面的代码中没有break
,则会出现:
可知:当输入3后,取余为0,与case 0
匹配;但因为没有break
,程序将会继续执行直至遇到break
或程序结束;
5.2.1 case穿透
在 switch
语句中,如果没有break
,程序会继续执行后续的 case
语句,即使它们的值与 switch
的表达式不匹配。这种现象称为 "case 穿透"(fall-through)。
当然,break
的有无还需要根据具体代码的要求;
5.3 switch语句中的default
在使用 switch语句 的时候,我们可能遇到 switch 后的表达式中的值无法匹配代码中的 case语句 ,这时候就得在 switch语句 中加入 default子句。
int main()
{
//创建变量
int day = 0;
printf("请输入数值:");
//输入
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;
default:
printf("输入数值不在星期定义范围内!\n 请检查输入\n");
}
return 0;
}
在 switch语句 中 case子句 和 default子句 并没有明确的顺序要求;只要你的顺序是满足实际需求的就可以。
通常是把default子句放在最后处理的。