在C语言中,仅仅依靠顺序结构以及选择结构是远远不够的,还需要用到循环结构来处理复杂重复的问题。大多数应用程序都会用到循环结构,循环和顺序以及选择结构是结构化程序设计的3种基本结构,它们也是各种复杂程序的基本构成单元。
一、用While语句实现循环
While语句的一般形式为:
While(表达式)
循环语句;
其中,循环语句就是循环体,循环语句可以是一个简单的语句,还可以是复合语句,但一定是一个循环语句。执行循环体的次数是由循环条件控制的,这个循环条件就是括号中的表达式,当表达式的值为“真(非0)”时,就执行循环语句,为“假(0)”时,就不执行循环语句。
特点:先判断条件表达式,在执行循环体语句;
练习:利用while语句打印0-9;
#include <stdio.h>
int main()
{
int i;
while(i<10)
{
printf("%d\n",i);
i++;
}
return 0;
}
结果:
当然,我们在进行循环时,可能在某些特定的时候需要终止或者说是跳出循环,C语言中,常用的语句有break与continue语句。
举例:利用break跳出循环
#include <stdio.h>
int main()
{
int i = 1;
while(i<10)
{
if(5==i)
break;
printf("%d\n",i);
i++;
}
return 0;
}
结果:
break的作用就是使流程跳到循环体之外,接着执行循环体下面的语句;
注意:break语句只能用于循环语句以及switch语句种,不能单独使用;
举例:利用continue跳出循环
#include <stdio.h>
int main()
{
int i = 1;
while(i<10)
{
if(5==i)
continue;
printf("%d\n",i);
i++;
}
return 0;
}
结果:
我们能够分析发现,代码陷入了死循环,这是因为While 中添加break,直接跳出while循环。而田间continue会跳过后面的语句,也就是跳出一次循环,直接去判断部分,直接进行下次循环。
有时候并不希望终止整个循环的操作,而只希望提前结束本次循环,而接着执行下次循环,这时便用到continue语句;
举例:要求输出100-200的不能被3整除的数
#include <stdio.h>
int main()
{
int i;
for(i=100;i<201;i++)
{
if(i%3==0)
continue;
else
printf("%d ",i);
}
return 0;
}
结果:
总结:continue语句只能结束本次循环,而不能终止整个循环的执行,而break语句则是结束整个循环过程,不在判断执行循环的条件是否成立。
二、用do···While语句实现循环
除了While语句以外,C语言还提供do···while语句来实现循环;
do···while语句的形式:
do 循环语句;
While(表达式);
表达式如果为真,就上去执行do循环语句。它的作用是:do表示“做”,while用来判断循环;
特点:先执行依次指定的循环,然后判别表达式,当表达式值为真(非0)时,返回重新执行循环体语句,如此反复,知道表达式为假(0);
举例:利用do···while语句打印0-9;
#include <stdio.h>
int main()
{
int i =1;
do
{
printf("%d ",i);
i++;
}
while (i<10);
return 0;
}
结果:
三、用For语句实现循环
除了用while和do···while循环外,C语言中使用最多的循环还算是for循环,而且for循环更加灵活,不仅可以用于循环次数确定的情况,还可以用于循环次数不确定的而只给出循环结束条件的情况。
for循环的一般形式为:
for(表达式1;表达式2;表达式3)
{
循环语句;
}
括号中3个表达式的作用分别为:
表达式1:设置初始条件只执行一次,例如(i=1);
表达式2:是循环条件表达式,用来判断是否将循环继续执行下去,在每次执行循环体前都要先执行此表达式,决定是否继续执行循环;
表达式3:作为循环的调整,例如使循环标量增值,它是在循环体后被执行的;
注意:1、for循环可以同while循环进行改写;
2、for循环中,表达式1可以省略,即不设置初值,但是表达式1后面的分号不能省略,而且随意删除for循环的初始赋值,是可能要付出代价的;
3、for循环中,表达式2也可以省略,既不设置循环判断条件,这样循环将无终至的进行下去;
4、for循环中,表达式3也可以省略,但是程序设计者应该另外设法保证循环能正常结束;
5、表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式,既包含一个以上的简单表达式,中间用逗号隔开。
举例1:计算N的阶乘。未考虑溢出的问题;
#include <stdio.h>
int main()
{
int n;
printf("enter a number:\n");
scanf("%d",&n);
int i;
int sum = 1;
for(i=1;i<=n;i++)
{
sum = i*sum;
}
printf("sum=%d\n",sum);
return 0;
}
结果:
举例2:计算1!+2!+3!··· +10!
#include <stdio.h>
int main()
{
int n;
int i=1;
int sum=0;
for(n=1;n<=10;n++)
{
i*=n;
sum+=i;
}
printf("sum=%d",sum);
}
结果:
练习1:在一个有序数组中查找某个数;
常规查找分析:定义一个数组,输入一个数字,将数字与数字中的数字元素一一对比;直至输入元素与其中一个数组元素相同;
#include <stdio.h>
int main()
{
int arr[]={1,2,3,4,5,34,54,65};//定义一个数组;
int k=4;
int i;
int sz = sizeof(arr)/sizeof(arr[0]);//计算数组长度;
for(i=1;i<sz;i++)//进行一一对比;
{
if(arr[i]==k)//如果与数组元素相同,输出找到了,并且输出下标,跳出循环;
{
printf("找到了,%d",i);
break;
}
}
if(i==sz)//如果循环次数与数组长度相同,则证明没有在数组中找到输入的数字;
printf("未找到");
return 0;
}
结果:
利用二分法查找:将输入的数字与中间的数字相对比,缩小查找的范围,进而确定输入数字在数组中的下标,前提,必须是在有序数组中进行查找,有序数组即数组元素是从小到大排列的。
#include<stdio.h>
int main()
{
int arr[]={1,2,3,4,5,6,7,8,9};//定义一个数组
int sz = sizeof(arr)/sizeof(arr[0]);//计算数组长度
int left = 0;//定义左下标;
int right = sz-1;//定义右下标
int k = 4;//定义查找的数字
while(left<=right)//如果左下标小于右下标就进入循环
{
int mid =(left+right)/2;//定义中标
if(arr[mid]<k)//如果中标元素小于查找的数字就将左下标定位中标+1
left = mid+1;
else if(arr[mid]>k)//如果中标元素大于查找的数字就将右下标定位中标-1
right = mid-1;
else//如果相等,就输出下标并跳出循环
{
printf("找到了,下标是%d",mid);
break;
}
}
if(left>right)//如果经过循环后左下标大于右下标,则证明在数组中没有找到输入的数字
printf("找不到");
return 0;
}
结果:
练习2:编写代码,演示多个字符从两端移动,向中间汇聚;
#include <windows.h>//主函数中用到sleep延迟函数,需要包含相关库函数
#include <stdio.h>
int main()
{
char arr1[]= "welcome to xian!!!";//定义初始数组1
char arr2[]= "##################";//定义初始数组2
int left = 0;//定义左下标
int sz = sizeof(arr1)/sizeof(arr1[0]);//定义数组长度
int right=sz-2;//定义右下标
while(left<=right)//如果左下标小于右下标就进入循环
{
arr2[left]=arr1[left];//使数组2的左下标元素等于数组1左下标元素
arr2[right]=arr1[right];//使数组2的右下标元素等于数组1右下标元素
printf("%s\n",arr2);//输出改变后的数组2
Sleep(1000);//延迟函数
left++;//左下标加一
right--;//右下标加一
}
return 0;
}
结果:
练习3: 提示登录,如果三次均输入错误,则退出程序;
#include <stdio.h>
int main()
{
char arr1[10]={"abcdef"};//定义一个数组,即为初始密码,将后面输入的密码同其进行比较;
char arr2[10];//定义一个空数组用于存放输入的密码
int i=0;
for(i=0;i<3;i++)//设置一个循环,循环次数为3次,即设置登录的次数为3次
{
printf("请输入密码:");
scanf("%s",arr2);//输入字符串至数组2,注意数组名为数组元素的首地址
if(strcmp(arr2,arr1)==0)//比较两个字符串是否相等,不能使用等号==,而是使用一个库函数,strcmp;如果相等,返回值为0,
{
printf("登陆成功。");
break;
}
else
printf("密码错误。\n");
}
if(i==3)//如果三次都输入错误即显示退出程序
{
printf("三次密码均输入错误,退出程序\n");
}
return 0;
}
结果:
注:字符串数组的输入语句为:scanf("%s",arr2);不用取地址符,以为数组名就代表了数组元素的数组元素的首地址;
四、go···to语句
首先,如果滥用go···to语句会导致逻辑混乱,因此一定要合理使用goto语句;
goto语句即为到哪里去;
用法:
goto名字;
···
名字:执行语句;
举例:
#include <stdio.h>
int main()
{
goto xian;
printf("1");
printf("2");
xian:
printf("3");
printf("4");
return 0;
}
结果:
程序自上而下进行,遇到goto,进行跳转;
总结:本次介绍了C语言中的循环结构,讲述了三种常见的循环语句以及goto语句,难度适中,大家将举例与练习多多熟练,即可掌握相应的知识。