循环结构又称重复结构,是程序的 种基本结构之一。它反复执行循环体内的代码,解决需要大量重复处理的问题。循环结构由循环控制语句实现,其中内建有条件控制语句,用来判读是否继续执行循环操作。C 语言提供了 while 语句、do-while 语句、for 语句 3 种基本的循环控制语句,并且可以相互嵌套使用。

3.4.1 while 语句

while 语句是“当”型循环控制语句,即在条件满足时执行循环体,否则跳过或跳出循环体。while 语句的一般形式为:

while (条件表达式) { 循环体; }

如下例所示,求阶乘 n! 的结果:

int n = 1, p;			// 声明整型变量 n 和 p,n 用于控制步进,p 用于保存操作数
double s = 1; // 声明双精度变量 s, s用于保存计算结果
printf("请输入操作数 (1 - 170):"); // 输出操作提示信息
scanf("%d", &p); // 获取操作数,保存到变量 p 中
while (n <= p) // 当步进值不大于操作数时,执行循环体
{
s *= n++; // 将上一次的计算结果 s 与 步长值 n 相乘,并保存新的计算结果到 s,计算完成后步进值 n 自增
} printf("\n阶乘 n = %d 的结果为:%fd \n", p, s); // 输出操作结果

上例使用循环控制语句进行阶乘操作,while语句中的表达式用于判断当前阶乘的步进值是否大于输入的操作数。如果不大于则继续进行运算,否则结束循环。

提示:阶乘(factorial)是基斯顿.卡曼(1760 - 1826)于1808年发明的运算符号。阶乘指从 1 乘以 2 乘以 3 乘以 4 一直乘到所要求的数。例如操作数是 4,则阶乘式是 1 x 2 x 3 x4,得到的结果是 24,24就是 4 的阶乘。阶乘的计算会产生相当巨大的结果,在 C 语言的基本数据类型中字长最大的 double 型,也只能保存 170!的运算结果。当然,有很多方法可以保存更大的阶乘结果,有兴趣的可以探索这一问题。

3.4.2 do-while 语句

在 C语言中,“直到” 型循环是 do-while 语句,一般的形式为:

do { 循环体 } while { 条件表达式 }

与 while 语句的区别是,while 是先判读条件表达式再去执行循环体,而 do-whie 语句是先执行循环体再判读条件表达式。也就是说,do-while 语句会首先将循环体执行一次,再判断是否应该结束循环。例如计算 sin(x) 的值算法是“x - x3/3! + x5/5! - x7/7(......)”直到最后一项小于 1e-7 时为止,可用下例代码描述:

#include <stuio.h>
#include <math.h> // 加入数学函数库,以提供幂运算函数 fabs() int main()
{
double s, t, x; // 定义双精度型变量 s、t、x,其中 s 保存计算结果,t 表示下一项的结果,x 表示操作数 int n; // n表示公式中的 幂
printf("请输入 x 的值:");
scanf("%lf", &x); // 获取操作数
t = x; // 使 t 的值等于 x,得到公式中的第一项的值
n = 1; // 初始化幂数 n 为 1
s = x; // 将第一项的结果保存到结果 s 中 do
{
n += 2;
t *= (-x * x) / ((float)(n) - 1) / (float) (n);
s += t;
}
while (fabs(t) >= le-7); printf("\nsin(%f) = %lf\n", x, s); return 0;
}

上例中,使用循环控制语句依次将公式中的每一项加入结果中,从上一项推算当前项的结果只用将上一项乘以因子(x2)/((n-1) * n),即代码第 16 行所示。函数fabs()由头文件 math.h提供,作用是取绝对值。当输入 x 的值为 1.5753时,运算结果为 0.999 990。

3.4.3 for 语句

for 语句使用于可预知执行次数的循环控制结构,是 C 语言中最常用的循环控制语句。for 语句的一般形式为:

for (<表达式1>; <表达式2>; <表达式3>) { 循环体 }

表达式1 用于为控制变量赋初始值,表达式2用于放置循环控制条件的逻辑表达式,表达式3用于改变变量的值。这种结构能明确地展现循环控制结构中的 3 个重要组成部分,即控制变量的初始值、循环条件 和 控制变量 的改变。如计算自然数数列 1 至 n 的平方和,可用下列代码描述:

int i, p;
double s = 0;
printf("请输入操作数:\n");
scanf("%d", &p); for (i = 1; i <= p; i++)
{
s += (double) i * (double) i;
} printf("自然数 1 至 %d 平方和为:%lf\n", p, s);

for语句的 3个表达式都可以省略,或者放置在 for 语句的参数集合外,但不能省略表达式之间的分号,否则会造成语法错误。

注意:在编写循环结构的程序时,如果循环控制条件不能有效地结束,就会出现死循环,这是程序员经常会碰到的问题。含有死循环的代码能被编译器编译,但运行该程序会造成循环体无休止地被执行,消耗系统资源,严重的会造成系统死机。Linux系统针对死循环有良好的控制机制,不会让一个进程无休止地占据所有CPU资源,从而避免死机现象。当然,死循环在某些情况下存在是合理的,例如硬件驱动程序,通信程序和设备控制程序中,都需要用死循环反复无休止地处理某些问题。while(1) 和 for(;;) 常被生成死循环。

3.4.4 break 与 continue 语句

如果需要在循环体的执行过程中结束某一轮循环,或者直接跳出循环,可以使用 break 或  continue 语句。

break 语句的作用是立即结束当前循环并跳出循环体。下例用一个有趣的计算题说明该语句的使用方法,一只蜗牛顺着葡萄架向上爬,葡萄架高 11 米,蜗牛每天白天可以向上爬 3 米,但晚上会滑下来 1 米,问该蜗牛几天能够爬到葡萄架的顶端,程序代码如下:

int i = 1, s = 0;			// 定义变量 i 和 s,表示天数,s 表示已爬上的高度
const int h = 11; // 定义常量 h,h 表示总高
const int up_move = 3; // 定义常量 up_move,up_move 表示每天爬上的高度
const int down_move = 1; // 定义常量 down_move,down_move 表示每天滑下的高度 while (s <= h) // 当 s 不大于 h 时,执行循环体
{
s += up_move; // 将已爬上的高度加上当天爬上的高度
if (s >= h) // 判读已爬上的高度是否不小于总高度
{
break; // 结束当前循环,并跳出循环体
}
s -= down_move; // 将已爬上的高度减去当天滑下的高度
i++; // 天数自增
}
printf("蜗牛需要 %d 天爬到葡萄架顶\n", i); // 输出结果

上例的计算结果是 5,每天蜗牛实际向上爬上了 2 米。但是到了第 5 天,距离葡萄架顶只有 3 米,所以蜗牛可以一次爬上去。当前循环在 break 语句后的循环体代码都不会被执行。

continue 语句的作用是结束本轮循环,当前循环的循环体在 continue 后的代码不被执行,但并不跳出循环结构,而是立即开始新一轮的循环。如下例所示:

int n1 = 1, nm = 100;			// 定义查找范围
int i, j, flag; // 定义循环控制变量
if (n1 == 1 || n1 == 2) // 处理素数 2
{
printf("%4d", 2); // 输出素数 2
n1 = 3; // 将查找范围移动到 2 以后
} for (i = n1; i <= nm; i++)
{
if (!(i % 2))
{
continue; // 如果当前的数能被 2 整除,则结束该轮循环,该数不是素数
} for (flag = 1, j = 3; flag && j < i / 2; j += 2) // 从 3 开始遍历至 i x 1/2,每次步进 2
{
if (!(i % j))
{
flag = 0; // 若能整除,则不是素数
}
} if (flag)
{
printf("%4d", i); // 如果是素数,则输出该数
}
}

上例使用了双层循环结构来解决问题,第一层循环用于遍历定义域内的每个数,第二层循环判读该数是否是素数。continue 和 break 一样,只能影响所处的那层循环。

【C语言入门教程】3.4 循环控制语句的更多相关文章

  1. 《Ruby语言入门教程v1.0》学习笔记-01

    <Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...

  2. 《JavaScript语言入门教程》记录整理:入门和数据类型

    目录 入门篇 js介绍 历史 基本语法 数据类型 概述 null 和 undefined 数值 字符串 对象 函数 数组 本系列基于阮一峰老师的<JavaScrip语言入门教程>或< ...

  3. 《JavaScript语言入门教程》记录整理:运算符、语法和标准库

    目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...

  4. 《JavaScript语言入门教程》记录整理:面向对象

    目录 面向对象编程 实例对象与 new 命令 this关键字 对象的继承 Object对象的方法 严格模式(strict mode) 本系列基于阮一峰老师的<JavaScrip语言入门教程> ...

  5. C语言入门教程-(5)格式化输入输出

    1.输入和输出 在程序的使用中,我们经常可以看的这么一个场景:用户需要输入数据,经过程序运算,得到结果后输出.在C语言中,输入数据和输出数据都是由库函数完成的,通过语句来输入/输出. 2.格式化输出— ...

  6. Go语言入门教程(十)之函数

    Hello 各位小伙伴大家好,我是小栈君,假期一眨眼就过去了.不知道大家玩的是否开心呢? 上次我们讲到了关于Go语言的流程控制,小栈君也希望小伙伴跟着小栈君一步一个脚印的敲一下代码,相互进步.本期我们 ...

  7. c语言该怎么入门?C语言入门教程(非常详细)

    C语言是一门面向过程的编译型语言,它的运行速度极快,仅次于汇编语言.C语言是计算机产业的核心语言,操作系统.硬件驱动.关键组件.数据库等都离不开C语言:不学习C语言,就不能了解计算机底层. 这套「C语 ...

  8. Go 语言入门教程,共32讲,6小时(已完结)

    Go语言入门教程,共32讲,6小时(完结) 在B站:https://www.bilibili.com/video/BV1fD4y1m7TD/

  9. 【C语言入门教程】目录/大纲

    第一章 C语言编程基础 1.1 基本程序结构 1.2 函数库 和 链接 1.3 C语言“32个”关键字 第二章 数据类型.运算符和表达式 2.1 数据类型(5种基本数据类型),聚合类型与修饰符 2.2 ...

随机推荐

  1. selenium 基本的键盘方法

    今晚不想加班,于是赶紧回来看看书: 1.下了selenium的小工具:FireBug/FirePath. 2.确定了看书顺序,我觉得难度低点开始比较好,所以我还是先看基于Python的selenium ...

  2. Mysql备份还原数据库之mysqldump实例及参数详细说明

    [root@localhost myexport]# mysqldump -h211.100.75.204 -uroot -p@^#coopen -P5029 --single-transaction ...

  3. sql lock

    要提升SQL的查询效能,一般来说大家会以建立索引(index)为第一考虑.其实除了index的建立之外,当我们在下SQL Command时,在语法中加一段WITH (NOLOCK)可以改善在线大量查询 ...

  4. MySQL------Navicat激活方法

    转载: http://www.jianshu.com/p/b1f9194e1e31

  5. aircrack-ng 多网卡启动后环境清理

    #!/bin/sh pkill airodump airmon-ng stop wlan0mon service network-manager restart rm -rf sadsad*

  6. bootstrap从phpcmsv9中数据库中取出照片达到自适应的效果

    <script type="text/javascript"> $(".col-xs-12 img").addClass("carouse ...

  7. 初识Hadoop一,配置及启动服务

    一.Hadoop简介: Hadoop是由Apache基金会所开发的分布式系统基础架构,实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS:Hadoo ...

  8. Android学习笔记——ProgressBarHandler

    该工程的功能是实现点击按钮进度条按10%递增,使用的方式是Handler 以下的代码是MainActivity.java中的代码 package com.example.progressbarhand ...

  9. hdu 1873 看病要排队(优先级队列)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1873 题目大意: 三个医生看病,病人排队看病,病人有优先级,优先级高的提前看病,同样的优先级按先后.I ...

  10. C#如何把List of Object转换成List of T具体类型

    上周码程序的时候碰到个问题,因为设计上的约束,一个方法接受的参数只能为List<object>类型,然而该方法需要处理的真实数据则是确定的List<Currency>.然而C# ...