第二章分支与循环语句
2.分支与循环语句
分支语句
- if
- switch
循环语句
- while
- do while
- for
goto语句
2.1分支语句(选择结构)
2.1.1 什么是选择?
例:如果你努力,也许会成功。如果你不努力,你永远不会成功。这就是选择
2.1.2 if语句
if语句语法结构:
//单分支 if 语句
语法结构:
if(条件判断表达式)
语句;
//多分支 if-else 语句
if(条件判断表达式)
语句1;
else
语句2;
if(条件判断表达式1)
语句1;
else if(条件判断表达式2)
语句2;
else
语句3;
例:
#include <stdio.h>
//单分支
int main()
{
int x = 2;
if (x = 2)
{
printf("%d\n", x);
}
return 0;
}
//多分支
//if-else
int main()
{
int x = 0;
scanf("%d", &x);
if (x >= 0)
{
printf("正数");
}
else
{
printf("负数");
}
return 0;
}
//else-if
int main()
{
int x = 0;
scanf("%d", &x);
if (x <= 40)
{
printf("差!\n");
}
else if (x <= 60)
{
printf("良");
}
else if (x <= 100)
{
printf("优");
}
else
{
printf("error");
}
return 0;
}
如果条件判断表达式为真,则语句执行。
C语言中何为真假?
真:非0的数 假:0
2.2 switch语句
switch也是一种多分支语句,常用于解决多分支的问题。
如:
输入one,输出1
输入two,输出2
输入three,输出3
输入four,输出4
输入five,输出5
因为用else if的形式写太复杂,所以用不一样的语法。即switch语句
switch语法结构:
switch(表达式)
{
case 常量表达式1: 语句1;break;
case 常量表达式2: 语句2;break;
'
'
'
case 常量表达式n: 语句n;break;
default: 语句n+1;
}
2.2.1 switch语句中的break
在switch语句中,没法直接实现实现,搭配break才能真正实现分支。
如:
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期一");
break;
case 2:
printf("星期二");
break;
case 3:
printf("星期三");
break;
case 4:
printf("星期四");
break;
case 5:
printf("星期五");
break;
case 6:
printf("星期六");
break;
case 7:
printf("星期日");
break;
}
return 0;
}
有时需求改变:
1.输入1-5,输出工作日
2.输入6-7,输出双休日
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日");
break;
case 6:
case 7:
printf("双休日");
break;
}
return 0;
}
break作用:实际上就是跳出循环。
编程书写:
在最后一个case后面加上break,避免后期修改,忘记加上,引起问题。(好习惯)
2.2.2 default子句
如果表达式的值与case标签的值都对不上,那程序将会执行default,每个switch语句只能出现一条default子句。
#include <stdio.h>
int main()
{
int i = 9;
switch (i)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("打工!");
break;
case 6:
case 7:
printf("休息!");
break;
default:
printf("error");
break;
}
return 0;
}
编程书写:
每个switch语句都写上一条default,甚至后面还可以跟上break。(好习惯)
2.3循环语句
while
do while
for
2.3.1 while语句
在前面我们已经掌握了if语句,但if语句只能执行一次,在生活中有时候一件事情需要做很多次,所以引入了while语句,实现循环。
while(表达式)
循环体语句;
例:打印1-5的数字
#include <stdio.h>
int main()
{
int i = 1;
while (i < 6) {
printf("%d ", i);
i++;
}
return 0;
}
上面的代码部分即为while语句的基本语法。
- while语句中break和continue
break:
#include <stdio.h>
int main()
{
int x = 0;
while (x < 6)
{
if (x == 3)
{
break;
}
printf("%d ", x);
x++;
}
return 0;
}
打印结果:0 1 2
总结:
break在while中的作用:
break在while循环中,只要一遇到break,后面的所有循环终止。
接下来介绍continue
continue:
int main()
{
int x = 0;
while (x < 6)
{
if (x == 3)
{
continue;
}
printf("%d ", x);
x++;
}
return 0;
}
打印结果:0 1 2
continue后没有执行后面的x++,导致打印到0 1 2 就死循环了
总结:
continue在while中的作用:
continue是来终止本次循环的,在本次循环continue后的代码不再执行,
直接跳到了while语句中判断部分,进行下一次循环的判断。
再看几个代码:
#include <stdio.h>
//代码1
int main()
{
char ch = 0;
while ((ch = getchar()) != EOF) //说明一下EOF是-1,判断是不是字符
outchar(ch);
return 0;
}
这里的代码适当的修改是可以用来清理缓冲区的.
#include <stdio.h>
//代码2
int main()
{
char ch = '\0';
while ((ch = getchar()) != EOF)
{
if (ch < '0' || ch > '9')
continue;
putchar(ch);
}
return 0;
}
//作用:只打印数字字符,跳过其他字符。
getchar:字符输入函数,功能是从键盘上输入字符。
putchar:字符输出函数,功能是输出字符。
2.3.2 for循环
for语法结构:
for(表达式1;表达式2;表达式3)
循环体语句;
表达式1:
表达式1为初始化部分,用来进行循环变量赋值。
表达式2:
表达式2为条件判断部分,用来控制循环条件。
表达式3:
表达式3为调整部分,用来控制循环变量递增或递减。
实际应用:
使用for循环,打印1-5的数字。
#include <stdio.h>
int main()
{
for (int i = 1; i <= 5; i++)
{
printf("%d ", i);
}
return 0;
}
这边我们可以对比以下while循环和for循环:
#include <stdio.h>
//使用while循环,实现相同的功能
int main()
{
int i = 0; //循环变量初始化部分
while (i < 5) //条件判断部分
{
printf("%d ",i);
i++; //调整部分
}
}
#include <stdio.h>
//使用for循环,实现相同功能
int main()
{
for (int i = 0; i < 5; i++)
{
printf("%d ", i);
}
return 0;
}
总结:
while循环依然需要有循环的三个必须条件,但受于风格问题,使得三个部分偏离较远,需要修改的时候查找不够方便和集中。所以for的风格更好一些,使用的多些。
- for循环中的break和continue
在for循环中也可以出现break和continue,但意义和在while循环中是一样的。
但略微还是有些差异,看以下代码
//代码1
#include <stdio.h>
int main()
{
int x = 3;
for (x = 0; x <= 5; x++)
{
if (x == 3)
{
break;
}
printf("%d ", x);
}
return 0;
}
//代码2
#include <stdio.h>
int main()
{
int x = 3;
for (x = 0; x <= 5; x++)
{
if (x == 3)
{
continue;
}
printf("%d ", x);
}
return 0;
}
代码1打印结果:0 1 2
代码2打印结果:0 1 2 4 5
- for循环的循环控制变量
小小的建议:不可以在循环体内修改循环变量的值,防止循环失控。建议循环变量的取值用’前闭后开区间’写法。
//前闭后开区间写法
int i = 0;
for ( i=1; i<5; i++)
//前后皆为闭区间
for( i=1; i<=4; i++)
- 一些for循环的变种
#include <stdio.h>
//代码1
int main()
{
for (;;) //for循环中的初始化部分、条件判断部分和调整部分是可以省略的,但不建议初学者使用,容易出问题。
{
printf("Hello World!");
}
return 0;
}
#include <stdio.h>
//代码2
int main()
{
int num = 0; //计数
int x = 0;
int y = 0;
//请问这里一共打印多少次Hello World ?
for (x = 1; x < 5; x++)
{
for (y = 1; y < 5; y++)
{
printf("Hello World!\n");
num++;
}
printf("%d",num);
}
return 0;
}
#include <stdio.h>
//代码3
int main()
{
int x = 1;
int y = 1;
//请问这里一共打印多少次Hello World ?
for (; x < 5; x++)
{
for (; y < 5; y++)
{
printf("Hello World!\n");
}
}
return 0;
}
#include <stdio.h>
//代码4
int main()
{
int x = 0;
int y = 0;
//使用多余一个变量控制循环
for (x = 1, y = 3; x < 5 && y>0; x++, y++)
{
printf("Hello world\n");
}
return 0;
}
回答一下以上问题:
代码2:共打印16次Hello World!。
代码3:共打印4次Hello World!
代码3的讲解:因为y没有在for()中初始化,导致y++到5的时候,尽管x++,y也不会再执行printf
- 一道笔试题
#include <stdio.h>
int main()
{
int i = 0;
int k = 0;
for(i =0,k=0; k=0; i++,k++) //请问这里循环几次?
k++;
return 0;
}
这里其实循环0次,循环中的条件判断部分为k=0,=为赋值运算符,如果是k==0,会循环1次。
2.3.3 do-while循环
do-while语法结构:
do
循环体语句;
while(表达式);
- do-while语句特点
无论条件如何,do-while语句首先执行一次循环体语句组,然后再判断条件的真假。而while语句当条件表达式的值为非0,才执行循环体,因此while循环可能一次也不执行。
#include <stdio.h>
int main()
{
int x = 0;
do
{
printf("Hello World\n");
} while (x > 0);
return 0;
}
- do-while语句中的break和continue
#include <stdio.h>
//代码1
int main()
{
int x = 5;
do
{
if (x == 3)
break;
printf("%d ", x);
x--;
} while (x > 0);
return 0;
}
#include <stdio.h>
//代码2
int main()
{
int x = 5;
do
{
if (x == 3)
continue;
printf("%d ", x);
x--;
} while (x > 0);
return 0;
}
2.4练习
-
计算 n的阶乘。
-
计算 1!+2!+3!+……+10!
-
在一个有序数组中查找具体的某个数字n。(讲解二分查找)
-
编写代码,演示多个字符从两端移动,向中间汇聚。
-
编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则
提示登录成,如果三次均输入错误,则退出程序。
2.4.1练习代码参考
#include <stdio.h>
//第一题
int main()
{
int i = 0;
int n = 0;
int sum = 1;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
sum *= i;
}
printf("%d的阶乘为%d\n", n, sum);
return 0;
}
#include <stdio.h>
//第二题
int main()
{
int i = 0;
int n = 0;
int ret = 1;
int sum = 0;
for ( n = 1; n <= 10; n++)
{
int ret = 1;
for (i = 1; i <= n; i++)
{
ret *= i;
}
sum += ret;
}
printf("10!为%d\n", sum);
return 0;
}
#include <stdio.h>
//第三题
int main() //二分查找法(折半查找法)
{
int left = 0;
int mid = 0;
int n = 0;
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int right = sizeof(arr) / sizeof(arr[0]) - 1;
scanf("%d", &n);
while (left <= right)
{
mid = (left + right) / 2;
if (arr[mid] > n)
{
right = mid - 1;
}
else if (arr[mid] < n)
{
left = mid + 1;
}
else
{
printf("找到了,它在数组下标为%d上",mid);
break;
}
}
if (left > right)
{
printf("抱歉,没有找到您要的数字");
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <windows.h> //下面Sleep函数和system使用时需要引用该头文件
//第四题 -- while循环
int main()
{
char arr1[] = "############";
char arr2[] = "Hello World!";
int left = 0;
int right = strlen(arr2) - 1;
while (left <= right)
{
arr1[left] = arr2[left];
arr1[right] = arr2[right];
printf("%s\n", arr1);
Sleep(1000); //休眠1秒 Sleep函数单位为毫秒
system("cls"); //清空屏幕
left++;
right--;
}
printf("%s\n", arr1);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <windows.h> //下面Sleep函数和system使用时需要引用该头文件
//第四题 - for循环
int main()
{
char arr1[] = "############";
char arr2[] = "Hello World!";
int left = 0;
int right = strlen(arr2) - 1;
for(left = 0, right = strlen(arr2) - 1; left<=right; left++,right--)
{
arr1[left] = arr2[left];
arr1[right] = arr2[right];
printf("%s\n", arr1);
Sleep(1000); //休眠1秒 Sleep函数单位为毫秒
system("cls"); //清空屏幕
}
printf("%s\n", arr1);
return 0;
}
#include <stdio.h>
#include <string.h>
//第五题
int main()
{
char password[20] = "1234567890"; //假设密码为1234567890
int i = 0;
for (i = 0; i < 3; i++)
{
printf("请输入你的密码:>");
scanf("%s", password);
if (strcmp(password, "1234567890") == 0) //字符串比较不能用 == ,应该使用strcmp
{
printf("输入正确!\n");
break;
}
else
{
printf("输入错误,请重新输入!\n");
}
}
if (i == 3)
{
printf("输入三次密码均错误,将退出程序!");
}
return 0;
}
2.4.2 猜数字游戏
//猜数字游戏
//游戏规则:
//1.选择1就开始游戏,选择0就退出游戏
//2.如果数字猜大了,就会提示猜大了
//3.如果数字猜小了,就会提示猜小了
#include <stdio.h>
#include <stdlib.h> //rand,srand函数使用时需要引用该头文件
#include <time.h> //使用time函数需引用该头文件
void menu();
void game();
int main()
{
int input = 0;
do
{
menu(); //菜单函数
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game(); //游戏函数
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择:>");
printf("\n");
break;
}
} while (input);
}
void menu()
{
printf("*****************************\n");
printf("********** 1.play ***********\n");
printf("********** 0.exit ***********\n");
printf("*****************************\n");
}
void game()
{
int guess = 0;
srand((unsigned int)time(NULL)); //设置rand的初始范围
//srand是用来设置rand函数初始范围0-RAND_MAX
//time函数是用来引用时间戳。时间戳:引用函数的时间减去计算机初始时间
//time函数类型为unsigned int,暂时不需要参数所以给NULL
//rand函数提供了一个随机数,rand的初始范围为0-32767
int Num = rand()%100+1; //%100的范围为0-99, +1后范围就为1-100
while (1) //设置个死循环
{
printf("请输入所猜的数字:>");
scanf("%d", &guess);
if (Num < guess)
{
printf("猜大了!\n");
}
else if (Num > guess)
{
printf("猜小了!\n");
}
else
{
printf("恭喜猜对!\n");
break;
}
}
}
2.5 goto语句
C语言给我们提供了可随意滥用的 goto语句和标记跳转的标号。
从理论上说 goto语句是没必要的,实践中没goto语句也可以很容易写出代码。
但在某些情况下还是用的上的,最常见的就是在某些深层的结构的处理过程
比如:一次跳出两层循环或者多个循环,这是break给不了的,break只能从最内层跳出上一层的循环。
goto例子:
#include <stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 2; i++)
{
if (i == 2)
{
goto end;
}
printf("Hello ");
}
end:
printf("World!\n");
return 0;
}
注意:goto语句与其跳转的标签处必须在同一个函数内
- 一个关机程序
//循环写法
#include <stdio.h>
#include <stdlib.h> //strcmp
#include <string.h> //system
int main()
{
char input[20] = { 0 };
system("shutdown -s -t 60"); //system函数-执行系统命令滴 关机倒计时60秒
while (1)
{
printf("请输入我真帅,否则你的电脑将在一分钟之内关机\n请输入:");
scanf("%s", input);
if (strcmp(input, "我真帅") == 0)
{
system("shutdown -a"); //取消关机
break;
}
}
return 0;
}
//goto语句写法
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char input[20] = { 0 };
system("shutdown -s -t 60");
again:
printf("请输入我真帅,否则你的电脑将在一分钟之内关机\n请输入:");
scanf("%s", input);
if (strcmp(input, "我真帅") == 0)
{
system("shutdown -a");
}
else
{
printf("输入错误,请重新输入\n");
goto again;
}
return 0;
}
shutdown操作命令:
shutdown -a 取消关机
shutdown -s 关机
shutdown -f 强行关闭应用程序
shutdown -m \计算机名 控制远程计算机
shutdown -i 显示“远程关机”图形用户界面,但必须是Shutdown的第一个参数
shutdown -l 注销当前用户
shutdown -r 关机并重启
shutdown -s -t 时间 设置关机倒计时
shutdown -r -t 时间 设置重新启动倒计时
shutdown -h 休眠
2.6补充练习
//输入三位整数,按从大到小输出
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
int c = 0;
int d = 0;
scanf("%d%d%d", &a, &b, &c);
if (a < b)
{
d = a;
a = b;
b = d;
}
if (a < c)
{
d = a;
a = c;
c = d;
}
if (b < c)
{
d = b;
b = c;
c = d;
}
printf("%d%d%d",a, b, c);
return 0;
}
//给定两个数,求这两个数的最大公约数
#include <stdio.h>
int main()
{
int m = 0;
int n = 0;
int min = 0;
scanf("%d%d", &m, &n);
if (m < n)
min = m;
else
min = n;
while (1)
{
if (m % min == 0 && n % min == 0)
break;
else
min--;
}
printf("最大公因数为%d", min);
return 0;
}
//辗转相除法
#include <stdio.h>
int main()
{
int m = 0;
int n = 0;
int min = 0;
scanf("%d%d", &m, &n);
while (m%n)
{
min = m % n;
m = n;
n = min;
}
printf("最大公因数为%d", min);
return 0;
}
//打印1000年-2000年之间的闰年
//闰年:1.能被4整除,不能被100整除 2.能被400整除
#include <stdio.h>
int main()
{
int year = 0;
for (year = 1000; year <= 2000; year++)
{
if (year % 4 == 0 && year % 100 != 0)
{
printf("%d ", year);
}
else if (year % 400 == 0)
{
printf("%d ", year);
}
else
continue;
}
return 0;
}
//打印100-200之间的素数
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
for (i = 100; i <= 200; i++)
{
for (j = 2; j < i; j++)
{
if (i % j == 0)
break;
}
if (i == j)
{
printf("%d ", i);
}
}
return 0;
}
//优化版
// x = a * b
// a和b之间一定至少有一个 <= x的开平方
// 100 = 50*2 = 25*4 = 10*10
#include <stdio.h>
#include <math.h> sqrt开平方函数,使用时需引用math.h头文件
int main()
{
int i = 0;
int j = 0;
for (i = 101; i <= 200; i+=2)
{
int sign = 1; //假设i为素数
for (j = 2; j <= sqrt(i); j++)
{
if (i % j == 0)
sign = 0;
break;
}
if (sign == 1)
printf("%d ", i);
}
return 0;
}
配套练习:
C语言练习题110例(一)
C语言练习题110例(二)
C语言练习题110例(三)
C语言练习题110例(四)
C语言练习题110例(五)
C语言练习题110例(六)
C语言练习题110例(七)
C语言练习题110例(八)
C语言练习题110例(九)
C语言练习题110例(十)
C语言练习题110例(十一)