switch 语句是⼀种特殊形式的if…else 结构,⽤于判断条件有多个结果的情况。
表达方式如下:
switch (expression)
{
case value1: statement
case value2: statement
default: statement
}
上面代码中,根据表达式 expression 不同的值,执行相应的case分⽀。如果找不到对应的值,就执行default 分支。
• switch 后的 expression 必须是整型表达式
• case 后的值,必须是整形常量表达式
输入任意⼀个整数值,计算除3之后的余数如果
使用if语句完成,如下:
#include
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
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;
}
上述的代码中,我们要注意的点有:
1. case 和后边的数字之间必须有空格
2. 每一个 case 语句中的代码执行完成后,需要加上 break ,才能跳出这个switch语句。
switch 语句中 break 语句是⾮常重要的,能实现真正的分支效果。
break 也不是每个 case 语句都得有,这就得根据实际情况来看了。如下:
练习:
输⼊⼀个1~7的数字,打印对应的星期⼏
例如:
输⼊:1 输出:星期⼀
输⼊:2 输出:星期⼆
输⼊:3 输出:星期三
输⼊:4 输出:星期四
输⼊:5 输出:星期五
输⼊:6 输出:星期六
输⼊:7 输出:星期天
参考代码如下:
#include
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;
}
return 0;
}
如果需求发生变化,变为:
1. 输入1-5,输出的是“工作日”;
2. 输⼊6-7,输出“休息日”
那参考代码如下:
#include
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;
}
return 0;
}
上面的练习中,我们发现应该根据实际的情况,来在代码中觉得是否使用 break ,或者在哪里使用break ,才能正确完成实际的需求。
在使用 switch 语句的时候,我们经常可能遇到一种情况,比如 switch 后的表达式中的值无法匹配代码中的 case 语句的时候,这时候要不就不做处理,要不就得在 switch 语句中加入default 子句。
switch (expression)
{
case value1: statement
case value2: statement
default: statement
}
当switch 后边的 expression 的结果不是 value1 ,也不是 value2 的时候,就会执行default 子句。
比如前面做的打印星期的练习,如果 day 的输入不是1~7的值,如果我们要提示:输入错误,则可以这样完成代码:
#include
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;
}
在 switch 语句中 case 语句和 default 语句是没有顺序要求的,只要你的顺序是满足实际需求的就可以。不过我们通常是把 default 子句放在最后处理的。
if(表达式)
语句;
#include
int main()
{
if(1)
printf("hehe\n"); //if后边条件满⾜,打印⼀次hehe
return 0;
}
while(表达式)
语句;//如果循环体想包含更多的语句,可以加上⼤括号
#include
int main()
{
while(1)
printf("hehe\n"); //while后边的条件满⾜,死循环的打印hehe
return 0;
}
区别就是while语句是可以实现循环效果的。
练习:
在屏幕上打印 1~10 的值
参考代码:
#include
int main()
{
int i = 1;
while(i<=10)
{
printf("%d ", i);
i = i+1;
}
return 0;
}
for(表达式1; 表达式2; 表达式3)
语句;
表达式1 用于循环变量的初始化
表达式2 用于循环结束条件的判断
表达式3 用于循环变量的调整
首先执行 表达式1 初始化循环变量,接下来就是执行 表达式2 的判断部分, 表达式 2 的结果,如果==0,则循环结束; 表达式2 的结果如果!=0则执行循行环语句,循环语句执行完后,再去执行表达式 3 ,调整循环变量,然后再去 表达式2 的地方执行判断, 表达式2 的结果是否为0,决定循环是否继续。
整个循环的过程中,表达式1初始化部分只被执行1次,剩下的就是表达式2、循环语句、表达式3在循环。
练习:在屏幕上打印1~10的值
参考代码:
1 #include <stdio.h>
2
3 int main()
4 {
5 int i = 0;
6 for(i=1; i<=10; i++)
7 {
8 printf("%d ", i);
9 }
10
11 return 0;
12 }
for 和 while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是 for 循环的三个部分非常集中,便于代码的维护,而如果代码较多的时候 while 循环的三个部分就比较分散,所以从形式上 for 循环要更优⼀些。
在循环语句中 do while 语句的使用最少,它的语法如下:
do
语句;
while(表达式);
while 和 for 这两种循环都是先判断,条件如果满⾜就进⼊循环,执⾏循环语句,如果不满足就跳出循环;
而 do while 循环则是先直接进入循环体,执行循环语句,然后再执行 while 后的判断表达式,表达式为真,就会进行下⼀次,表达式为假,则不再继续循环。
在屏幕上打印1~10的值
#include
int main()
{
int i = 1;
do
{
printf("%d ", i);
i = i + 1;
}while(i<=10);
return 0;
}
在循环执行的过程中,如果某些状况发生的时候,需要提前终止循环,这是非常常见的现象。C语言中提供了 break 和 continue 两个关键字,就是应用到循环中的.
• break 的作用是用于永久的终止循环,只要 break 被执行,直接就会跳出循环,继续往后执行。
• continue 的作用是跳过本次循环 continue 后边的代码,在 for 循环和 while 循环中有所差异的。
#include
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 外的第⼀层循环就终止了。
那以后我们在循环中,想在某种条件下终止循环,则可以使用 break 来完成我们想要的效果。
continue 是继续的意思,在循环中的作用就是跳过本次循环中 continue 后边的代码,继续进行下⼀次循环的判断。
上面的代码,如果把 break 换成 continue 会是什么结果呢?
#include
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 循环中的 break ⼀样, for 循环中的 break 也是⽤于终止循环的,不管循环还需要循环多少次,只要执⾏到了 break ,循环就彻底终止,我们上代码:
#include
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
break;
printf("%d ", i);
}
return 0;
}
break 的作用是永久的终止循环,未来我们在某个条件发生的时候,不想再继续循环的时候,就可以使用break 来完成
上面的代码,如果把 break 换成 continue 会是什么结果呢?
#include
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
continue;//这⾥continue跳过了后边的打印,来到了i++的调整部分
printf("%d ", i);
}
return 0;
}
所以在 for 循环中 continue 的作用是跳过本次循环中 continue 后的代码,直接去到循环的调整部分。未来当某个条件发生的时候,本次循环无需再执行后续某些操作的时候,就可以使用continue 来实现。
在这里我们也可以对比⼀下 while 循环和 for 循环中 continue 的区别:
do.while 语句中的 break 和 continue 的作用和 while 循环中几乎⼀模⼀样,大家下来可以自行测试并体会
#include
int main()
{
int i = 1;
do
{
if(i == 5)
break;
printf("%d ", i);
i = i + 1;
}while(i<=10);
return 0;
}
#include
int main()
{
int i = 1;
do
{
if(i == 5)
continue;
printf("%d ", i);
i = i + 1;
}while(i<=10);
return 0;
}
前面学习了三种循环 while , do while , for ,这三种循环往往会嵌套在⼀起才能更好的解决问题,就是我们所说的:循环嵌套,这⾥我们就看⼀个例子。
找出100~200之间的素数,并打印在屏幕上。
注:素数又称质数,只能被1和本身整除的数字。
1. 要从100~200之间找出素数,首先得有100
~200之间的数,这里可以用循环使用
2. 假设要判断i是否为素数,需要拿2~i-1之间的数字去试除i,需要产生2i-1之间的数字,也可以使用循环解决.
3. 如果2~i-1之间有数字能整除i,则i不是素数,如果都不能整除,则i是素数。
#include
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;
}
C语言提供了⼀个函数叫 rand,这函数是可以生成随机数的,函数原型如下所示:
1 int rand (void);
rand函数会返回⼀个伪随机数,这个随机数的范围是在0~RAND_MAX之间,这个RAND_MAX的大小是依赖编译器上实现的,但是⼤部分编译器上是32767。
rand函数的使用需要包含⼀个头文件是:stdlib.h
那我们就测试⼀下rand函数,这里多调用几次,产生5个随机数:
#include
#include
int main()
{
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
return 0;
}
我们可以看到虽然一次运行中产生的5个数字是相对随机的,但是下⼀次运行程序生成的结果和上⼀次⼀模⼀样,这就说明有点问题。
如果再深入了解⼀下,我们就不难发现,其实rand函数生成的随机数是伪随机的,伪随机数不是真正的随机数,是通过某种算法生成的随机数。真正的随机数的是无法预测下⼀个值是多少的。而rand函数是对⼀个叫“种子”的基准值进行运算生成的随机数。
之所以前面每次运行程序产生的随机数序列是⼀样的,那是因为rand函数生成随机数的默认种子是1。
如果要生成不同的随机数,就要让种子是变化的。
C语言中又提供了⼀个函数叫 srand,用来初始化随机数的生成器的,srand的原型如下:
1 void srand (unsigned int seed);
程序中在调用 rand 函数之前先调用 srand 函数,通过 srand 函数的参数seed来设置rand函数生成随机数的时候的种子,只要种子在变化,每次生成的随机数序列也就变化起来了。
那也就是说给srand的种子是如果是随机的,rand就能生成随机数;在生成随机数的时候又需要⼀个随机数,这就矛盾了。
在程序中我们⼀般是使⽤程序运行的时间作为种子的,因为时间时刻在发生变化的。
在C语言中有⼀个函数叫 time ,就可以获得这个时间,time函数原型如下:
1 time_t time (time_t* timer);
time 函数会返回当前的日历时间,其实返回的是1970年1月1日0时0分0秒到现在程序运行时间之间的差值,单位是秒。返回的类型是time_t类型的,time_t 类型本质上其实就是32位或者64位的整型类型。
time函数的参数 timer 如果是非NULL的指针的话,函数也会将这个返回的差值放在timer指向的内存中带回去。
如果 timer 是NULL,就只返回这个时间的差值。time函数返回的这个时间差也被叫做:时间戳。
time函数的时候需要包含头文件:time.h
//VS2022 上time_t类型的说明
#ifndef _CRT_NO_TIME_T
#ifdef _USE_32BIT_TIME_T
typedef __time32_t time_t;
#else
typedef __time64_t time_t;
#endif
#endif
typedef long __time32_t;
typedef __int64 __time64_t;
1
如果只是让time函数返回时间戳,我们就可以这样写:
1 time(NULL);//调⽤time函数返回时间戳,这⾥没有接收返回值
那我们就可以让生成随机数的代码改写成如下:
#include
#include
#include
int main()
{
//使⽤time函数的返回值设置种⼦
//因为srand的参数是unsigned int类型,我们将time函数的返回值强制类型转换
srand((unsigned int)time(NULL));
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
return 0;
}
(注:截图只是当时程序运行的结果,你的运行结果不一定和这个⼀样)
srand函数是不需要频繁调用的,⼀次运行的程序中调用一次就够了。
如果我们要生成0~99之间的随机数,方法如下:
1 rand() % 100;//余数的范围是0~99
1 rand() % 100;//余数的范围是0~99
1 rand()%100+1;//%100的余数是0~99,0~99的数字+1,范围是1~100
如果要生成100~200的随机数,方法如下:
100 + rand()%(200-100+1)
//余数的范围是0~100,加100后就是100~200
所以如果要生成a~b的随机数,方法如下:
1 a + rand()%(b-a+1)
参考代码:
#include
#include
#include
void game()
{
int r = rand()%100+1;
int guess= 0;
while(1)
{
printf("请猜数字>:");
scanf("%d", &guess);
if(guess < r)
{
printf("猜⼩了\n");
}
else if(guess > r)
{
printf("猜⼤了\n");
}
else
{
printf("恭喜你,猜对了\n");
break;
}
}
}
void menu()
{
printf("***********************\n");
printf("****** 1. play ******\n");
printf("****** 0. exit ******\n");
printf("***********************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch(input)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
}while(input);
return 0;
}
还可以加上猜数字的次数限制,如果5次猜不出来,就算失败.
#include
#include
#include
void game()
{
int r = rand() % 100 + 1;
int guess = 0;
int count = 5;
while (count)
{
printf("\n你还有%d次机会\n", count);
printf("请猜数字>:");
scanf("%d", &guess);
if (guess < r)
{
printf("猜⼩了\n");
}
else if (guess > r)
{
printf("猜⼤了\n");
}
else
{
printf("恭喜你,猜对了\n");
break;
}
count--;
}
if (count == 0)
{
printf("你失败了,正确值是:%d\n", r);
}
}
void menu()
{
printf("***********************\n");
printf("****** 1. play ******\n");
printf("****** 0. exit ******\n");
printf("***********************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}