目录
3.循环语句 😊
1.什么是语句🤞
C语言中的语句大致可分为下面五类:🥰
1. 表达式语句
2. 函数调用语句
3. 控制语句
4. 复合语句
5. 空语句
其中,我们今天主要讲的是控制语句,控制语句用于控制程序的执行流程,以实现程序的各种结构方式(C语言支持三种结构:顺序结构、选 择结构、循环结构),它们由特定的语句定义符组成,C语言有九种控制语句。
可分成以下三类:👇
1. 条件判断语句也叫分支语句:if语句、switch语句;
2. 循环执行语句:do while语句、while语句、for语句;
3. 转向语句:break语句、goto语句、continue语句、return语句。
2.分支语句(选择结构)🤞
在人生中处处面临着选择,每种选择都会有相应的结果:
C语言中如何实现这种多样的选择呢?
2.1 if语句🤞
if语句的语法结构:
if(表达式)
语句1;
if(表达式)
语句2;
如果是多分支语句,也可以这样写:
if(表达式1)
语句1;
else if(表达式2)
语句2;
else
语句3;
让我们来举个例子吧:
#include<iostream>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("未成年\n");
else
printf("成年\n");
return 0;
}
上面是一个简单的if语句,而下面这种稍微复杂一点:
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("青少年\n");
else if (age >= 18 && age <= 30)
printf("青年\n");
else if (age >= 31 && age <= 50)
printf("中老年\n");
else if (age >= 81 && age <= 100)
printf("老年\n");
else
printf("老妖精\n");
return 0;
}
注意:当有多个条件并存时,要使用“&&”
错误示例 :
正确示例:
能否将上述代码中的else去掉呢,变成下面这样:
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("青少年\n");
if (age >= 31 && age <= 50)
printf("青年\n");
if (age >= 31 && age <= 50)
printf("中老年\n");
if (age >= 81 && age <= 100)
printf("老年\n");
if (age > 100)
printf("老妖精\n");
return 0;
}
答案是可以,但是第一种代码执行的效率可能要高,因为第一种到遇到满足的条件,其后面的判断语句就不会再执行,最多执行5次判断,最少只会执行一次判断,如果是第二种代码,则会执行每一条if语句,一定会执行5次判断。
上述代码还可以这样写:
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("青少年\n");
else
{
if (age >= 31 && age <= 50)
printf("青年\n");
else if (age >= 31 && age <= 50)
printf("中老年\n");
else if (age >= 81 && age <= 100)
printf("老年\n");
else
printf("老妖精\n");
}
return 0;
}
这种写法是if语句的嵌套使用 ,和上面的代码执行逻辑是一样的
关于大括号的省略:🤞
当if或else下面只控制一条语句时,可以省略大括号,如果有多条语句,则大括号不能省略,当有if嵌套时也可以省略大括号:
例如:👇
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("未成年\n");
else
{
printf("成年\n");
printf("交女朋友\n");
}
return 0;
}
//if嵌套省略大括号的情景
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
printf("青少年\n");
else
if (age >= 31 && age <= 50)
printf("青年\n");
else if (age >= 31 && age <= 50)
printf("中老年\n");
else if (age >= 81 && age <= 100)
printf("老年\n");
else
printf("老妖精\n");
return 0;
}
好的编程习惯是不管是一条语句还是多条语句都把大括号加上
测验:下面代码的输出结果是什么?
绝大多数人是这样认为的:先判断第一条if语句,条件不成立,则执行else中的内容,输出“haha”,然而正确的答案是屏幕上什么也不打印;
其实是这串代码的对齐方式欺骗了我们,当我们正确的对其代码后,结果就显而易见了:因为这种if嵌套是可以省略大括号的,当我们加上括号就是左边这样:
小贴士:
在我们写像这样的代码:
如果我们少写了一个‘=“编译的结果就会出现错误:
因为编译器会将一个等号认作是赋值语句,将a的值赋值为1.此时if条件就是永真了。
为了避免出行这种错误,我们可以把a写在后边:
如果少写了一个’=‘,编译器就会报错,方便我们及时发现。
练习:
1.判断一个数是否为奇数
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
if (a % 2 == 1)
{
printf("是奇数\n");
}
else
{
printf("不是奇数");
}
return 0;
}
2.输出1-100间的奇数
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 100)
{
if (i % 2 == 1)
printf("%d ", i);
i++;
}
return 0;
}
2.2 switch语句🤞
switch语句也是一种分支语句。 常常用于多分支的情况。
有这样一种情况:我们从键盘上输入数字1-7,程序就会输出对应的星期。这用代码怎么实现呢?
如果用if...else...语句就是下面这样实现的:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
if (day == 1)
printf("星期一\n");
else if (day == 2)
printf("星期二\n");
else if (day == 3)
printf("星期三\n");
else if (day == 4)
printf("星期四\n");
else if (day == 5)
printf("星期五\n");
else if (day == 6)
printf("星期六\n");
else if (day == 7)
printf("星期天\n");
else
printf("输入错误\n");
return 0;
}
像这样的代码,其实更适合用switch语句来实现:
#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("输入错误");
break;
}
return 0;
}
其中,case后面的数必须是整形常量,不能是变量。
switch后边括号里边变量类型可以是整形,字符型。但是不能是浮点型。
switch语句中break的作用:结束switch语句,防止进入下一条语句。
有时候我们的需求变了,就可以适当的删去一些break:
1. 输入1-5,输出的是“weekday”;
2. 输入6-7,输出“weekend”
所以我们的代码就应该这样实现了:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("weekday\n");
break;
case 6:
case 7:
printf("weekend\n");
break;
default:
printf("输入错误");
break;
}
return 0;
}
default子句的作用:
如果表达的值与所有的case标签的值都不匹配怎么办?
其实也没什么,结果就是所有的语句都被跳过而已。
程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。
但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?
你可以在语句列表中增加一条default子句,把下面的标签 default: 写在任何一个 case 标签可以出现的位置。
当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。 所以,每个switch语句中只能出现一条default子句。 但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
好的编程习惯:
在每个 switch 语句中都放一条default子句是个好习惯,甚至可以在后边再加一个 break 。
3.循环语句 🤞
3.1 while循环🤞
我们已经掌握了if语句,当条件满足的情况下,if语句后的语句执行,否则不执行。 但是这个语句只会执行一次。 由于我们发现生活中很多的实际的例子是:同一件事情我们需要完成很多次。 那我们怎么做呢? C语言中给我们引入了: while 语句,可以实现循环。
要在屏幕上输出1-10的数字,用代码怎么实现呢?
#include<stdio.h>
int main()
{
int n = 1;
while (n <= 10)
{
printf("%d ", n);
n++;
}
return 0;
}
如果在循环体内加上break和continue语句会发生什么呢:
#include<stdio.h>
int main()
{
int n = 1;
while (n <= 10)
{
if (n == 5)
break;
printf("%d ", n);
n++;
}
return 0;
}
加上break的作用就是让循环终止,在上述代码中,当n=5的时候,执行break语句,于是程序就终止 了循环,在屏幕上只输出了 1 2 3 4,在循环中,当某个条件发生时,不想让循环继续执行下去,就可以使用break来达到目的。
break的作用:终止循环。
下面来看看continue的作用:
#include<stdio.h>
int main()
{
int n = 1;
while (n <= 10)
{
if (n == 5)
continue;
printf("%d ", n);
n++;
}
return 0;
}
当执行这段代码,屏幕上只出现了1 2 3 4,但是4后面的光标却一直在闪烁,说明程序并没有结束,而是出现了死循环,原因就是continue引发的。当程序执行时遇到continue,程序就会结束当前的循环,然后进入下一次循环,因此当n=5是,程序执行continue语句,导致后面的语句直接跳过进入下一次循环,但是在以后的每一次进入循环,n的值都是5,所以程序陷入了死循环。
如果改变n++的位置,就可以避免死循环的发生:
#include<stdio.h>
int main()
{
int n = 1;
while (n <= 10)
{
n++;
if (n == 5)
continue;
printf("%d ", n);
}
return 0;
}
continue的作用:跳过本次循环continue后边的语句,直接去while循环的判断部分
下面让我们来看几个代码:
#include <stdio.h>
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)
putchar(ch);
return 0;
}
这个代码的作用是读取键盘输入得字符并输出在屏幕上,到读取到的内容为空(按下ctrl+z)的时候结束程序
EOF:end of file,文件结束标志
EOF的应用:
在scanf函数中,scanf读取成功,返回的是读取到的数据个数,读取失败返回EOF
在getchar中,getchar读取成功返回的是字符的ASCII码值,读取失败返回EOF
这串代码做适当的修改可以用来清空代码缓冲区:
例如:有这样的情景:
#include <stdio.h>
int main()
{
char password[] = { 0 };
printf("请输入密码:->");
scanf("%s", password);
printf("请确认密码(N/Y):>");
char input;
input=getchar();
if (input == 'Y')
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
上述代码是一个输入密码的操作,输完密码后需要我们来输入一个字符来确认密码,当我们输入字符后,在屏幕上打印“确认成功”或者是“确认失败”
但是我们运行代码并输入密码后运行结果是这样的:
我们还没有输入‘Y或者’N’屏幕上却自动的输出了 “确认失败 ”,这是什么原因呢?
当我们从键盘缓冲区输入123456并按下回车键,键盘缓冲间里就有了“1233456\n”,但scanf函数只会的去‘\n'前面的内容,因此键盘缓冲区你还剩下‘\n’没有被读取,当执行getchar函数时,‘\n’就会被getchar给读走,然后再赋给input。
要想解决这个情况,我们需要想办法把‘\n’给处理掉 ,可以单独放一个getchar来吃掉‘\n’,如下面的代码:👇
#include <stdio.h>
int main()
{
char password[20] = { 0 };
printf("请输入密码:->");
scanf("%s", password);
printf("请确认密码(N/Y):->");
getchar();
char input;
input = getchar();
if (input == 'Y')
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
这样程序就可以正常运行了。
还有一种情况,当我们从键盘输完123456,有输入了空格和其他字符,这样也会引起错误:
原因是scanf不能读取空格,遇到空格就结束输入,后面的字符停留在了输入缓冲区被getchar读取到了。
解决方法:👇
#include <stdio.h>
int main()
{
char password[20] = { 0 };
printf("请输入密码:->");
scanf("%s", password);
printf("请确认密码(N/Y):->");
//清理缓冲区中剩余数据
while (getchar() != '\n')
{
}
char input;
input = getchar();
if (input == 'Y')
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
3.2 for循环🤞
我们已经知道了while循环,但是我们为什么还要一个for循环呢?
首先来看看for循环的语法:
表达式1 表达式1为初始化部分,用于初始化循环变量的。
表达式2 表达式2为条件判断部分,用于判断循环时候终止。
表达式3 表达式3为调整部分,用于循环条件的调整。
实际使用:
使用for循环 在屏幕上打印1-10的数字.
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
printf("%d ", i);
}
return 0;
}
for循环不加大括号只能控制一条语句,如果想要控制多条语句,必须加上一组大括号。
在for循环里也可以使用break和continue语句:
加break:👇
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
加continue:👇
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问 题。
#include<stdio.h>
int main()
{
for (;;)
{
printf("hehe");
}
return 0;
}
这个代码的三个表达式都省略了,意味着判断是恒为真的,代码将死循环的打印“hehe”
比较下面两串代码的输出结果:👇
左边代码输出结果:👇
右边代码输出结果:👇
原因:右边的代码省略了第一个表达式,当外层循环第一次执行结束后,j的值已经变成了4,无法进入第二层循环,因此只打印4次
3.3 do...while()循环🤞
do语句的语法:
使用do while循环打印1-10:
代码:👇
#include<stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ", i);
i++;
}while(i <= 10);
return 0;
}
在do while循环里也可以使用break和continue,基本方法和上面的循环一样。
3.4 有关循环语句的练习🤞
1. 计算 n的阶乘。
代码:👇
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int i = 0;
int ret = 1;
for (i = 1; i <= n; i++)
{
ret *= i;
}
printf("%d\n", ret);
return 0;
}
2. 计算 1!+2!+3!+……+10!
代码:👇
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int i = 0;
int ret = 1, sum = 0;
for (i = 1; i <= n; i++)
{
ret *= i;
sum += ret;
}
printf("%d\n", sum);
return 0;
}
3. 编写代码,演示多个字符从两端移动,向中间汇聚。
代码的效果就是依次在屏幕上输出下面图片上的每一行:
代码:👇
#include<stdio.h>
#include<windows.h>
#include<string.h>
int main()
{
char arr1[] = "Nice to meet you!";
char arr2[] = "#################";
int left = 0;
int right = strlen(arr1) - 1;
while(left<=right)
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
printf("%s\n", arr2);
Sleep(500);
system("cls");
left++;
right--;
}
printf("%s\n", arr2);
return 0;
}
4. 编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则 提示登录成,如果三次均输入错误,则退出程序。
代码:👇
#include<stdio.h>
#include<string.h>
int main()
{
int i = 0;
char password[20] = { 0 };
char s[20] = "123456";//假设密码是123456
for (i = 0; i < 3; i++)
{
printf("请输入密码:\n");
scanf("%s", &password);
if (strcmp(password, s) == 0)
{
printf("登录成功\n");
break;
}
else
{
printf("密码错误\n");
}
}
if (i == 3)
{
printf("退出程序\n");
}
return 0;
}
3.5 折半查找🤞
在一个有序数组中查找具体的某个数字n。
代码模板: 👇
#include <stdio.h>
int main()
{
int g[] = { 1,2,3,4,5,6,7,8,9,10 };
int k, flag = 0;
int left = 0;
int right = sizeof(g) / sizeof(g[0]) - 1;
printf("请输入要查找的数:\n");
scanf("%d", &k);
while(left<=right)
{
int mid = (left + right) / 2;
if (g[mid] == k)
{
printf("找到了,下标是:%d\n",mid);
flag = 1;
break;
}
else if (g[mid] < k)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
if (flag == 0)
{
printf("找不到\n");
}
return 0;
}
4. goto语句🤞
C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。 从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。 但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。
例如:一次跳出两层或多层循环。 多层循环这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环。
随意滥用goto语句可能引发错误:
#include<stdio.h>
int main()
{
again:
printf("hehe");
goto again;
return 0;
}
程序死循环的打印“hehe”了
goto语言真正适合的场景如下:👇
for(...)
for(...)
{
for(...)
{
if(disaster)
goto error;
}
}
…
error:
if(disaster)
// 处理错误情况
如果需要跳出多层循环,就需要用到goto语句了
goto语句只能在一个函数内部跳转,不能跨函数跳转,下面为错误案例:👇
使用goto语句写一个关机程序😊
1.程序运行起来后,1分钟内电脑关机
2.如果输入:我是猪,就取消关机
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char input[20];
system("shutdown -s -t 60");
again:
printf("请注意,你的电脑将在1分钟内关机,如果输入:我是猪,就取消关机\n");
scanf("%s", input);
if (strcmp(input, "我是猪") == 0)
{
system("shutdown -a");
}
else
{
goto again;
}
return 0;
}
不使用goto语句的写法:👇
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char input[20];
system("shutdown -s -t 60");
while(1)
{
printf("请注意,你的电脑将在1分钟内关机,如果输入:我是猪,就取消关机\n");
scanf("%s", input);
if (strcmp(input, "1") == 0)
{
system("shutdown -a");
break;
}
}
return 0;
}
总结:这篇文章主要写的是C语言中的分支和循环语句的使用方法,后期将继续写关于C语言的文章。如果我写的有什么的不好之处,请在文章下方给出你宝贵的意见。如果觉得我写的好的话请点个赞赞和关注哦~😘