分支语句和循环语句
- if语句
- 关系操作符
- 条件操作符
- 逻辑操作符 && || !
- switch语句
- while循环
- for循环
- do…while循环
- break和continue语句
- 循环的嵌套
- goto语句
- C语言是一门结构化的程序设计语言,包含有顺序结构,选择结构,循环结构
if语句
if语句
- if语句的整体语法格式如下所示:
- 表达式成立(为真),则语句执行,表达式不成立(为假),则语句不执行;那么什么叫真,什么叫假呢, 其实在C语言里面,0表示假,非0表示真
- 输入一个数字,判断他是不是奇数
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if (n % 2 == 1)
printf("是奇数\n");
return 0;
}
- 上面的代码,当你输入11的时候就会输出是奇数,但是有个问题,如果我们输入12的话,其实就是没有任何输出的,也就是说,这个代码没有完全考虑所有情况,所以我们其实还需要一个else的情况
else语句
- 那么这个时候,其实就需要 if else 的语句了
- 下面这个代码,当我们输入12的时候,其实就会输出是偶数的结果了
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if (n % 2 == 1)
printf("是奇数\n");
else
printf("是偶数\n");
return 0;
}
- 输⼊⼀个年龄,>= 18岁就输出:成年,否则就输出:未成年
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
printf("成年\n");
else
printf("未成年\n");
return 0;
}
分支中包含多条语句
- 默认在 if 和 else 语句中默认都只控制⼀条语句,比如说,下面这个代码,当我们输入20的时候,还是会给我们输出不可以谈恋爱,这个就说明下面的else只能包含一条语句
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
printf("成年\n");
else
printf("未成年\n");
printf("不可以谈恋爱\n");
return 0;
}
- 如果我们希望包含多条语句的话,那么我们就需要用花括号把相应的代码全部扩在一起
- 下面这个代码就不会有什么问题了
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
printf("成年\n");
else
{
printf("未成年\n");
printf("不可以谈恋爱\n");
}
return 0;
}
嵌套if
- 在 if else 语句中, else 可以与另⼀个 if 语句连用,构成多重判断,比如:要求输⼊⼀个整数,判断输⼊的整数是0,还是正数或者负数
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if (n <= 0)
{
if (n == 0)
printf("n是0\n");
else if (n < 0)
printf("n是负数\n");
}
else
printf("n是正数\n");
}
- 同时还有另一种写法
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if (n == 0)
printf("n是0\n");
else if (n < 0)
printf("n是负数\n");
else
printf("n是正数\n");
}
悬挂else
- 悬挂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;
}
//这段代码什么都不会打印 第二个else会在编译器中主动和第二个if靠近
//所以代码什么都不会打印,没有符合的条件
- 之所以我们会误解,其实也有一部分原因是上面代码对齐的问题,会让我们觉得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;
}
- 当然了,如果我们相让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;
}
关系操作符
- C 语言用于比较的表达式,称为 “关系表达式”,里面使用的运算符就称为“关系运算符”
- 主要有大于 小于 大于等于 小于等于 等于 不等于 这几种关系运算符
- 关系表达式通常返回0或者1 ,表示真假
#include<stdio.h>
int main()
{
int c = (3 == 5);
printf("%d", c); //0
return 0;
}
#include<stdio.h>
int main()
{
int c = (3 == 3);
printf("%d", c); //1
return 0;
}
- 这里需要同步注意的一个点在于一个等号和两个等号的差别,一个等号的意思是复制,两个等号的意思在判断是不是相等,比如说下面的这个代码是不是会打印hehe呢,其实是不会的,因为这里3和5并不是相等的,所以条件判断是假的,也就自然不会执行的
#include<stdio.h>
int main()
{
int a = 5;
if (3 == a)
printf("hehe\n");
return 0;
}
- 但是如果是一个等号的话,就是可以的,下面这种是一个赋值操作,条件是真的,所以就是完全可以打印出来hehe的
#include<stdio.h>
int main()
{
int a = 5;
if (a = 3)
printf("hehe\n");
return 0;
}
- 那么为了防止有人上面一个等号和另一个等号进行混用,所以我们一般就是把常量放在左边,这个时候,我们再把一个等号和两个等号混用的时候,代码就会直接报错了
- 就像下面这样:
#include<stdio.h>
int main()
{
int a = 5;
if (3 = a)
printf("hehe\n");
return 0;
}
多个运算符不宜联用
i<j<k
- 上⾯示例中,连续使用两个⼩于运算符。这是合法表达式,不会报错,但是通常达不到想要的结果,即不是保证变量 j 的值在 i 和 k 之间,因为关系运算符是从左到右计算,所以实际执行的是下⾯的表达式
(i < j) < k
- 上面表达式中, i < j 返回 0 或 1 ,所以最终是 0 或 1 与变量 k 进行比较,如果想要判断变量 j 的值是否在 i 和 k 之间,应该使用下面的写法
i < j && j < k
- 比如我们要去判断年龄是否在某个区间内,我们就不要使用下面这种代码
- 正确的代码如下所示,是可以输出正确的结果的
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age > 18 && age < 36)
printf("ok\n");
else
printf("no\n");
return 0;
}
条件操作符
- 条件操作符也叫三目操作符,需要接受三个操作数的,形式如下:
- a?b:c 意思就是如果a是真的话,就执行b,如果a是假的话,就执行c,比如说,我们看下面的代码
#include<stdio.h>
int main()
{
int b = 0;
int c = 0;
scanf("%d", &b);
if (b > 1)
c = 3;
if (b < 1)
c = -3;
printf("%d", c);
return 0;
}
- 当然了,上面的代码是用分支去实现的,我们也可以使用条件操作符去实现,如下:
#include<stdio.h>
int main()
{
int b = 0;
int c = 0;
scanf("%d", &b);
c = b > 1 ? 3 : -3;
printf("%d", c);
return 0;
}
- 用条件操作符找出两个数字里面的较大数
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
int c = 0;
scanf("%d %d", &a, &b);
c = a > b ? a : b;
printf("%d", c);
return 0;
}
逻辑操作符 && || !
!
- !的作用在于,这个操作符可以让真的变成假的,也能让假的变成真的
#include<stdio.h>
int main()
{
int a = 10;
int b = !a;
printf("%d\n", b);
return 0;
}
#include<stdio.h>
int main()
{
int a = 0;
int b = !a;
printf("%d\n", b);
return 0;
}
&&
- &&这个操作符被称为逻辑与,也是并且的意思,&&是⼀个双目操作符,使用的方式是a&&b ,&& 两边的表达式都是真的时候,整个表达式才为真,只要有⼀个是假,则整个表达式为假。
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int c = a && b;
printf("%d", c);
return 0;
}
||
- || 就是或运算符,也就是或者的意思,|| 也是⼀个双目的操作符,使用的方式是a || b ,||两边的表达式只要有⼀个是真,整个表达式就是真,两边的表达式都为假的时候,才为假
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int c = a || b;
printf("%d", c);
return 0;
}
- 练习------闰年的判断
#include<stdio.h>
int main()
{
int year = 0;
scanf("%d", &year);
if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0))
printf("%d是闰年\n", year);
else
printf("不是闰年\n");
return 0;
}
短路
- C语言逻辑运算符还有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的
- 如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”
- 练习:阅读代码,计算代码输出的结果
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
//i = a++||++b||d++;
printf("a =%d\nb =%d\nc =%d\nd =%d\ni=%d", a, b, c, d,i);
return 0;
}
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++||++b||d++;
printf("a =%d\nb =%d\nc =%d\nd =%d\ni=%d", a, b, c, d, i);
return 0;
}
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a =%d\nb =%d\nc =%d\nd =%d\ni=%d", a, b, c, d, i);
return 0;
}
switch
- 除了if 语句外,C语言还提供了switch语句来实现分支结构
- switch语句是⼀种特殊形式的if…else结构,用于判断条件有多个结果的情况。它把多重的if…else改成更易用、可读性更好的形式
- 格式如下所示:
- 上面代码中,根据表达式expression 不同的值,执行相应的case分支。如果找不到对应的值,就执行default分支
- switch后的expression 必须是整型表达式
- case后的值,必须是整形常量表达式
- 练习:输⼊任意⼀个整数值,计算除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格式的, case和后边的数字之间必须有空
- 每⼀个case 语句中的代码执行完成后,需要加上break ,才能跳出这个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;
default:
printf("错误了\n");
break;
}
return 0;
}
switch语句中的default
- 在使用switch语句的时候,我们经常可能遇到⼀种情况,比如switch后的表达式中的值无法匹配代码中的
case语句的时候,这时候要不就不做处理要不就得在switch语句中加⼊default子句。 - switch后边的expression的结果不是value1,也不是value2的时候,就会执行default子句。比如:
- 打印星期的代码
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期一\n");
break;
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("星期六\n");
break;
case 7:
printf("星期日\n");
break;
default:
printf("错误\n");
break;
}
return 0;
}
switch语句中的case和default的顺序问题
- 在switch语句中case子句和default子句有要求顺序吗?default只能放在最后吗?
- 其实,在switch语句中case语句和default语句是没有顺序要求的,,只要你的顺序是满足实际需求的就可以,不过我们通常是把default子句放在最后处理的
while循环
- C语言中提供了三种循环,while就是其中的一种,while语句的语法结构和if语句的语法结构是非常类型的
- 我们来看看while和if语句的对比
- 下面的代码打印一个ok
#include<stdio.h>
int main()
{
if (1)
{
printf("ok\n");
}
return 0;
}
- 下面的代码会一直打印,这就是他们的区别,while语句是可以实现循环效果的
- while循环体里面如果不止一条语句的话,一定要加上大括号
#include<stdio.h>
int main()
{
while (1)
{
printf("ok\n");
}
return 0;
}
while语句的执行流程
- 首先上来就是执行判断表达式,表达式的值为0,循环直接结束;表达式的值不为0,则执行循环语句,语句执行完后再继续判断,是否就行下⼀次判断
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
printf("%d ", i);
i++;
}
return 0;
}
- 输⼊⼀个正的整数,逆序打印这个整数的每⼀位
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
while (n)
{
printf("%d ", n % 10);
n = n / 10;
}
return 0;
}
for循环
- for循环是三种循环里面使用最多的一种循环,for循环的整体格式如下所示:
for循环的执行流程
- 打印1-10
#include<stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
printf("%d ", i);
}
return 0;
}
- 计算1-00之间的三的倍数的和
#include<stdio.h>
int main()
{
int sum = 0;
for (int i = 1; i <= 100; i++)
{
if (i % 3 == 0)
{
sum += i;
}
}
printf("%d", sum);
return 0;
}
do…while循环
- do…while循环是三种循环里面用的最少的循环,dowhile循环的格式如下所示:
- 同时dowhile有一个特征,就是循环体至少会被执行一次
- while 和 for 这两种循环都是先判断,条件如果满足就进入循环,执行循环语句,如果不满足就跳出循环
- ⽽ do while 循环则是先直接进入循环体,执行循环语句,然后再执行 while 后的判断表达式,表达式为真,就会进⾏下⼀次,表达式为假,则不再继续循环
do…while执行的流程
- 在 do while 循环中先执⾏图上的“语句”,执行完语句,在去执行“判断表达式”,判断达式的结果是!=0,则继续循环,执⾏循环语句;判断表达式的结果==0,则循环结束
- 打印1-10
#include<stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
- 输⼊⼀个正整数,计算这个整数是几位数?
#include<stdio.h>
int main()
{
int count = 0;
int n = 0;
scanf("%d", &n);
do
{
count++;
n = n / 10;
} while (n);
printf("%d", count);
return 0;
}
break和continue语句
- 在循环执行的过程中,如果某些状况发生的时候,需要提前终止循环,这是非常常见的现象。C语言中提供了 break 和 continue 两个关键字,就是应用到循环中的
- break 的作⽤是用于永久的终止循环,只要 break 被执行,直接就会跳出循环,继续往后执行
- continue 的作⽤是跳过本次循环中 continue 后边的代码,在 for 循环和 while 循环中有
所差异的
while循环中的break和continue
- 下面代码打印的结果是1 2 3 4
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
break; // 1 2 3 4
printf("%d ", i);
i++;
}
return 0;
}
- 下面的代码执行的结果是 1 2 3 4 死循环
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
continue; // 1 2 3 4...
printf("%d ", i);
i++;
}
return 0;
}
for循环中的break和continue
- 下面这个代码打印的结果是1 2 3 4
#include<stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
if (i == 5)
break;
printf("%d ", i); //1 2 3 4
}
return 0;
}
- 下面代码的执行结果是1 2 3 4 6 7 8 9 10
#include<stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
if (i == 5)
continue;
printf("%d ", i); //1 2 3 4 6 7 8 9 10
}
return 0;
}
do while循环中的break和continue
- 下面代码打印的结果是1 2 3 4
#include<stdio.h>
int main()
{
int i = 1;
do
{
if (i == 5)
break;
printf("%d ", i); //1 2 3 4
i++;
} while (i <= 10);
}
- 下面这个底阿妈打印结果是1 2 3 4 死循环
#include<stdio.h>
int main()
{
int i = 1;
do
{
if (i == 5)
continue;
printf("%d ", i); //1 2 3 4
i++;
} while (i <= 10);
}
循环的嵌套
- 前⾯学习了三种循环 while , do while , for ,这三种循环往往会嵌套在⼀起才能更好的解决问题,就是我们所说的:循环嵌套,这里我们就看⼀个例子
- 打印100-200之间的所有的素数
#include<stdio.h>
int main()
{
int count = 0;
int j = 2;
for (int i = 100; i <= 200; i++)
{
for (j = 2; j < i; j++)
{
if (i % j == 0)
break;
}
if (j == i)
{
printf("%d ", i);
count++;
}
}
printf("\n");
printf("%d", count);
return 0;
}
- 用开平方去写代码
#include<stdio.h>
#include<math.h>
int main()
{
int count = 0;
int j = 2;
for (int i = 100; i <= 200; i++)
{
for (j = 2; j <= sqrt(i); j++)
{
if (i % j == 0)
break;
}
if (j >sqrt(i))
{
printf("%d ", i);
count++;
}
}
printf("\n");
printf("%d", count);
return 0;
}
goto语句
- C语言提供了⼀种非常特别的语法,就是 goto 语句和跳转标号, goto 语句可以实现在同⼀个函数内跳转到设置好的标号处
#include<stdio.h>
int main()
{
printf("haha\n");
goto next;
printf("hehe\n");
next:
printf("ok\n");
return 0;
}
- goto 语句如果使用的不当,就会导致在函数内部随意乱跳转,打乱程序的执行流程,所以我们的建议是能不用尽量不去使用;但是 goto 语句也不是一无是处,在多层循环的代码中,如果想快速跳出,使⽤ goto 就非常的方便了
- break一次只能跳出一层循环,但是goto一次是可以跳出多层循环的
关机程序
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
int main()
{
char arr[20] = { 0 };
system("shutdown -s -t 60");
again:
printf("你的电脑将会在一分钟后关机,如果输入你是猪,则取消关机\n");
scanf("%s", arr);
if (0 == strcmp(arr, "你是猪"))
{
system("shutdown -a");
}
else
{
goto again;
}
}
- 循环的写法
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
int main()
{
char arr[20] = { 0 };
system("shutdown -s -t 60");
while (1)
{
printf("你的电脑将会在一分钟后关机,如果输入你是猪,则取消关机\n");
scanf("%s", arr);
if (0 == strcmp(arr, "你是猪"))
{
system("shutdown -a");
break;
}
}
}