分支与循环2
首先,分支语句有两种: if 语句和 switch 语句。 循环语句有三种:while,do while;for
PS: getchar() 和 putchar() 函数的用法:
getchar()是从缓冲区读取一个字符,(注意是一个字符)当缓冲区存在字符时,getchar就会自动读取一个字符,如果缓冲区没有字符时,getchar就会等待我们输入字符供其读取;putchar的作用则与之对应,是用于输出一个字符(同样是一个字符)。如下:一开始缓冲区内没有字符,需要等待我们人工输入字符,输入字符a后 打印字符a
如下,利用while循环使用 getchar() 和 putchar(),我们输入字符,就打印字符,这段代码在字面上的意义是只有读取到 EOF 字符时,才会结束本次循环,但实际操作却不是这样,在输入EOF字符后,仍然会继续读取和输出
原因在于,getchar()函数在读取字符时,是一个一个读取的,因此依次读取 E、O、F并依次打印出来,并不会按照代码的字面意思导致遇到 EOF就停止循环。要使该循环停下来,需要键入 Ctrl+Z,这样,就会使系统读取到 EOF,(EOF= End Of File 文件结束标志)
1、 for 循环
实际上C语言的三种循环:while,do while,和for是早期设计C语言是设计好的,在实际应用中,一种循环语法就可以解决问题,while循环的缺点在于 循环的 初始化、判断、调整 三部分是隔开的,这就不便于后续的修改,for 循环语句可以很好地解决这个问题。
for循环的语法: for (表达式1;表达式2;表达式3)
循环语句
首先for循环中三个表达式用分号隔开,另外:表达式1 为初始化部分,用于初始化循环变量,表达式2 为条件判断部分,用于判断循环什么时候终止,表达式3 为调整部分,用于循环条件的调整。
以下是用for循环实现的打印从1~10的数字
通过观察 for语句的执行流程图可以看出
表达式1 只会被执行一次,最初将其初始化后就不再执行;
同时,在 for 循环内部嵌套一个 if 语句,增加对 break和continue 函数的理解,首先是break:
因为 break 是终止本次循环,因此打印到4后就不再打印。
continue的作用是结束本次循环,但不终止大循环
2、关于for循环一些循环控制变量的建议
(1)不可以在for循环的循环体内修改循环变量,不然循环可能失去控制,如下所示:
(2)建议for循环的写法采用前闭合后开区间的写法,这一条可以举例说明,如下:
for (i=0;i<10;i++) ---> 这就是 前闭合后开区间的写法(建议这种写法)
for (i=0;i<=9;i++) ---> 这就是 前后都是闭合区间的写法
虽说从正确性的角度来说,两种写法都可以,但是上一中写法中的 10 更加鲜明,具备了某种意义,比如:10次循环;
3、for 循环的变种
(1)for语句的 标准形式是:for(初始化、判断、调整)--->也可进行一次变换: for( ; ; )
这样的语句,就可以形成一个死循环:这是因为如果for语句省略了判断条件,那么就相当于判断条件恒为真。另外,刚开始写代码时,不建议随便省略判断条件。
举例说明随意省略的后果:
左边的展示的是没有省略的 for 语句,在不省略的 for 语句的情况下,i 的 for 语句循环内嵌套了一个 j 的for语句,两个循环都是10次的循环,而每一次循环都会打印一次 “hehe” ,所以一共是打印100次。
而右边显示的循环中,由于省略了for循环语句的 初始化条件,在执行语句时,先执行 j 的循环,在 j 的for循环中,当 j 累加到 10 时,内部嵌套的 j 循环执行完毕,这时一共打印了 10 次 hehe,在执行外部的 i 循环,而此时 已经不执行内部循环了,因此就只会打印 10 次 hehe 。
这就是随意省略的后果。
(2)for循环的第二个变种:利用一个for循环,达到控制,调整多个变量的目的,如下所示:
可以看到上图中,一个for循环中控制了 2个 定义的变量,而由于for语句中的 判断条件 是&&,也就是“逻辑且”因此这个for循环也就会执行两次。
(3)关于for循环的题目
这里会出现不循环的原因是,for循环语句中的 判断语句 实际上是 赋值语句“k=0”, 也就是说每次循环到这里的时候,系统会自动给k赋值0,因此,当 i=0,k=0进入循环后, k被赋值为0,而0在C语言中代表假, 所以循环不执行。
4、do ... while () 循环
do语句的语法:
do
循环语句
while(表达式)
do语句的执行流程是:先执行循环语句,执行完一次后再判断是否要进行下一次的循环,因此 do while 语句至少要执行一次循环语句,
下面使用 do while 语句实现打印1~10,
需要注意的是:do while 语句中,do后的执行语句只能是一句话,如果需要写多条,则要用大括号括起来。同时,break的中止循环语句依然可以在 do while 中使用,并且break是中止整个循环,也就是从break开始就跳出循环,不再继续执行。,同样,continue中断语句也可以在 do while 中使用,如下所示:
在上面的代码中,执行到 continue时,跳出本次循环,这时 i =5,跳出本次循环后,继续进入 do 的大循环,继续跳出当前循环,也就是陷入了死循环,因此 结果为:1,2,3,4
5、练习
(1)计算n的阶乘
(2)计算1!+2!+3!+......+10!
(3)在一个有序数组中查找具体的数字n。
练习题的第一题答案 代码如下:
如果要改变需要计算的阶乘的 n 的数值,就在 while()里面的数值进行修改;
还可以使用输入函数写的更简单一点:
(2)至于第二个练习,将1的阶乘加到10 的阶乘,我写的代码如下:
//计算n的阶乘 #includeint JC(int n) { int i=0; int ret=1; // scanf("%d",&n); for(i=1;i<=n;i++) { ret =ret*i; } return ret; } int main(){ //int j=0; int k=0; int a=1; k=JC(a); //调用函数JC for(a=2;a<=10;a++)//注意是先调用再加1 { k=JC(a)+k; } printf("%dn",k); getchar(); //控制台显示,无实际意义 return 0; }
在上面这段代码中,我先定义了一个 用于计算阶乘的函数: JC()接着利用这个函数计算 1的阶乘到10 的阶乘之和。最后得到结果如下:
(3)在一组有序的数组中找到特定的数字n,编写 int binsearch 功能。
//有序数组中查找特定数字n #includeint main() { int arr[] = {1,2,3,4,5,6,7,8,9,10};//定义有序数组 int k=7; //假设我们要找数组中的7元素 int i=0; //这里定义i 用于表示数组的下标 int sz=sizeof(arr)/sizeof(arr[0]); // 这里是计算数组的长度 for(i=0;i PS:二分查找算法。每次都折半查找,提高查找元素的效率,如下所示,是数组内的元素及其下标:
假如,现在要求查找到特定的元素,就先找到数组元素中间的元素。方法是:将两边下标相加除以2,这就得到了 4(商4),下标为4 的元素是 5,这样就可以以此类推,查找到特定的元素。这就是二分查找算法。
二分查找算法的代码:
//有序数组中查找特定数字n #includeint main() { int arr[] = {1,2,3,4,5,6,7,8,9,10};//定义有序数组 int k = 7;//定义需要查找的元素为 7 int sz =sizeof(arr)/sizeof(arr[0]); //计算元素个数 //printf("%dn",sz); int left =0;//表示左下标从0开始 int right =sz-1;//表示右下标为元素个数减去1 int mid =(left+right)/2; //printf("%dn",right); //printf("%dn",mid); //循环体 while(left<=right){ int mid =(left+right)/2; //这里如果不重新计算中间元素,会陷入死循环 if(arr[mid] > k) { right = mid-1; //中间元素大于需要查找的元素下标,向左二分 } else if(arr[mid] < k) { left = mid+1; //中间元素小于需要查找的元素下标,向右二分 //printf("%dn",left); } else //下标与待查找元素相同 { printf("找到了,下标是:%dn",mid); break;//找到后,跳出循环 } } if(left>right){ printf("找不到n"); } return 0; } (4)练习题4:编写代码,演示多个字符从两端移动,向中间汇聚,代码如下
//演示多个字符从两端移动,向中间汇聚 //打印一句话,但是是在屏幕上从两端向中间汇集 #include#include //引用strlen的库函数 int main() { //创建数组存放需要在屏幕上打印的文字 char arr1[] = "welcome to HFUU!!!!!";//在系统内先存入 char arr2[] = "####################"; int left = 0; //int right = sizeof(arr1)/sizeof(arr1[0])-2;//数组最后会有元素“ ” int right = strlen(arr1)-1; while(left<=right){ arr2[left] = arr1[left]; arr2[right] = arr1[right]; printf("%sn",arr2); left++; right--; } return 0; } 这是最后打印的效果:
为了能够感受到动态打印的效果,可以调用 Sleep(); 函数。注意这个函数的单位是:毫秒(ms),同时使用这个函数,需要调用库函数
,再将之前打印的清空,使用函数system(); system("cls"); // 清空屏幕 改进后的代码:
#include#include //引用strlen的库函数 #include //引用Sleep()的库函数 #include //引用system()的库函数 int main() { //创建数组存放需要在屏幕上打印的文字 char arr1[] = "welcome to HFUU!!!!!";//在系统内先存入 char arr2[] = "####################"; int left = 0; //int right = sizeof(arr1)/sizeof(arr1[0])-2;//数组最后会有元素“ ” int right = strlen(arr1)-1; while(left<=right){ arr2[left] = arr1[left]; arr2[right] = arr1[right]; printf("%sn",arr2); Sleep(500); //延时0.5秒 system("cls");//清空屏幕 left++; right--; } return 0; }



