1.while循环
C语言提供了三种循环,while是其中一种
while语句的语法结构和if语句非常相似,但是效果不同
1.1if和while对比
if(表达式)
语句;
while(表达式)
语句;//如果循环体内想包含更多语句,可以加上大括号
不断冒出的hehe VS 只有一次性冒出的hehe

1.2while语句的执行流程

1.3while循环的实践
练习1:在屏幕上打印1-10的值

练习2:输入一个正的整数,逆序打印这个整数的每一位

进阶版:打印出每一位之和

2.for循环
2.1语法形式
for(表达式1;表达式2;表达式3)
语句;//如果循环体想包含多条语句,可以加上大括号
表达式1 用于循环变量的初始化
表达式2 用于循环结束条件的判断
表达式3 用于循环变量的调整
注意表达式用分号隔开,不是逗号!!!
语法上面支持初始化、判断、调整三个部分都可以省略不写,如果是判断部分不写,则表示判断恒成立,可能会造成死循环,eg.无穷无尽的hehe

2.2类比while循环

2.3for循环执行流程
跟while一样
先初始化循环变量 //表达式1,只执行了1次
再判断循环结束条件 //表达式2
进而执行语句 //语句
最后进行循环变量的调整 //表达式3
然后继续判断循环结束条件 //表达式2
……
练习1:在屏幕上面打印1-10的值(对比前面的while循环)

while和for在实现循环的过程中都有初始化、判断、调整这三个部分,但是for循环的三个部分非常集中,便于代码的维护,而如果代码较多的时候while循环的三个部分就比较分散,所以形式上面for循环要更优一些。
练习2:将1-100中所有3的倍数求和
算法1:(算法就是解决问题的办法)

算法2:(更简便,省去了多余的循环和判断)

while和for循环使用场景区别:是否知道循环次数
3.do-while循环
3.1语法
在循环语句中do while语句的使用最少,它的语法如下:
do
语句;
while(表达式);
while 和 for 循环都是先判断,条件如果满足就进入循环,如果不满足就跳出循环;
而do-while循环则是先进入循环体,执行循环语句,然后再执行while后的判断表达式,表达式为真,就会进行下一次,表达式为假,则不再继续循环。
至少循环1次
3.2实例
练习1:在屏幕上面打印1-10

练习2:测量出输入数据的长度
算法1:while循环写法

算法2:do-while循环写法

4.break和continue语句
在循环执行的过程中,有一个常见现象:由于某些状况发生需要提前终止循环。
C语言中提供了break和continue两个关键字,就是应用到循环中解决这个状况的
break 的作用是永久终止循环,只要break被执行,直接就会跳出循环,继续往后执行
continue 跳过本次循环中continue后面的代码,在for和while中有一定差异
4.1 while循环中的break和continue
break

continue

程序跳过了后续代码,导致数字5未被打印,同时跳过了i++和5+1=6的计算步骤。随后重新进入循环时,i的值仍为5,再次被跳过。如此循环往复,最终陷入死循环状态。
避免死循环的技巧:将循环变量i++前置–不要在continue语句后面调整循环变量

4.2 for循环中的break和continue
break

continue

由于for循环的执行流程,执行完语句后一定会去执行循环变量的调整,因此for的continue不会进入死循环。
5.循环的嵌套
5.1练习
找出100-200之间的素数,并打印在屏幕上面
素数:又称为质数,只能被1和本身整除的数字
(1)产生100-200之间的数字i
(2)判断i是否为素数:若2~i-1之间的数字能整除i,那就是素数
(3)打印素数
算法1:

算法2:假设法

6.goto语句
C语言提供了一种特别的语法,就是goto语句和跳转标号,goto语句可以实现在同一个函数内跳转到设置好的标号处。
goto语句如果使用不当,就会导致在函数内部随意乱跳转,打乱程序的执行流程;
在多层循环的代码中,如果想要快速跳出,可以使用goto。
for(;;)
{
for(;;)
{
for(;;)
{
if(disaster)
goto error;
}
}
}
error:
//…
使用break语句可以提前退出for循环,但每个break只能跳出一层循环。在嵌套三层循环的情况下,需要三个break才能完全退出。相比之下,使用goto语句能更高效地实现循环的快速退出。
关机恶搞小程序

while版本:

发送给好友教程:





7.随机数生成
学完以上知识,可以写一些有趣的代码,比如:
写一个猜数字游戏
游戏要求:
1.首先弹出玩家互动界面,提示玩家输入数字选择:1表示开始游戏,0表示退出游戏
2.系统随机生成1-100之间的整数
3.玩家进行数字猜测,系统会根据实际数值提示"过大"或"过小",直到猜中为止
4.游戏支持连续多轮游玩,无需重新启动程序
7.1随机数生成
7.1.1rand
C语言提供了一个函数叫做rand,这函数是可以生成随机数的,函数原型如下所示:
int rand(void);
rand函数会生成一个0到RAND_MAX之间的伪随机数,
RAND_MAX的具体值取决于编译器实现,但通常为32767。
rand函数的使用需要包含一个头文件:stdlib.h
多调用函数生成几次,会发现生成的随机数是有规律的:

因为rand函数生成的随机数的是伪随机的,伪随机数不是真正的随机数,而是通过某种算法生成的随机数。真正的随机数是无法预测下一个值是多少的,而rand函数是对一个叫“种子”的基准值进行运算生成的随机数。
之所以之前每次运行程序产生的随机数列是一样的,那是因为rand函数生成随机数的默认种子是1。
如果要生成不同的随机数,就要让种子变化。
7.1.2srand
C语言中又提供了一个函数叫srand,用来初始化随机数的生成器(种子)的,srand原型如下:
void srand(unsigned int seed);
程序中在调用rand函数之前先调用srand函数,通过srand函数的参数seed来设置rand函数生成随机数的时候的种子,只要种子在变化,每次生成的随机数序列也就变化起来了。
也就是说,给srand的种子如果是随机的,rand就能生成随机数;就变成为了让我生成一个随机数,先给我一个随机数,矛盾了。
7.1.3time
在程序中我们一般是使用程序运行的时间作为种子,因为时间时刻在变化。
利用函数time,就可以获得这个时间,time函数原型如下:
time_t time(time_t* timer);
time函数返回当前日历时间,具体是从1970年1月1日0时0分0秒到程序运行时刻的时间差(以秒为单位)。其返回值类型为time_t,本质上是一个32位或64位的整型数值。
time函数的参数timer如果是非NULL的指针的话,函数也会将这个返回的差值放在timer指向的内存中带过去。
如果timer是NULL,就只返回这个时间的差值。time函数返回的这个时间差也被叫做:时间戳。

time函数使用的时候需要包含头文件:time.h

此时生成的就是不可预测的随机数了。
7.1.4设置随机数的范围
0-99
rand () % 100;//余数的范围是0-99
1-100
rand () % 100 + 1
100-200
100 + rand () % (200 – 100 + 1);//余数的范围是0-100,加100后就是100-200
a-b(a和b代指的是数字)
a + rand () % (b – a + 1);
8.猜数字游戏
//猜数字游戏
#include<stdlib.h>
#include<time.h>
void game()
{
//猜数字的逻辑
//1.生成1-100之间的随机数
int r = rand() % 100 + 1;
//2.猜数字
int guess = 0;
int count = 5;
while(count)
{
printf("还剩下%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("很遗憾,失败了\\n");
}
int main()
{
srand((unsigned int)time(NULL));//设置随机数生成的基准值
int input = 0;
do {
//打印菜单
printf("———————–\\n");
printf("——-1.玩游戏——–\\n");
printf("——-0.退出游戏——\\n");
printf("———————–\\n");
printf("请选择:—>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\\n");
break;
default:
printf("选择错误,请重新选择\\n");
break;
}
} while (input);//非零就会重新进入循环
return 0;
}





