循环结构又称重复结构,是程序的 种基本结构之一。它反复执行循环体内的代码,解决需要大量重复处理的问题。循环结构由循环控制语句实现,其中内建有条件控制语句,用来判读是否继续执行循环操作。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. OS X: Messages Agent wants to use the "login" keychain

    问题: 启动mac电脑后弹出对话框,内容是Messages Agent wants to use the "login" keychain.无法取消. 首先说下keychain是什 ...

  2. hdu 2014 青年歌手大奖赛_评委会打分

    题意: 输入N个数,去掉最大和最小的数,求剩余的数的平均数. 解法: 找到分别最大和最小的数,然后从总和中减去他们,再求平均数(不要排序): 1: #include<stdlib.h> 2 ...

  3. linux 无线网络配置工具wpa_supplicant与wireless-tools

    4.a. 介绍目前您可以使用我们提供的wireless-tools 或wpa_supplicant工具来配置无线网络.请记住重要的一点是,您对无线网络的配置是全局性的,而非针对具体的接口.wpa_su ...

  4. JavaWeb学习总结-03 JSP 学习和使用

    一 JSP JSP 是Java Server Pages的缩写,在传统的网页HTML文件中加入 Java 程序片段和JSP标签就构成了JSP网页. 1 JSP与Servlet的生成方式 Servlet ...

  5. js003-基本概念

    js003-基本概念 3.1 语法 3.1.1 区分大小写 ECMAScript中的一切(变量.函数名和操作符)都是区分大小写的,并且不能用关键字作为函数名:如 typeof. 3.1.2 标识符 所 ...

  6. Cloudservice程序设置Idle timeout

    部署的云服务程序,默认的idle timeout是4分钟,意味着如果你通过一个workerrole发布了wcf服务,客户端第一次调用服务方法后,再过4分钟尝试去重新调用服务,会报错,具体测试如下: 1 ...

  7. 2012 Theory for Forward Rendering

    http://miss-cache.blogspot.com/2012/08/lighting-transparent-surfaces-with_26.html http://aras-p.info ...

  8. Quartz.NET总结(一)入门

    前段时间,花了大量的时间,将原先的计划任务,切换到Quartz.NET来进行管理.原先的后台定时服务都是通过计划任务来实现的,但是随着业务增长,计划任务也越来越多,每个后台服务,都得创建一个计划任务. ...

  9. 【原】Gradle调用shell脚本和python脚本并传参

    最近由于项目自动化构建的需要,研究了下gradle调用脚本并传参的用法,在此作个总结. Pre build.gradle中定义了$jenkinsJobName $jenkinsBuild两个Jenki ...

  10. HTML5 Audio and Video 的新属性简介

    前言:HTML5 中 Audio and Video的使用方法比较简单,但就是比较复杂,方法属性多.如果不常用的几乎难以记住,甚至有些人难以区分不同属性和方法的作用,更别说应用了.以下对Audio a ...