zoukankan      html  css  js  c++  java
  • 【C语言入门教程】3.4 循环控制语句

    循环结构又称重复结构,是程序的 3 种基本结构之一。它反复执行循环体内的代码,解决需要大量重复处理的问题。循环结构由循环控制语句实现,其中内建有条件控制语句,用来判读是否继续执行循环操作。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 = %d 的结果为:%fd 
    ", 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("
    sin(%f) = %lf
    ", 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("请输入操作数:
    ");
    scanf("%d", &p);
    
    for (i = 1; i <= p; i++)
    {
    	s += (double) i * (double) i;
    }
    
    printf("自然数 1 至 %d 平方和为:%lf
    ", 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 天爬到葡萄架顶
    ", 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 一样,只能影响所处的那层循环。

  • 相关阅读:
    GIT基础详解
    JS进阶解析
    JS基础解析
    CSS布局模型解析
    02.CentOS Linux 7.7 系统配置文档
    docker 创建bridge网络和修改默认网段
    selenium浏览器自动化测试工具 进阶使用
    前端导出Excel和打印介绍
    stm32使用gmtime()转换timestamp为日期,出的结果是乱的,不符合预期。改为localtime正常输出
    .net core api action 不能用作 httpget注释的参数名
  • 原文地址:https://www.cnblogs.com/52php/p/5681197.html
Copyright © 2011-2022 走看看