分支结构和操作符
前言
C语言是结构化的程序设计语言,这里的结构化指的是顺序结构,选择结构,循环结构。
选择结构又叫分支结构,我们可以使用if、switch实现。
实现循环结构,使用while、for、do…while.
if语句的各种运用方式
if语句
表达式为真,则语句执行。表达式为假,则语句不执行。
在C语言中,0表示假,非0表示真
举个例子:输入一个整数判断是否为奇数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int n = 0;
//输入
scanf("%d", &n);
//判断
if (1 == n % 2)
{
printf("奇数\n");
}
return 0;
}
else语句
如果一个数不是奇数,那就是偶数了,那我们该怎么表示?我们可以用if…else表示。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int n = 0;
//输入
scanf("%d", &n);
//判断
if (1 == n % 2)
{
printf("奇数\n");
}
else
printf("偶数\n");
return 0;
}
分支中包含多条语句
默认在if 和else语句中默认都只控制一条语句。如果if要同时控制多条语句,那就要使用{}将代码括起来,else也一样。{}这个叫程序块,或者复合语句,用来控制多条语句
#include <stdio.h>
int main()
{
int age;
scanf("%d", &age);
if (age >= 18)
{
printf("成年\n");
printf("可以谈恋爱了\n"); //程序块
}
else
{
printf("未成年\n");
printf("不能沉迷游戏\n");
}
return 0;
}
嵌套if
第一种:在if…else语句中,else可以与另一个if语句连用。
举个例子:要求输入一个整数,判断输入的整数是0,还是正数或者负数。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
//要求输入一个整数,判断输入的整数是0,还是正数或者负数
int n = 0;
scanf("%d", &n);
if (0 == n)
printf("输入的数字是0\n");
else
if (n > 0)
printf("输入的数字是正数\n");
else
printf("输入的数字是负数\n");
return 0;
}
大家是不是有疑惑,为什么else不加程序块?大家认为else底下的if…else语句属于一条语句还是俩条语句。其实是属于一条语句的,因为它只选择一条执行,所以去掉括号也能执行。
当然了,它还有另一种写法,大家应该会很熟悉。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
//要求输入一个整数,判断输入的整数是0,还是正数或者负数
int n = 0;
scanf("%d", &n);
if (0 == n)
printf("输入的数字是0\n");
else if (n > 0) //这只能算一条语句,因为它只能选择一个语句执行,所有可以不加程序块
printf("输入的数字是正数\n");
else
printf("输入的数字是负数\n");
return 0;
}
第二种:if…else语句中,if还可以和另一个if连用,属于嵌套在if语句中的,构成了第二种的嵌套的if语句。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//要求输入一个整数,如果是正数,再判断是奇数还是偶数,并输出,如果不是正数则输出:非正数;
int main()
{
int n = 0;
scanf("%d", &n);
if (n > 0)
{
if (0 == n % 2)
printf("偶数\n");
else
printf("奇数\n");
}
else
printf("非正数\n");
return 0;
}
使用嵌套if语句,就可以完成更多复杂逻辑的判断。
悬空的else问题
如果有多个if和else,大家记住这样一条规则,else总是跟最接近的if匹配。
下面来看代码:
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (1 == a)
if (2 == b)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
程序运行的结果是上面?
可能很多人认为,上来判断a是0,不等于1,那就执行else,打印haha。
但是当你运行代码,输出的结果是:啥都不输出。
这个就是悬空else问题,如果有多个if和else,大家记住这样一条规则,else总是跟最接近的if匹配。
如果代码改成这样,就容易理解了。
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (1 == a)
{
if (2 == b)
printf("hehe\n");
else
printf("haha\n");
}
return 0;
}
只要适当加上大括号,代码的逻辑就会更加的清晰,所以大家以后再写代码的时候要注意括号的使用,让代码的可读性更高。
switch语句
除了if 语句之外,C语言还提供了switch语句来实现分支结构。
switch后的expression必须是整型表达式.(字符类型底层也是整数类型)
case后面的值必须是整型常量表达式。
if语句和switch语句的对比。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if (0 == n % 3)
{
printf("余数为0\n");
}
else if (1 == n % 3)
{
printf("余数为1\n");
}
else
printf("余数为2\n");
return 0;
}
switch语句
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch (n % 3)
{
case 0:
printf("余数是0\n");
break;
case 1:
printf("余数是1\n");
break;
case 2:
printf("余数是2\n");
break;
default:
break;
}
关于switch中,我们要注意的点有:
1.case和后面的数字之间必须有空格。
2.每一个case语句中的代码执行完成后,需要加上break,才能跳出switch语句。
switch 语句的时候,我们经常可能遇到⼀种情况,⽐如代码中switch后的表达式中的值⽆法匹配代码中case语句的时候,这时候要不就不做处理,要不就得在switch 语句中加⼊default ⼦句
switch语句中的case和default的顺序问题
在switch语句中case⼦句和default⼦句有要求顺序吗?default只能放在最后吗?其实,在switch语句中case语句和default语句是没有顺序要求的,只要你的顺序是满⾜实际需求的就可以。不过我们通常是把default⼦句放在最后处理的。
关系操作符
C语言中用于比较的表达式,称为关系表达式,里面使用的运算符就叫关系运算符。主要有下面6个。
- >大于运算符
- <小于运算符
- >=大于等于运算符
- <=小于等于运算符
- ==相等运算符
- !=不相等运算符
关系表达式通常返回0或1,表示真假
举个例子:
比如:20 > 12 就返回 1,而12 > 20 就返回 0 .
另一个需要避免的错误是:多个关系运算符不宜连用。
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = 2;
if (a < b < c) //关系操作符是从左到右计算的
printf("hehe\n");
return 0;
}
因为关系运算符是从左到右计算的,所以先看a < b,它符合,所以返回 1,在把 1 和 c比较 ,符合在返回 1 ;非0 为真,执行下面语句。所以多个关系运算符不宜连用
条件操作符
条件操作符也叫三⽬操作符,需要接受三个操作数的,形式如下:
条件操作符的计算逻辑是:如果exp1 为真,exp2 计算,计算的结果是整个表达式的结果;如果exp1 为假,exp3 计算,计算的结果是整个表达式的结果。
条件操作符又是简单的if …else 语句
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
//if (a > 5)
// b = 3;
//else
// b = -3;
//三目操作符,又是简单的if else 语句
b = (a > 5 ? 3 : -3);
printf("b = %d\n", b);
return 0;
}
逻辑操作符
- !:逻辑取反运算符(改变单个表达式的真假)
- &&:逻辑与运算符,就是并且的意思
- ||:逻辑与运算符,就是或的意思
逻辑取反操作符
#include <stdio.h>
int main()
{
int flag = 0;
scanf("%d", &flag);
//flag为假时,打印hehe
if (!flag)
printf("hehe\n");
return 0;
}
当flag为假时,想要打印hehe,就需要对他逻辑取反。
逻辑与运算符
这是只有俩边表达式都为真的时候,整个表达式才为真。只要有一个是假,整个表达式为假。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int month = 0;
scanf("%d", &month);
if (3 <= month && month <= 5)
printf("春天\n");
return 0;
}
这⾥表达的意思就是month既要⼤于等于3,⼜要⼩于等于5,必须同时满⾜。
逻辑或运算符
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int month = 0;
scanf("%d", &month);
if (month == 12 || month == 1 || month == 2)
printf("冬天\n");
return 0;
}
上面代码,只要有一个为真,整个表达式就为真,两边的表达式都为假的时候,才为假。
小练习
输入一个年份year,判断year是否为闰年
闰年判断的规则:
- 能被4整除并且不能被100整除是闰年
- 能被400整除是闰年
#include <stdio.h>
//代码
int main()
{
int year = 0;
scanf("%d", &year);
if(year%4==0 && year%100!=0)
printf(”是闰年\n");
else if(year%400==0)
printf("是闰年\n");
return 0;
}
//代码2
int main()
{
int year = 0;
scanf("%d", &year);
if((year%4==0 && year%100!=0) || (year%400==0))
printf("是闰年\n");
return 0;
}
短路
C语⾔逻辑运算符还有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。
如果左边的表达式满⾜逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”
对于&&操作符来说,左边操作数的结果是0的时候,右边操作数就不再执⾏。
所以,|| 操作符的左操作数的结果不为0时,就⽆需执⾏右操作数。
像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对操作数进⾏计算的运算称为短路求值
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
//当a=0时,因为是逻辑与操作符,右边操作数不执行,整个为假,所以i的值为0,因为用操作符得到的值只有0和1
//i = a++ && ++b && d++; //a=1 b=2 c=3 d=4
//逻辑或操作符,a为0时,执行右边一个的操作符,为真的时候,最后一个不执行
i = a++||++b||d++; // a = 1 b=3 c=3 d=4
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}
逻辑或操作符,a为0时,执行右边一个的操作符,为真的时候,最后一个不执行,因为逻辑或,有一个为真,整个为真,所以i的值为1,因为用操作符得到的值只有0和1