初识C语言④:分支和循环
目录
1. if语句
2. 关系操作符
3. 条件操作符
4. 逻辑操作符:&&、||、!
5. switch语句
6. while循环
7. for循环
8. do-while循环
9. break和continue语句
10. 循环的嵌套
前面层提到,生活中任何事情的解决方法都可以拆分为三种结构:顺序结构、选择结构、循环结构。
而C语言作为一种结构化的程序设计语言,也为我们提供了这三种结构。我们可以使用if、switch实现分支机构,使用for、while、do-while实现循环结构。下面我们就一起深入的了解这几种结构对应语句的使用方法。
一、if语句
1.1 if语句的语法形式
if语句的语法形式如下:
if (表达式)
语句;
表达式成立(为真),则语句执行,表达式不成立(为假),则语句不执行。
在C语言中,0为假,非0表示真,也就是表达式的结果如果是0,则语句不执行,表达式的结果如果不
是0,则语句执行。
代码演示:
//输入一个整数,判断是否为奇数
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num % 2 == 1)
printf("%d 是奇数\n", num);
return 0;
}
代码结果:
1.2 else
如果一个数不是奇数,那就是偶数了,如果任意一个整数,我们要清楚的判断是奇数还是偶数怎么表
示呢?
这里,我们就要用到if…else…语句了。
if…else…语句语法如下:
if (表达式)
语句1;
else
语句2;
代码演示:
//输入一个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印偶数。
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num % 2 == 1)
printf("%d 是奇数\n", num);
else
printf("%d 是偶数\n", num);
return 0;
}
代码结果:
1.3 分支中包含多条语句
在if和else语句中,默认都只能控制一条语句的执行。
代码演示:
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age >= 18)
printf("成年了\n");
printf("可以谈恋爱了\n");
return 0;
}
上面的代码,你会发现输入的值不管是>=18 还是<18,“可以谈恋爱了” 都会打印在屏幕上。
代码结果:
这是因为if 语句只能控制一条语句,就是printf(“成年了\n”); ,if语句为真,则打印成年了,if语句为假,则不打印。
对于printf(“可以谈恋爱了\n”);,是独立存在的,不管if语句的条件的真假,都会被执行。所以如果我们要if语句同时控制2条语句,那就要使用 {} 将代码括起来,变成一个代码块,else语句同理。
代码演示:
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age >= 18) //if 后使用{} 控制多条语句-这个块也叫:程序块,或者复合语句
{
printf("成年了\n");
printf("可以谈恋爱了\n");
}
else //else 后使用{}控制多条语句-这个块也叫:程序块,或者复合语句
{
printf("未成年\n");
printf("不可以恋爱\n");
}
return 0;
}
1.4 嵌套if
在if else 语句中, else 可以与另一个if 语句连用,构成多重判断。
代码演示:
//要求输入一个整数,判断输入的整数是0,还是正数或者负数。
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num == 0)
printf("输入的数字是0\n");
else if(num > 0) //这里的if 相当于嵌套在else语句中,形成了嵌套结构
printf("输入的数字是正数\n");
else
printf("输入的数字是负数\n");
return 0;
}
1.5 else悬空的问题
如果有多个if 和else ,可以记住这样一条规则, else 总是跟最接近的if 匹配。
代码演示:
#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 和else ,可以记住这样一条规则, else 总是跟最接近的if 匹配。
造成这类悬空问题的本质实际上是**没有一个好的代码风格造成的,**所以我们在最开始学习的时候,一定要养成一个良好的代码风格。
这里,推荐大家可以去看看 《高质量的C-C++编程》 这本书,相信会对于初学者养成一个好的编程习惯有一定的帮助。
二、关系操作符
C 语言用于比较的表达式,称为 “关系表达式”(relational expression),里面使用的运算符就称为“关系运算符”(relational operator),主要有下面6个。
- 大于运算符:>
- 小于运算符:<
- 大于等于运算符:>=
- 小于等于运算符:<=
- 相等运算符:==
- 不相等运算符:!=
实例如下:
a == b;
a != b;
a < b;
a > b;
a <= b;
a >= b;
//关系表达式通常返回0 或1 ,表示真假。
关系表达式常用于if 或while 结构
if (x == 3)
{
printf("x is 3.\n");
}
Tip:
- 相等运算符== 与赋值运算符= 是两个不一样的运算符,不要混淆。
- 过个关系运算符不宜连用。
三、条件操作符
条件操作符也叫三目操作符,需要接受三个操作数的。
形式如下:
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;
}
四、逻辑操作符:&&、||、!
逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。
- ! :逻辑取反运算符(改变单个表达式的真假)。
- && :逻辑与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
- || :逻辑或运算符,就是或者的意思(两侧至少有一个表达式为真,则为真,否则为假)。
4.1 逻辑取反运算符 !
比如,我们有一个变量叫flag ,如果flag为假,要做一个什么事情,就可以这样写代码:
#include <stdio.h>
int main()
{
int flag = 0;
if(!flag)
{
printf("do something\n");
}
return 0;
}
4.2 逻辑与运算符
&& 就是与运算符,也是并且的意思, && 是一个双目操作符,使用的方式是a&&b , && 两边的表达式都是真的时候,整个表达式才为真,只要有一个是假,则整个表达式为假。
代码演示:
//判断3月份到5月份是春天
#include <stdio.h>
int main()
{
int month = 0;
scanf("%d", &month);
if(month >= 3 && month <= 5)
{
printf("春季\n");
}
return 0;
}
这里表达的意思就是month既要大于等于3,又要小于等于5,必须同时满足。
4.3 逻辑或运算符
|| 就是或运算符,也就是或者的意思, || 也是一个双目操作符,使用的方式是a || b , ||两边的表达式只要有一个是真,整个表达式就是真,两边的表达式都为假的时候,才为假。
代码演示:
#include <stdio.h>
int main()
{
int month = 0;
scanf("%d", &month);
if(month == 12 || month==1 || month == 2)
{
printf("冬季\n");
}
return 0;
}
五、switch语句
除了if 语句外,C语言还提供了switch 语句来实现分支结构。
switch 语句是一种特殊形式的 if…else 结构,用于判断条件有多个结果的情况。它把多重的else if 改成更易用、可读性更好的形式。
switch语句语法形式如下:
switch (expression)
{
case value1: statement;
case value2: statement;
default: statement;
}
上面代码中,根据表达式expression 不同的值,执行相应的case 分支。如果找不到对应的值,就执行 default 分支。
Tip:
- switch 后的expression 必须是整型表达式。
- case 后的值,必须是整形常量表达式。
5.1 if语句和switch语句的对比
输入任意一个整数值,计算除3之后的余数
代码演示:
//使用if语句
#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语句
#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;
}
return 0;
}
上述代码我们需要注意的是:
- case 和后边的数字之间必须有空格
- 每一个case 语句中的代码执行完成后,需要加上break ,才能跳出这个switch语句。
5.2 witch语句中的default
在使用 switch 语句的时候,我们经常可能遇到一种情况,比如switch 后的表达式中的值无法匹配代码中的case 语句的时候,这时候要不就不做处理,要不就得在switch 语句中加入default 子句。
switch (expression)
{
case value1: statement
case value2: statement
default: statement
}
当switch 后边的expression 的结果不是value1 ,也不是value2 的时候,就会执行default 子句。
代码演示:
#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;
default:
printf("输入错误\n");
break;
}
return 0;
}
在上述代码中,当我们存在多个条件都输出相同结果时,可以合并使用结果语句。
5.3 switch语句中的case和default的顺序问题
在switch 语句中case 子句和default 子句有要求顺序吗? default 只能放在最后吗?
其实,在switch 语句中case 语句和default 语句是没有顺序要求的,只要你的顺序是满足实际需求的就可以。
不过我们通常是把default 子句放在最后处理的。
六、while循环
C语言提供了3种循环语句, while 就是其中一种,接下来就介绍一下while 语句。
while 语句的语法结构和if 语句非常相似。
6.1 if 和 while的对比
if(表达式)
语句;
while(表达式)
语句; //如果循环体想包含更多的语句,可以加上大括号
实际代码对比:
//if语句
#include <stdio.h>
int main()
{
if(1)
printf("hehe\n"); //if后边条件满足,打印一次hehe
return 0;
}
//while语句
#include <stdio.h>
int main()
{
while(1)
printf("hehe\n"); //while后边的条件满足,死循环的打印hehe
return 0;
}
6.2 while语句的执行流程
首先上来就是执行判断表达式,表达式的值为0,循环直接结束;表达式的值不为0,则执行循环语句,语句执行完后再继续判断,是否进行下一次判断。
代码演示:
//在屏幕上打印1-10的值
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
printf("%d ", i);
i = i+1;
}
return 0;
}
代码结果:
七、for循环
7.1语法形式
for 循环是三种循环中使用最多的, for 循环的语法形式如下:
for(表达式1; 表达式2; 表达式3)
语句;//如果循环体想包含更多的语句,可以加上大括号
for循环的初始化、判断、调整三个部分都可以省略,若判断部分省略,则判断恒为真,就会造成死循环。
- 表达式1 :用于循环变量的初始化
- 表达式2 :用于循环结束条件的判断
- 表达式3 :用于循环变量的调整
7.2 for循环实践
代码演示:
//在屏幕上打印1~10的值
#include <stdio.h>
int main()
{
int i = 0;
for(i=1; i<=10; i++)
{
printf("%d ", i);
}
return 0;
}
代码结果:
7.3 while循环和for循环的对比
for 和while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是for 循环的三个部分非常集中,便于代码的维护,而如果代码较多的时候while 循环的三个部分就比较分散,所以从形式上for 循环要更优一些。
八、do-while循环
8.1 语法形式
在循环语句中do while 语句的使用最少,它的语法如下:
do
语句;
while(表达式);
while 和for 这两种循环都是先判断,条件如果满足就进入循环,执行循环语句,如果不满足就跳出循环;
而 do while 循环则是先直接进入循环体,执行循环语句,然后再执行 while 后的判断表达式,表达式为真,就会进行下一次,表达式为假,则不再继续循环。
8.2 do-while循环使用
代码演示:
//在屏幕上打印1~10的值
#include <stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ", i);
i = i + 1;
}while(i<=10);
return 0;
}
代码结果:
九、break和continue语句
在循环执行的过程中,如果某些状况发生的时候,需要提前终止循环,这是非常常见的现象。C语言中提供了break 和continue 两个关键字,就是应用到循环中的。
- break 的作用是用于永久的终止循环,只要break 被执行,直接就会跳出循环,继续往后执行。
- continue 的作用是跳过本次循环中continue 后边的代码,在for 循环和while 循环中有所差异的。
9.1 while循环中的break和continue
break举例:
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
break;//当i等于5后,就执行break,循环就终止了
printf("%d ", i);
i = i+1;
}
return 0;
}
代码结果:
打印了1,2,3,4后,当i等于5的时候,循环在break 的地方终止,不再打印,不再循环。
所以break 的作用就是永久的终止循环,只要break 被执行, break 外的第一层循环就终止了。
continue举例:
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
continue;
//当i等于5后,就执行continue,直接跳过continue的代码,去循环的判断的地方
//因为这里跳过了i = i+1,所以i一直为5,程序陷入和死循环
printf("%d ", i);
i = i+1;
}
return 0;
}
continue 可以帮助我们跳过某一次循环continue 后边的代码,直接到循环的判断部分,进行下一次循环的判断,如果循环的调整是在continue 后边的话,可能会造成死循环。
十、循环的嵌套
前面学习了三种循环while , do while , for ,这三种循环往往会嵌套在一起才能更好的解决问题。
代码演示:
#include <stdio.h>
int main()
{
int i = 0;
//循环产生100~200的数字
for(i=100; i<=200; i++)
{
//判断i是否为素数
//循环产生2~i-1之间的数字
int j = 0;
int flag = 1;//假设i是素数
for(j=2; j<i; j++)
{
if(i % j == 0)
{
flag = 0;
break;
}
}
if(flag == 1)
printf("%d ", i);
}
return 0;
}