“教小白精通编程”系列之“C语言教程” (版权所有,不得转载,擅自抄袭转载将承担法律责任)
4. C语言教程-循环
有时我们希望某一个语句块在满足某种条件的情况下能重复执行。
比如我们要编写一个统计某门课程的学生平均成绩的程序,程序应该一直可以输入学生成绩,直到满足某个结束条件就停止输入,然后计算并输出平均成绩。
再比如我们要计算一组数的和,如1+2,1+3,…等,我们可以直接在代码里写
int s = 0 ;
s = 1+2; printf("%d\n",s);
s = 1+2+3+4; printf("%d\n",s);
但如果很多个数字,比如要计算1到100或者1到1000之间的整数之和,显然不可能将所有这些数字都这样列举出来。因此,需要一种更方便的方法重复执行这种加法运算,而不是将每次加法都写出来。即,我们可以设计这样的语句
s = s+i; //对不同的i(比如1=1,2,3,...,100)重复这个过程就可以了
C语言提供了所谓的循环语句可以帮助我们轻松完成这个工作,C语言的循环语句分为2种:while循环 和for 循环。即分别用关键while和for描述的在满足某条件情况下可以重复执行的语句。
while循环 (while Loop):
while (condition表达式)
{
body程序块
}
含义: 只要while里的condition表达式是真的,就一直重复执行body程序块。
可以用while语句写出1到100求和问题的程序如下:
//计算1到100之间的整数之和
#include <stdio>
int main(){
int sum = 0,i = 1 ;//sum保存和,i表示参与求和的数字
while(i<=100) //只要小于等于100,就执行while循环体
{ //while循环体
sum = sum +i; //可以用+=写成: sum +=i;
i = i+1; //i的值增加1,可以用自增运算符++写成i++;
}
printf("1到100之间的整数和为:%d\n",sum);
}
注:
a) C 语言中 " i++ " 就相当于" i = i+1" ,因此++称为自曾运算符。
b) "sum += i" 就相当于" sum = sum + i" 。 类似的还有: -= ,*= ,/=, %=等运算符!
还有一个变种 do-while循环,
do {
body程序块
} while(condition表达式);
含义: 只要while里得到condition表达式是真的,就一直重复执行body程序块。
可以用do-while语句写出1到100求和问题的程序如下:
//计算1到100之间的整数之和
#include <stdio>
int main(){
int sum = 0,i = 1 ;//sum保存和,i表示参与求和的数字
do
{ //循环体
sum = sum +i; //可以用+=写成: sum +=i;
i = i+1; //i的值增加1,可以用自增运算符++写成i++;
}while(i<=100); //只要小于等于100,就执行循环体
printf("1到100之间的整数和为:%d\n",sum);
}
while的2种形式是等价的,可以根据自己的喜欢选择任意一种。唯一的主要注意的是do-while的循环体至少执行1次,而while的循环体可能1次也不执行。
for循环 (for loop) :
for (init初始表达式; test测试表达式; post_proc后处理表达式)
{
循环体程序块
}
含义: 先执行init初始化表达式,然后重复下列循环:
如果"test测试表达式"真 -> 执行"循环体程序块" -> post_proc后处理表达式
直到”test测试表达式”不真。
可以用for语句”求1到100之间的整数和”
#include <stdio>
int main(){
int sum = 0;
for( int i = 1; i<= 100 ; i++) {
sum += i;
}
printf("1到100之间的整数和为:%d\n",sum);
}
break
可用于跳出for和while循环体,如同用break跳出switch语句一样,执行时如果遇到break语句就跳出整个循环。
void main(){
int sum=0,i = 0;
while (1) { //条件一直为真
n++;
if (i == 101) {
break; //遇到break语句就跳出整个循环。
}
sum +=i;
}
printf("%d\n",sum);
}
现在我们可以写一个程序,计算某门课学生成绩的平均分:
//用while语句计算成绩平均分
#include <stdio>
int main(){
float score,average_acore = 0; //average_acore表示平均成绩
int n = 0;//人数
while(1){ //条件始终满足,会一直执行
scanf("%f",&score);
if(score<0 || score>100) //逻辑或运算符||用于2个表达式
break; / /跳出循环
average_acore += score; //累加分数
n++; //等价于n = n+1;
}
average_acore /=n; //计算平均分
printf("平均分=:%f\n",average_acore);
return 0;
}
问:如何判断一个整数n是否是质数?
思考:假设n不是质数,则存在两个不是1和n的整数a和b,使得n = a*b
。
不妨设a<b
,则a不可能大于n/2。也就是说“非质数”必定存在一个介于2和n/2之间的整数a能整除n。
因此,只要用2到n/2之间的每个整数去除一下n,看看是否能整除n,就能判断n是否是质数了。
程序如下:
#include<Stdio.h>
int main(){
int n,a,m;
printf("请输入一个整数\n");
scanf("%d",&n);
m = n/2;
for (a = 2; a <= m; ++a) {
if ( n % a == 0) { // a整除n?
printf("%d 不是一个质数 ", n);
break; /* 跳出循环,不需要再检查了*/
}
}
}
再看一个例子:循环生成10个随机数。
随机数需要用到C标准库中的随机数函数rand和srand,srand根据一个数字生成一个随机数的种子,然后用rand生成一个随机数。 为了给srand提供一个随机值,可以使用time函数将得到的时间值传给srand
srand(time(0)); //用当前时间作为参数,生成一个“随机数发生器”
先看一个生成1个随机数的程序
#include <stdio.h>
#include <stdlib.h> //包含了rand() 和 srand的函数规范说明
#include <time.h> // time()函数的头文件
#include <ctype.h>
int main() {
srand(time(0)); //用当前时间作为参数,生成一个“随机数发生器”
printf("%d\n", rand() );
return 0;
}
rand()函数生成的是介于[0, RAND_MAX]的随机整数,假如我们要0到 99之间的随机整数,怎么办?
我们可以将rand()得到的随机整数和100取模(求余数)
printf("%d\n", rand() % 100);
综上所述,我们可以写出”循环生成10个随机数”的程序如下
/*---循环生成10个随机整数或实数---*
#include <stdio.h>
#include <stdlib.h> /*rand() 和 srand*/
#include <time.h> /* time() */
#include <ctype.h>
int main() {
// rand() 生成一个介于[0, RAND_MAX]的随机整数
printf("RAND_MAX is %d\n", RAND_MAX); //RAND_MAX一般是32767
/*没有先生成“随机数发生器”,产生的10个0到99之间的随机整数可能是一样的*/
int i;
for (i = 0; i < 10; ++i) {
printf("%d ", rand() % 100);
}
printf("\n");
/* 用当前时间作为参数,生成一个“随机数发生器” */
srand(time(0));
/* 生成10个0到 99之间的随机整数,结果不一样 */
for (i = 0; i < 10; ++i) {
printf("%d ", rand() % 100); /* <stdlib.h> */
}
printf("\n");
/* 生成10个0到 1之间的随实数,结果不一样 */
for (i = 0; i < 10; ++i) {
printf("%f ", rand()/ (RAND_MAX+0.1) ); /*实数相除才能得到实数 */
}
printf("\n");
}
continue
有时我们可能在循环体中根据某种条件是否满足决定是否终止当前的循环(不是终止整个循环),就要用到关键字continue表示的continue语句。 一旦遇到continue语句,就不再执行循环体continue后面的语句,而继续开展下一个循环体过程:
下面的程序输出所有1到20之间的偶数。
#include <stdio.h>
void main(){
int n=1;
for (; n<=20; n++) {
if (n % 2 == 1) { // i是否是奇数
continue; // 回到循环的开头
}
printf("%d\n",n);
}
}
该程序当发现n是一个奇数(n % 2 == 1)时,就回到循环开头,不再执行后面的printf语句。只有偶数才执行printf语句。
该程序for头” for (; n<=20; n++)”中的第一个分号;前面的初始化语句可以省略.实际上第二个分号后面的表达式也可以省略,但中间的条件表达式必须有,即写成如下形式。
#include <stdio.h>
void main(){
int n=1;
for (; n<=20; n++) {
if (n % 2 == 1) { // i是否是奇数
continue; // 回到循环的开头
}
printf("%d\n",n);
n++;
}
}
上面,我们已经看到循环和条件语句可以嵌套,再如
#include <stdio.h>
void main(){
int n = 100,i,sum=0;
if ( n > 0){
for(i = 0 ; i<n;i++)
sum += i;
}
printf("sum=%d\n",sum);
}
或
#include<stdio.h>
void main( ){
char command;
while( 1 ){
command = getchar( );
getchar(); /* 跳过输入缓冲区的换行符号/n */
switch( command){
case ' W ' :
printf( " welcome to come here ! \n " );
break;
case 'P':
printf( " I print some information for you \n " );
break;
default:
printf(" You pressed other key \n ");
break;
}
if(command=='q') break;
}
}
练习:
- 请编写一个函数计算y =x2在区间[-1,3]之间的定积分 (即该区间函数曲线和x轴之间部分的面积)。
提示:定积分也就是曲线包围的图形面积,可以将区间[-1,1]等分为很多份,比如100份,然后用每个小区间对应的矩形面积之和逼近定积分
- 猜数字游戏:程序随机生成一个 1到100之间的整数,然后让用户猜测一个数字,如果猜对了就祝贺并程序退出,猜错了,提示一下“太大”或“太小”,一共可以猜测比如7次。
程序执行情况如下:
请输入一个随机整数
你输入的数字过小
你输入的数字过大
你输入的数字过小
...
失败!超过最大尝试次数,程序退出!
提示:随机生成一个整数代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
int main(){
int number;
/*产生一个随机数发生器*/
srand( (unsigned)time( NULL ) );
/* rand()随机生成一个整数,
然后除以最大值RAND_MAX,
得到0到1之间的一个实数*/
for(int i = 0 ; i<5;i++){
number = 1+(int)(100.0*rand()/(RAND_MAX+0.1));
printf("%d\n",number);
}
}
您的打赏是对我最大的鼓励!