1. if语句
2. 关系操作符
3. 条件操作符
4. 逻辑操作符:&&,||,!
5. switch语句
6. while循环
7. for循环
8. do-while循环
9. break和continue语句
10. 循环的嵌套
11. goto语句
同志们 好久不见,关于前二章的知识大家有没有认真学习呢?
那么接下来 我们来开始第三章的学习.
本章我们主要学习的是分支和循环
在我们日常解决问题的时候我们可以发现,不管什么事情的解决都是需要逻辑的,一般来说我们只需要三种形式就可以完美的解决其中的问题
> 1、顺序结构
2、选择结构
3、循环结构
或者是几种方式的集合。
本章我们就来讲解 2 、3这两种结构。
一、if语句
if 语句的语法形式如下
if (表达式)
语句;
1、 如果(表达式为真)则执行语句
2、 如果(表达式为假)则语句不执行
有一点我们需要注意的是:在C语言中 0 为假 ,非0为真。
让我们用代码来呈现
我们来写一个代码,比较两个整数的大小
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);
if(a>b)
{
printf("%d的值是最大的", a);
}
return 0;
}
8>5 为真 代码可以正常运行
5不大于8 (表达式)为假 则就无法执行该代码,也就无法打印
1.2
我们感觉如果只有一个if是不完整的,是的 if…与else 才能组成一个完整的整体。
else 就是用来补充if无法顾及的情况的
代码来如下
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);
if (a > b)
{
printf("%d的值是最大的", a);
}
else
{
printf("%d的值是最大的", b);
}
return 0;
}
通过这个例子我们就可以很好的看出 if 与else的相互补充 ,都是非常重要的。
接下来我们来练习一个例子
输入一个整数表示成绩 ,成绩在500以上就有本科上 否则则没有。
int main()
{
int score = 0;
scanf("%d", &score);
if (score >= 500)
{
printf("您有本科上");
}
else
{
printf("没有学上");
}
return 0;
}
1.3
当if控制着多条的语句时需要用大括号来括起来
if(表达式)
{
语句1
语句2
…
}
没加大括号
以下是加了大括号的
可以明显发现如果加上大括号就可以很好的控制所有的语句
1.4
if 语句的嵌套 意思就是我们可以用多次if …else 语句来完成一些代码的执行。
即在if else 语句中,else 可以与另⼀个if 语句连⽤,构成多重判断。
接下来 我们来直接练习一个.
我们对一部电影进行评价
1.如果大于9分算经典(每个都包含)
2.大于7分算非常好看
3.大于5分算 一般
4.小于5分算差劲
int main()
{
int score = 0;
scanf("%d", &score);
if (score >= 9)
{
printf("该电影是经典");
}
else if (score >= 7)
{
printf("该电影是非常好看");
}
else if (score >= 5)
{
printf("该电影是一般");
}
else
{
printf("该电影是差劲");
}
return 0;
}
1.5
else 的悬空问题
观察下边这个代码考虑其输出的值
int main()
{
int a = 2;
int b = 0;
if (a == 1)
if (b == 0)
b = 2; //大家第一次看见这个代码会有猜测a和b的值是多少呢?
else
a = 5; //w我第一次看这个代码猜的是a=5,b=0;
printf("a=%d b=%d", a, b);
return 0;
}
但是实际输出的值却是
这是为什么呢?其实这个代码的本质是按照以下的逻辑执行的
这就是悬空else 的问题,如果有多个的if匹配。上⾯的代码排版,让if 和else ,可以记住这样⼀条规则,else 总是跟最接近*(当我们遇见这种问题的时候,我们可以把距离if最近的else这两者用大括号括起来这样更容易理解而且不容易出错)
二、关系操作符
C语⾔⽤于⽐较的表达式,称为“关系表达式”(relationalexpression),⾥⾯使⽤的运算符就称为“关系运算符”(relationaloperator),主要有下⾯6个
1.>
2.<
3.>=
4.<=
5.!=(不等于)
6.==(这个是用来判断两个值大小是否相等)
接下来我们来一一举例
a == b;
a != b;
a < b;
a > b;
a <= b;
a >= b;
关系表达式通常会返回 0 或1,用来表示假或真,并且通常会用于for和while循环用来作为条件
关于关系操作符我们需要注意的是
1.=和==是不同的 ,=是用来赋值的 ,是用来判断的
(:相等运算符, 与赋值运算符=,是两个不⼀样的运算符,不要混淆。有时候,可能会不⼩⼼写出下⾯的代码,它可以运⾏,但很容易出现意料之外的结果。)
2.多个操作符不宜连用。
接下来我们用例子来帮助大家理解
如果我们是想比较两个数字的大小
可能会不注意把 == 写成=
注意看 ,我们这里用赋值=,a=5是给其赋值 ,5是非零为真所以就会输出;
如果我们换成= =呢?
这里我们用= =就是用来判断 a的值是否与5相等
0 不等于 5 是假 所以就不输出
那么如何避免这种情况呢?
我们只需要把常量写在前边,如果你这样来写,写的只要**不是==**编译器就会自动报错
**写成==**就不会报错,这样的问题也就迎刃而解了
2.2
多个操作符不易连用可能会造成一些编译错误的结果
我们用代码来观察一下,就会有清晰的认知
这里 50应该是成年的了,那么为什么会打印未成年呢?
这就是操作符连用造成的问题,那么接下来我们就来刨析一下该代码的问题。
因此在写代码的过程中我们要学会避免关系操作符的连用。
**三、**条件操作符
条件操作符 也叫三目操作符
其语法形式为:
条件判断?表达式1:表达式2;(1?2:3)
(1):如果1成立(真)则执行2,则2就为该表示的结果;
(2):如果1不成立(假)则执行3,3就为表达式的结果
还是实践;
int main1()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);
if (a > b)
{
printf("%d", a);
}
else
{
printf("%d", b);
}
return 0;
}
int main()
{
int a = 0; //代码我已经放在这里了,大家可以自行来验证一下,
int b = 0; //两种都可以实现,且结果相同,大家可以选择自己喜欢的一种
scanf("%d%d", &a, &b);
a > b ? printf("%d", a): printf("%d", b);
return 0;
}
**四、**逻辑操作符
逻辑操作符有3种
1.&&:逻辑与运算符(和)
2.||:逻辑或运算符 (或)
3.!:逻辑取反运算符 (反)
我们来举例子来理解一下吧,同志们!
相信通过这个例子就能帮助大家很好的理解,这逻辑运算符的作用,那么我们来实践一下吧!
int main()
{
int a = 0;
int b = 0;
int c = 20;
scanf("%d%d", &a, &b);
{
if (a > c && b < c) //两个都需要满足
{
printf("小黑子\n");
}
if (a > c || b < c) //满足一个即可
{
printf("真爱粉\n");
}
if (!a) //这里的a需为假!a为真才可以执行该输出
{
printf("我家哥哥\n");
}
}
return 0;
}
接下来 我们来练习一道题目
判断闰年
提示:
- 能被4整除并且不能被100整除是闰年
- 能被400整除是闰年
#include<stdio.h>
int main()
{ //这就是该代码的实现
int year = 0;
scanf("%d", &year);
if ((year % 4 == 0 && year % 100 != 0) || (year % 100 == 0))
{
printf("%d是闰年", year);
}
return 0;
}
4.2
此外逻辑运算符还有需要注意一个问题,C语⾔逻辑运算符还有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是
保证的。
如果左边的表达式满⾜逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”。
像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进⾏计算的运算称为短路求值。
接下来,我们仍然来举例子说明
#include<stdio.h>
int main()
{
int a = 0;
int b = 3;
int c = 5;
int i = 0;
i = a++ && b++ && c++; 仔细观察这两个代码,并猜测输出值。(运用了短路的知识)
// i = a++ || b++ || c++;
printf("i=%d,a=%d,b=%d,c=%d",i, a, b, c);
return 0;
}
五、switch语句
除了if语句switch语句也有实现分支的作用,其实也可以这样说:switch语句是if语句的一种特殊形式。但是switch更简洁可读性好
其语法形式为
switch (expression) {
case value1:
statement
break;
case value2:
statement
break;
…
default: statement
}
这里需要注意:
1:case后边必须是常量
2;switch后的表达式必须是常量表达式
3:这里的break是为了跳出switch语句
如果我们再写代码时不用break;会怎么样呢?
没break就不会打印只满足的条件而是所有printf都会打印
加上break就能很好的解决该条件
接下来我们举一个例子来对比其中的差异
int main()
{
int num = 0;
scanf("%d", &num);
if (num % 3 == 0)
{
printf("该数能被整除");
}
else if (num % 3 == 1)
{
printf("该余数为1");
}
else if (num % 3 == 2)
{
printf("该余数为2");
}
return 0;
}
//大家可以运行来自行比较两者的不同,观察其运行的速度,大家就可以惊奇的发现switch的运行速度会更快一点
int main2()
{
int a = 0 ;
scanf("%d", &a);
switch(a%3)
{
case 0 :
printf("该数能被整除");
break;
case 1 :
printf("该余数为1");
break;
case 2 :
printf("该余数为2");
break;
}
return 0;
}
**六、**while循环
循环的作用是什么呢?如果我们要打印10个1,没有循环我们是这样打印的的
这样写出来的代码不仅占据空间大,而且不美观
但是如果我们利用了循环呢?
*这里我们发现代码即美观而且又简洁。
那么while循环时如何执行的呢
我们首先来是要判断表达式是否成立,如果成则就执行循环内部的表达式,反之则不执行。
接下来我们来练习一个题目
在屏幕上打印1到10的数值(我们用以前的方法会很笨拙,那么循环的意义就是在这里)
int main()
{
int num = 1;
while (num <= 10)
{
printf("%d\n", num);
num++;
}
return 0;
}
再练习一个题目
输⼊⼀个正的整数,逆序打印这个整数的每⼀位
例如:
输⼊:123,输出:321
输⼊:146,输出:641
int main()
{
int num1 = 0;
scanf("%d", &num1);
while (num1)
{
printf("%d ", num1 % 10);
num1 /= 10;
}
return 0;
}
七、for循环
for 循环是我们使用最多,并且for循环的语法简单方便理解,因此受欢迎
语句如下:
for(表达式1; 表达式2; 表达式3)
语句;(如果使用的语句不止一条就要加上大括号)
注意三个表达式都有他们自己的含义
表达式1:为变量的初始化
表达式2:条件的判断
表达式3:变量的调整
那么我们用for循环是如何打印1到10呢?
int main()
{
int i = 0;
//1初始值 // 2循环条件 //3初始值的调整
for (i = 1; i <= 10; i++)
{
printf("%d ", i);
}
return 0;
}
我们已经学了两种循环我么接下来看一下两者的区别·
光学不练假把式
接下来我们就来进行一个练习
计算1~100之间3的倍数的数字之和
我们使用两种方式来来实现这个练习
int main1()
{
int num = 0;
int sum = 0;
//这里我们还可以进行一个小优化
//3的倍数,我们只要+3不就可以每次都找到3的倍数了
for (num = 1; num <= 6; num++/*num=num+3*/)
{
if (num % 3 == 0)
{
sum += num;//相当于sum = sum + num ;
}
}
printf("sum =%d", sum);
return 0;
}
int main()
{
int num = 1;
int sum = 0;
while (num<=100)
{
if (num % 3 == 0)
{
sum = sum + num;
}
num++;
}
printf("sum =%d", sum);
return 0;
}
八 、do-while循环
do-while循环与for和while不同的是,不论条件成立与否,必定会执行一次,然后再判断条件是否为真或假,如果表达式为假则就不再执行
我们不难发现如果条件为恒真则就死循环了
但是即使为恒假 代码也会至少执行一次
代码如下
练习
输⼊⼀个正整数,计算这个整数是⼏位数?
例如:
输⼊:12345 输出:5
输⼊:521 输出:3
int main()
{
int num = 0;
scanf("%d", &num);
int sum = 0; //输入一个数,它肯定至少是一位数
do
{
sum++; //在这里就要提前+1
num = num / 10; //每除10就会消去一位 521
} while (num);
printf("该数是%d位数", sum);
return 0;
}
九、breakh和continue
在我们写代码的时候遇到某些特定的条件可能会需要提前结束或者跳过某段代码,这是很正常的事情。
而c语言就给我们提供了两种语句为我们实现这两种情况
1:break
的作⽤是⽤于永久的终⽌循环,只要break 被执⾏,直接就会跳出循环,继续往后执⾏。
2: continue 的作⽤是跳过本次循环中continue
后边的代码,在for 循环和while 循环中有所差异的
9.1
我们来先举while循环中的break和continue
#include<stdio.h>
int main()
{
int a = 0;
while (a <= 10)
{
if (a == 5)
{
break; //当a=5时,就直接终结了循环,直接跳出
}
printf("%d\n", a);
a++;
}
return 0;
}
int main1()
{
int a = 0;
while (a <= 10)
{
if (a == 5)
{
continue; //跳过continue后的语句,a=5跳过+1,那么就会一直为5,那就陷入了死循环(这里的光标一直在闪动)
}
printf("%d\n", a);
a++;
}
return 0;
}
9.2 for 循环中的break和continue
for和while这里会有什么不同呢我们来观察一下
int main3()
{
int a = 0;
for (a = 0; a <= 10; a++) //for循环中,是先执行循环语句中的语句,然后再执行++,所以这就有区别与while循环
{
if (a == 5)
{
continue; //这里我们可以看见只是把5给跳过了,其他的照样打印
}
printf("%d\n", a);//这是因为执行berak后再++,就不会影响代码的运行
}
return 0;
}
int main()
{
int a = 0;
for (a = 0; a <= 10; a++)
{
if (a == 5)
{
break; //这里就是当a=5就直接结束了循环,++不会执行所以就直接打印 0到4
}
printf("%d\n", a);
}
return 0;
}
9.3 do while 循环中的continue和break 和while循环中的作用几乎是一样的,这里我就不举例子,留给同志们自行练习。听百遍不如自己实践一边
**十、**循环的嵌套
前⾯学习了三种循环 whlie、for 、do,while这三种循环往往会嵌套在⼀起才能更好的解决
问题,就是我们所说的:循环嵌套,这⾥我们就看⼀个例⼦。
- 要从100到200之间找出素数,⾸先得有100~200之间的数
(产生了多个数字,所以我们要用循环) - 假设要判断i是否为素数,需要拿2到i-1之间的数字去试除i,需要产⽣2~i-1之间的数字,也可以使⽤
循环解决。(循环) - 如果2~i-1之间有数字能整除i,则i不是素数,如果都不能整除,则i是素数。
# include<stdbool.h>
int main()
{
int i = 0;
for (i = 100; i <= 200; i++)
{
//
int j = 0;
bool flag = true; //假设i 为素数
for (j = 2; j < i; j++) //产生 2到i-1的数
{
if (i % j == 0)
{
/*printf("%d不是素数\n", i);*/
flag = false; // i 就不是素数
break;
}
}
if (flag == true) //是素数,就打印
{
printf("%d是素数\n", i);
}
}
return 0;
}
这里用其它两种循环也同样可以解决
十一、goto语句
C语⾔提供了⼀种⾮常特别的语法,就是
内跳转到设置好的标号处。 goto 语句可以实现在同⼀个函数内跳转到设置好的标号处。
例如:
goto 语句一般用在需要跳出多层循环的代码中,相比与break只能跳出一层循环,而goto语句可以直接跳出多层循环。此时用goto语句就十分方便了。
莫愁前路无知己,天下谁人不识君。