C语言do while循环
要努力丫! 人气:01、do while()循环-先执行后判断
do语句的语法
do
循环语句;
while(表达式);
此处的循环语句可能不是一条语句,而是一段代码。
示例:利用do while循环实现打印1-10
#include <stdio.h> int main() { int i = 1; do { printf("%d ",i); i++; } while (i <= 10); return 0; }
打印结果为:1 2 3 4 5 6 7 8 9 10
执行流程:
2、do while中的break以及continue
#include <stdio.h> int main() { int i = 1; do { if (i == 5) break; printf("%d ",i); i++; } while (i <= 10); return 0; }
打印结果为:1 2 3 4
将代码中的break换成continue的时候,查看运行结果,可以看到:1 2 3 4 _(4后面的光标持续闪烁),因为它会跳过continue后面的部分,直接来到while中的判断部分,判断是否<=10,满足条件,又返回回去执行do语句,但是它等于5,就会又跳过continue后面的语句,又去判断while里面的条件是否满足,满足就又进去do语句,等于5跳过continue后面的语句,如此循环往复,所以会出现光标闪烁的情况。
do语句的特点:循环至少执行一次,使用的场景有限,所以不是经常使用。
3、练习
利用循环语句(while、for、do while)来完成下面的练习。
/练习一:计算n的阶乘//
自己写的代码如下:
利用for循环语句:
n这个数字自己来键入,从1开始作乘法,每次乘的数加一,直到乘到键入的数字n为止,打印此时的mux值。
int main() { int n = 0; int i = 0; int mux = 1; scanf("%d",&n); for (i = 1; i<n; i++) { mux *= (i + 1); } printf("mux = %d ",mux); return 0; }
运行结果如下:
比如5!=1x2x3x4x5=120,测试结果正确。
5
mux = 120
利用while语句实现
int main() { int i = 0; int n = 0; int mux = 1; scanf("%d",&n); while (i < n) { i++; mux *= i; } printf("mux=%d",mux); return 0; }
测试运行结果:
8
mux=40320
利用do while语句
int main() { int i = 0; scanf("%d", &i); int mux = i; do { mux *= (i-1); i--; if (i != 1) continue; printf("mux=%d ", mux); } while ((i -1) != 0); return 0; }
测试结果如下:
6
mux=720
//练习二:计算1!+2!+ …+10!///
这里的第一个for循环里面将条件设置为m<5,意思是求1!+2!+3!+4!的值来测试一下
//其实是循环嵌套 int main() { int m = 0; int i = 0; int mux = 1; int sum = 0; for (m = 1; m < 5; m++) { for (i = 1; i <= m; i++) { mux *= i ; } //printf("mux = %d\n",mux); sum += mux; } printf("sum = %d",sum); return 0; }
运行结果为303
如何修正程序呢?在每一次求阶乘之前,都应该将mux的值置为1.
mux = 1;//在第二个for语句上面加上这条语句 //意思是在每一次求阶乘之前,让mux的初始值为1
这样程序就可以运行成功,结果为33。
但是上述代码的效率不太高,每一次计算阶乘都是从1x1!,1x2!(都是从1开始乘,直到乘到m)等开始一步一步算,但是我们知道,2!=2x1!,3!=3x2!…,所以有:
//相对于上一段代码,这段代码更高效。 int main() { int i = 0; int mux = 1; int sum = 0; for (i = 1; i <= 3; i++) { mux *= i ; sum += mux; } printf("sum = %d",sum); return 0; }
/ 练习三:在一个有序数组中查找具体的某个数字n ///
编写int binsearch(int x, int v[], int n);功能:在v[0]<=v[1]<=…<=v[n-1]的数组中查找x
题目的大意是:假如有一组数字[1 2 3 4 5 6 7 8 9 10],然后从这一组数字里面找出数字7.有个思路就是从头到尾遍历,直到找到为止。但是题目里面还有一个关键词语“有序”,如果采用从前往后遍历的方法程序处理效率就太低了。采用什么方法比较合理呢?采用二分查找比较高效一些。
第四步:这个范围它的左下标是6,右下标也是6,左右下标的平均值还是6,所以由6所确定的下标对应的元素刚好是7,就是所要找的元素。如果这时候的数字“7”还不是我们要找的数字的时候,那在这个数组里就找不到要找的元素了。
按照这种寻找元素的办法,最坏的情况下找了四次就找到了,而如果从前往后遍历的话最坏的情况下需要找10次,可见折半查找(二分查找)的效率是很高的。它所需要的查找的次数为log2n次。
这种方法就在于不断更新查找范围的左值和右值。
int main() { int arr[] = {1,2,3,4,5,6,7,8,9,10}; int k = 7;//要查找的数字 //在arr这个有序数组中查找k的值 int sz = sizeof(arr) / sizeof(arr[0]);//求出数组的元素个数以此来确定查找范围的下标右值 int left = 0; int right = sz - 1; int mid; while (left <= right) { int mid = (left + right) / 2;//第一次进来的时候,数组元素中间值是arr[4] if (arr[mid] < k) { left = mid + 1;//范围舍去左边一半,从arr[5]开始 } else if (arr[mid] > k) { right = mid - 1;//范围舍去右半边,到arr[3]结束 } else { printf("找到了,下标为:%d\n",mid); break;//找到元素之后就跳出循环 } } if (left > right) { printf("找不到\n"); } return 0; }
运行结果为:
找到了,下标为:6
如果将k值改为17,再次运行程序,运行结果为“找不到”
//练习四:编写代码,展示多个字符从两端移动,向中间汇聚
方法就是先设置一个和想要打印的字符串等长的字符串数组,全部写为*,然后用想要打印的字符串里面的字符去逐步替换数组2中的*,直到全部完整地将数组1打印出来为止。在这个过程中,左边的下标作加一操作,右边的下标作减一操作,就实现了从两端向中间移动的这个功能。
//比如打印 welcome to xi'an!!! // ******************* // 每一次打印的时候都放进去一对字符替换掉** //第一次打印:w************! //第二次打印:we**********!! #include <string.h> #include <stdio.h> int main() { char arr1[] = "welcome to xi'an!!!"; 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); left++; right--; } return 0; }
运行结果如下:
w*****************!
we***************!!
wel*************!!!
welc***********n!!!
welco*********an!!!
welcom*******'an!!!
welcome*****i'an!!!
welcome ***xi'an!!!
welcome t* xi'an!!!
welcome to xi'an!!!
将代码中加入睡眠命令以及清空屏幕命令,可以在运行结果窗口看到程序的“动态”执行效果。
#include <string.h> #include <stdio.h> #include <Windows.h> int main() { char arr1[] = "welcome to xi'an!!!"; 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(1000);//1000毫秒,也就是1秒,这样我们就可以看到它逐步打印的过程了 system("cls");//清空屏幕 left++; right--; } return 0; }
///练习五:编写代码实现模拟用户登录情景,并且只能登录三次(只允许输入3次密码),如果密码正确,则提示登录成功,如果三次均输入错误,则退出程序///
#include <string.h> #include <stdio.h> int main() { char arr[20] = { 0 }; //假设正确的密码是字符串“2022”,如何比较呢 int m = 0; for (m = 0; m < 3; m++) { printf("请输入密码:"); scanf("%s", arr); //if (arr == "2022")//这样的写法是错误的,两个字符串比较不能使用==来比较 //应该使用字符串函数strcmp if(strcmp(arr,"2022")==0) { printf("密码正确\n"); printf("进入系统"); break; } else { printf("密码错误\n"); } } if (m == 3) { printf("退出系统\n"); } return 0; }
运行结果如下:
请输入密码:2022
密码正确
进入系统
请输入密码:20201
密码错误
请输入密码:124r
密码错误
请输入密码:12345
密码错误
退出系统
4、猜数字游戏
写一个猜数字游戏,这个游戏会
自动产生一个1-100之间的随机数然后去猜一下这个数字
如果猜对了,就会输出恭喜猜对了
猜错了会告诉是猜大了还是小了,让你继续猜,直到才对为止
游戏可以一直玩,除非退出游戏
要解决这种问题,应该在调用rand函数之前调用srand函数,这样一来再次运行程序的时候就发现第一次执行的随机数字是365而不是41了,但是再多执行几次,发现每次的值都是365,这就也不对了。
这就要求srand处的参数就是随机的,是一直在发生变化的值,否则生成的随机数也会是定值。时间是一直在发生变化的,就可以把时间放进srand函数里面,这个地方传进去的实际上是时间戳。一番设置之后,发现虽然比较不一样了,但是它们之间离得很近,甚至选择的“1/0”数字太快的时候,它们甚至有可能生成的随机值还是一样的。因为srand确实应该在rand之前调用,但是随机数起点的设置只需要调用一次就可以了,不用开始一次游戏game函数调用并设置一次。在整个工程里面设置一次就行了,把它放进主函数里面就行。
修正过的:(生成的数字很随机了)srand((unsigned int)time(NULL));
(放在main函数里面)
想要生成1-100之间的随机数,可以将rand函数%100,0-32767的数字对100进行取余之后的结果是0-99,然后加一,范围就是1-100了
int random = rand()%100 +1;//%100的余数是0-99,再+1就是1-100
来吧,展示。代码如下:
#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <stdio.h> void menu() { printf("***********************\n"); printf("***********************\n"); printf("****** 1.play *******\n"); printf("********0.exit*********\n"); printf("***********************\n"); printf("***********************\n"); } void game() { //猜数字游戏,将猜数字的功能封装到这个game函数里面去 //先生成随机数,用rand函数,它需要的头文件是stdlib.h //srand(100); //srand((unsigned int)time(NULL)); //时间---时间戳,时间转换出来的一个数字 //(此时的时间相较于计算机的起始时间之间的差值,换算成以秒为单位的数字) //用time函数(需要包含头文件time.h)来获取时间戳,time函数的返回类型是time_t,而time_t是64位的整型 //srand需要的是unsigned int 类型,那就将time的类型强制转换一下 //int random = rand(); //查询资料,可以发现rand函数返回了一个0-32767之间的数字 //但是这个数字不够随机 要在调用rand之前使用srand功能去设置随机数的生成器 int random = rand() % 100 + 1;//%100的余数是0-99,再+1就是1-100 printf("%d\n", random); int guess = 0; while (1) { printf("猜数字:"); scanf("%d", &guess); if (guess < random) { printf("猜小了\n"); } else if (guess > random) { printf("猜大了\n"); } else { printf("猜对了,恭喜\n"); break; } } } int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu();//打印菜单 printf("请选择:"); scanf("%d", &input); switch (input) { case 1: //printf("猜数字\n"); game(); break; case 0: printf("退出游戏"); break; default: printf("输入错误,请重新选择"); break; } } while (input); return 0; }
运行结果如下:
加载全部内容