第六章 循环控制结构

循环结构:需要重复执行的操作

被重复执行的语句序列称为循环体

  • 计数控制的循环
  • 条件控制的循环
  • 当型循环结构
  • 直到型循环结构
  • for
  • while
  • do-while
while(循环控制表达式)
{
语句序列
}

计算循环控制表达式的值,如果循环控制表达式的值为真,执行循环体中的语句,返回;如果循环控制表达式的值为假,退出循环。

do
{
语句序列
}while(循环控制表达式);

执行循环体中的语句,计算循环控制表达式的值,如果循环控制表达式的值为真,返回;如果循环控制表达式的值为假,退出循环。

for(初始化表达式;循环控制表达式;增值表达式)
{
语句序列
}

初始化表达式的作用是为循环控制变量赋初值,决定了循环的起始条件

如何对循环变量进行增值,决定了循环的执行次数

如果在循环体内再次改变这个变量的值,将改变循环正常的执行次数

//L6-1

#include <stdio.h>
main()
{
int i, n, sum;
printf("Input n:");
scanf("%d", &n);
sum = 0; /* 累加和变量初始化为0 */
for (i=1; i<=n; i++)
{
sum = sum + i; /* 做累加运算 */
}
printf("sum = %d\n", sum);
}

逗号运算符:可把多个表达式连接在一起,作用是实现对各个表达式的顺序求值

空语句(仅由一个分号构成):表示什么也不做,常用于编写延时程序

//L6-2

#include <stdio.h>
main()
{
int i, n;
long p = 1; /* 因阶乘值取值范围较大,故p定义为长整型,并赋初值1 */
printf("Please enter n:");
scanf("%d", &n);
for (i=1; i<=n; i++)
{
p = p * i; /* 做累乘运算 */
}
printf("%d! = %ld\n", n, p); /* 以长整型格式输出n的阶乘值 */
}

//L6-3

#include <stdio.h>
main()
{
int i, n;
long p = 1;
printf("Please enter n:");
scanf("%d", &n);
for (i=1; i<=n; i++)
{
p = p * i;
printf("%d! = %ld\n", i, p); /* 输出1~n之间的所有数的阶乘值 */
}
}

//L6-4(嵌套循环)

#include <stdio.h>
main()
{
int i, j, n;
long p, sum = 0; /* 累加求和变量sum初始化为0 */
printf("Input n:");
scanf("%d", &n);
for (i=1; i<=n; i++)
{
p = 1; /* 每次循环之前都要将累乘求积变量p赋值为1 */
for (j=1; j<=i; j++)
{
p = p * j; /* 累乘求积 */
}
sum = sum + p; /* 累加求和 */
}
printf("1!+2!+…+%d! = %ld\n", n, sum);
}
//运行结果
Input n:4
1!+2!+…+4! = 33

编写累加求和程序的关键在于寻找累加项的构成规律

  • 当累加项较为复杂或者前后项之间无关时,需要单独计算每个累加项
  • 当累加项的前项和后项之间有关时,可以根据关系通过前项来计算后项

//6-5

#include  <stdio.h>
main()
{
int i, j;
for (i=0; i<3; i++) /* 控制外层循环执行3次 */
{
printf("i=%d: ", i);
for (j=0; j<4; j++) /* 控制内层循环执行4次 */
{
printf("j=%d ", j);
}
printf("\n");
}
}
//运行结果
i=0: j=0 j=1 j=2 j=3
i=1: j=0 j=1 j=2 j=3
i=2: j=0 j=1 j=2 j=3

//6-6(条件控制的循环)

#include  <stdlib.h>
#include <stdio.h>
main()
{
int magic; /* 计算机"想"的数 */
int guess; /* 用户猜的数 */
magic = rand(); /* 调用随机函数"想"一个数magic */
printf("Please guess a magic number:");
scanf("%d", &guess); /* 输入用户猜的数guess */
if (guess > magic) /*若guess>magic,则提示"Wrong!Too big"*/
printf("Wrong! Too big!\n");
else if (guess < magic)/*若guess<magic,则提示"Wrong!Too small"*/
printf("Wrong! Too small!\n");
else /* 否则提示"Right!"并打印这个数 */
printf("Right!\n");
}

//6-7

#include  <time.h>        /* 将函数time()所需要的头文件time.h包含到程序中 */
#include <stdlib.h>
#include <stdio.h>
main()
{
int magic, guess, counter = 0;
srand(time(NULL)); /* 为函数rand()设置随机数种子 */
magic = rand() % 100 + 1;
do{
printf("Please guess a magic number:");
scanf("%d", &guess);
counter ++;
if (guess > magic)
printf("Wrong! Too big!\n");
else if (guess < magic)
printf("Wrong! Too small!\n");
else
printf("Right!\n");
}while (guess != magic);
printf("counter = %d\n", counter);
}
//运行结果
Please guess a magic number:50
Wrong! Too small!
Please guess a magic number:75
Wrong! Too big!
Please guess a magic number:62
Wrong! Too big!
Please guess a magic number:56
Wrong! Too big!
Please guess a magic number:53
Wrong! Too big!
Please guess a magic number:51
Right!
counter = 6

//L6-8

#include  <time.h>
#include <stdlib.h>
#include <stdio.h>
main()
{
int magic, guess, counter = 0;
srand(time(NULL));
magic = rand() % 100 + 1;
do{
printf("Please guess a magic number:");
scanf("%d", &guess);
counter ++;
if (guess > magic)
printf("Wrong! Too big!\n");
else if (guess < magic)
printf("Wrong! Too small!\n");
else
printf("Right!\n");
}while (guess!=magic && counter<10);/*猜不对且未超过10次时继续猜*/
printf("counter = %d\n", counter);
}

//L6-9

#include  <time.h>
#include <stdlib.h>
#include <stdio.h>
main()
{
int magic, guess, counter = 0;
int ret; /* 保存函数scanf()的返回值 */
srand(time(NULL));
magic = rand() % 100 + 1;
do{
printf("Please guess a magic number:");
ret = scanf("%d", &guess);
while (ret != 1) /* 若存在输入错误,则重新输入 */
{
while (getchar() != '\n'); /* 清除输入缓冲区中的非法字符 */
printf("Please guess a magic number:");
ret = scanf("%d", &guess);
}
counter++;
if (guess > magic)
printf("Wrong!Too big!\n");
else if (guess < magic)
printf("Wrong!Too small!\n");
else
printf("Right!\n");
} while (guess!=magic && counter<10); /*猜不对且未超过10次时继续猜*/
printf("counter = %d\n", counter);
}

//L6-10

#include  <time.h>
#include <stdlib.h>
#include <stdio.h>
main()
{
int magic, guess, counter = , ret;
char reply; /* 保存用户输入的回答 */
srand(time(NULL));
do{
magic = rand() % + ;
do{
printf("Please guess a magic number:");
ret = scanf("%d", &guess);
while (ret != ) /* 若存在输入错误,则重新输入 */
{
while (getchar() != '\n'); /* 清除输入缓冲区中的非法字符 */
printf("Please guess a magic number:");
ret = scanf("%d", &guess);
}
counter++;
if (guess > magic)
printf("Wrong!Too big!\n");
else if (guess < magic)
printf("Wrong!Too small!\n");
else
printf("Right!\n");
} while (guess!=magic && counter<); /*猜不对且未超10次继续猜*/
printf("counter = %d\n", counter);
printf("Do you want to continue(Y/N or y/n)?"); /*提示是否继续*/
scanf(" %c", &reply); /* %c前有一个空格 */
}while (reply=='Y' || reply=='y'); /* 输入Y或y则程序继续 */

goto、break、continue和return语句是C语言中用于控制流程转移的跳转语句

goto语句为无条件转向语句,它既可以向下跳转,也可往回跳转

它的作用是在不需要任何条件的情况下直接使程序跳转到该语句标号所标识的语句去执行

其中语句标号代表goto语句转向的目标位置,应使用合法的标识符表示语句标号,其命名规则与变量名相同

break语句用于退出switch结构,也可用于由while、do-while和for构成的循环体中

当执行循环体遇到break语句时,循环将立即终止,从循环语句后的第一条语句开始继续执行

//L6-11

#include <stdio.h>
main()
{
int i, n;
for (i=1; i<=5; i++)
{
printf("Please enter n:");
scanf("%d", &n);
if (n < 0) goto END;
printf("n = %d\n", n);
}
END:printf("Program is over!\n");
}

continue语句与break语句都可用于对循环进行内部控制,但二者对流程的控制效果是不同的

当在循环体中遇到continue语句时,程序将跳过continue语句后面尚未执行的语句,开始下一次循环

即只结束本次循环的执行,并不终止整个循环的执行

//L6-12

#include <stdio.h>
main()
{
int i, n;
for (i=1; i<=5; i++)
{
printf("Please enter n:");
scanf("%d", &n);
if (n < 0) continue;
printf("n = %d\n", n);
}
printf("Program is over!\n");
}

在嵌套循环的情况下,break语句和continue语句只对包含它们的最内层的循环语句起作用,不能用break语句跳出多重循环。

若要跳出多重循环,break语句只能一层一层地跳出,显然goto语句是跳出多重循环的一条捷径。

以下两种情况使用goto语句可以提高程序的执行效率,使程序结构更清晰

  • 快速跳出多重循环
  • 跳出共同的出口位置,进行退出前的错误处理工作

//L6-13

#include <stdio.h>
main()
{
int x;
int find = 0; /* 置找到标志变量为假 */
for (x=1; !find; x++) /* find为假时继续循环 */
{
if (x%5==1 && x%6==5 && x%7==4 && x%11==10)
{
printf("x = %d\n", x);
find = 1; /* 置找到标志变量为真 */
}
}
}
//运行结果
x = 2111

结构化程序设计:

结构化程序设计是一种进行程序设计的原则和方法,按照这种原则和方法设计的程序,具有结构清晰、容易阅读、容易修改、容易验证等特点

  • 程序应该只有一个入口和一个出口
  • 不应有不可达语句和死循环
  • 尽量避免使用goto语句,因为它破坏了结构化设计风格
  • 采用自顶向下、逐步求精的模块化设计方法

常用的程序调试与排错方法:

  • 除为了取得堆栈轨迹和一两个变量的值之外,尽量不要使用排错系统,因为人很容易在复杂数据结构和控制流的细节中迷失方向
  • 有时以单步运行遍历程序的方式还不如努力思考,并辅之以在关键位置增设打印语句和测试代码,后者的效率更高

排错策略:

  • 缩减输入数据,设法找到导致失败的最小输入
  • 注释掉一些代码,分而治之
  • 增量测试

类型溢出

//L6-14

#include <stdio.h>
main()
{
long i, sum = 0;
for (i=1; ;i++)
{
sum = sum + i*i*i;
if (sum >= 1000000) break;
}
printf("count = %d\n", i);
//运行结果
count = 45

//L6-15

#include <stdio.h>
main()
{
double term, result = 1;
int n;
for (n=2; n<=100; n=n+2)
{
term = (double)(n * n) / ((double)( n - 1) * ( n + 1));
result = result * term;
}
printf("pi = %f\n", 2 * result);
}
//运行结果
pi = 3.126079

C语言程序设计(六) 循环控制结构的更多相关文章

  1. C语言程序设计第六次作业——循环结构(2)

    C语言程序设计第六次作业--循环结构(2) 之前的博客园图片没处理好,对大家说一声抱歉.希望大家能够多多指出我的错误,我来认真修改 ^ - ^ !. (1)改错题 序列求和:输入一个正实数eps,计算 ...

  2. 160809209_李梦鑫_C语言程序设计实验3 循环结构程序设计

    <C语言程序设计>实验报告 学 号 160809209 姓 名 李梦鑫 专业.班 计科16-2班 学    期 2016-2017 第1学期 指导教师 黄俊莲 吉吉老师 实验地点 C05 ...

  3. Python语言程序设计之一--for循环中累加变量是否要清零

    最近学到了Pyhton中循环这一章.之前也断断续续学过,但都只是到了函数这一章就停下来了,写过的代码虽然保存了下来,但是当时的思路和总结都没有记录下来,很可惜.这次我开通了博客,就是要把这些珍贵的学习 ...

  4. 《C语言程序设计教程》学习笔记

    <C语言程序设计教程>--朱鸣华.刘旭麟等 第一章 C语言概述 1.C语言的特点: 1)兼具高级.低级语言的双重能力(C语言允许直接访问物理地址,能够进行位操作,能实现汇编语言的大部分功能 ...

  5. 全国计算机等级考试二级Python语言程序设计考试大纲

    全国计算机等级考试二级Python语言程序设计考试大纲(2018年版) 基本要求 掌握Python语言的基本语法规则. 掌握不少于2个基本的Python标准库. 掌握不少于2个Python第三方库,掌 ...

  6. 《C语言程序设计》编程总结汇总

    <C语言程序设计>编程总结汇总 院系: 专业年级: 班级名称: 学号: 姓名: 指导教师: 完成时间: 自我评价: 计算机科学与技术专业教研室 2018 年秋季学期 第四周编程总结 题目4 ...

  7. C语言程序设计之 数组2020-10-28

    C语言程序设计之 数组2020-10-28 整理: 第一题:求最小数与第一个数交换 [问题描述] ​ 输入一个正整数n (1<n<=100),再输入n个整数,将最小值与第一个数交换,然后输 ...

  8. C语言程序设计入门学习五步曲(转发)

    笔者在从事教学的过程中,听到同学抱怨最多的一句话是:老师,上课我也能听懂,书上的例题也能看明白,可是到自己动手做编程时,却不知道如何下手.发生这种现象的原因有三个: 一.所谓的看懂听明白,只是很肤浅的 ...

  9. C语言程序设计第4堂作业

    大家注意:本次作业稍有增加,由于放假期间大家空闲时间比较充足,将之前学习过程中遗留的问题必须在假期解决.   本次课学习主要内容: 分支结构中的二分支结构.多分支结构和else-if语句 掌握字符型数 ...

随机推荐

  1. Oracle中实现sql查询得到连续号码段

    一.表名为t的表中数据如下: select * from t; FPHM KSHM ---------- ---------- 实现代码如下: select b.fphm,min(b.kshm),ma ...

  2. python后端面试第五部分:Linux操作系统--长期维护

    ##################     Linux操作系统      ####################### 1,讲一下你常用的Linux/git命令和作用: 2,查看当前进程是用什么命 ...

  3. perf4j @Profiled常用写法

    以下内容大部分摘抄自网络上信息. 1.默认写法 @Profiled 日志语句形如: 2009-09-07 14:37:23,734 [main] INFO org.perf4j.TimingLogge ...

  4. deeplearning.ai 构建机器学习项目 Week 2 机器学习策略 II

    1. 误差分析(Error analysis) 误差分析的目的是找到不同误差源的比重,从而指引我们接下来往哪个方向努力改进.NG建议手工统计随机100个错误的误差源,比如对于猫分类器,错误的照片可能是 ...

  5. 听《Sara》

    Sara这首歌太好听了,虽然没有清楚具体是唱什么,但我感觉是讲一个故事,很好奇,我找到了歌词. Sara 塞拉 鲍勃迪伦 I laid on a dune, I looked at the sky, ...

  6. jmeter常用定时器以及事物控制器

    定时器(并发):Synchronizing Timer 事物控制器: 勾选Generate parent sample当单看主要数据和页面数据性能测试结果还是有比较大的差异的,因而在进行页面性能测试的 ...

  7. C 语言高效编程与代码优化

    译文链接:http://www.codeceo.com/article/c-high-performance-coding.html英文原文:Writing Efficient C and C Cod ...

  8. (转)假如没有OI By Vani

    假如没有OI                                                                                               ...

  9. 2015-09-14-初级vector

    标准库vector类型 #include<vector> using std::vector; vector为一个类模板. vector的初始化 vector<T> v1; v ...

  10. 国产ROM纷争升级 能否诞生终结者?

    能否诞生终结者?" title="国产ROM纷争升级 能否诞生终结者?"> 相比iOS系统的低硬件高流畅,安卓系统就显得"逼格"低了许多.先不说 ...