0. 问题的引入
sum = 1 + 2 +3 +4 + 5 +... + 100; int sum = 0; int i = 1; sum = sum + i; // sum = 0 + 1 i = i + 1; sum = sum + i; // sum = 0 + 1 + 2 i = i + 1; sum = sum + i; // sum = 0 + 1 + 2 +3 i = i + 1; ... 把上面那两行代码,重复做100遍 …… 但是,这不科学, 能不能想办法,让计算机重复帮我去做100遍。 循环结构。 循环的本质是 : 重复!!!! 所有重复的代码,都可以用循环来实现。 在C语言中,能够达到循环效果("重复")的语句有如下: (1) if 和 goto 构造循环 (2) while 语句 (3) do while语句 (4) for语句
1. goto语句
-
逻辑:无条件跳转
让Cpu到指定的地方去执行。
-
格式
goto 行标识(语句标识);//程序会直接跳转到语句标号的地方执行 "行标识": 标识符,用来标识某一行…… 行标识一般写在一行的最前面, 当然行标识前面允许有空白符(如:空格,TAB,...) 注意: 语句标号一般写在一行的最前面, 当然语句标号前面允许有空白符(如:空格,TAB,...)
-
语法:
-
goto语句直接跳转到本代码块中的标签处
-
标签指的是以冒号结尾的标识符
-
-
注意:
-
一般来说,goto语句要和if配合使用,避免造成“死循环”
-
goto语句的无条件跳转不利于程序的可读性,一般不建议使用
-
-
goto语句常被用在程序的错误处理中
#include <stdio.h> int main() { int a; int b; //XXX: a++; goto XXX;// 编译器优化之后,可以跳转到后面代码段 printf("a = %d\n", a); XXX: a++; printf("a = %d\n", a); } //注意: 1. 行标识范围内不允许定义新的变量 // 2. if语句注意和goto一起用 // 3. 编译器优化之后,可以跳转到后面代码段
练习:
求100以内3的倍数之和。
3+6+9+12+...99 0+3 3+6 9+9 .... ==> int sum = 0; int i = 0; i += 3; sum = sum + i; i += 3; sum = sum + i; ... ====================================== i : [1,100] 1: 判断是否为3的倍数 是 累加 不是 不管 2: 判断是否为3的倍数 是 累加 不是 不管 3: 判断是否为3的倍数 是 累加 不是 不管 ... 100: 判断是否为3的倍数 是 累加 不是 不管 ===> int sum = 0; int i = 1; LOOP: if(i % 3 == 0) { sum += i; } i++; if(i < 100) goto LOOP; printf("sum = %d\n", sum);
==============
int main() { int sum = 0; int i = 3; LOOP: i += 3; sum = sum + i; if(i < 99) goto LOOP; printf("sum = %d\n", sum); }
2.while与do...while循环
-
逻辑:使得程序中每一段代码可以重复循环的运行
2.1while循环:先判断,再循环
while(表达式)// 表达式的值为真的时候进入循环体,为假退出 循环语句 当(while)“表达式”的值为非0,则执行“语句”,执行完“语句”后,则跳转到上面,继续判断 当(while)“表达式”的值为非0,则执行“语句”,执行完“语句”后,则跳转到上面,继续判断 .... 当(while)“表达式”的值为0,循环结束。 “表达式”: C语言中所有合法的表达式都可以。 “语句”: 循环体语句,要重复执行的语句 单语句: 只有一个;号的语句 复合语句: {}/if/switch/while/do while/for eg: while(1)// 死循环 等价于 while(1); { } 如果循环体内只有一条语句,那么{}可以省略 编程建议: 不管while后面有没有语句,先打一对{},以确定其“管辖范围” while () { }
while循环:入口判断
练习:
1.循环输出一系列正整数,直到100为止
2.用while循环来实现:逆序输出一个非负数 (作业)
x:
4321 ==> 1234
2.2do-while循环:先循环,再判断
语法: do 循环体语句 while(表达式) ; 先执行“循环体语句”,然后再判断"表达式"的值,如果"表达式"的值非0, 则回到上面,继续执行“循环体语句”,然后再判断"表达式"的值,如果"表达式"的值非0, 则回到上面,……。 直到“表达式”的值为0为止。 “循环体语句”: 单语句 复合语句: {}/if/switch/for/while/do while
例子:
编程建议: 不管do后面有没有语句,先打一对{},以确定其“管辖范围” do { } while();
do-while循环:出口判断
-
注意:
-
while 循环先进行判断,条件为真后才执行循环体,因此循环体可能一遍也不执行。
-
do-while 循环先执行循环体,再进行判断,因此循环体至少会执行一遍。
-
do-while 循环中的 while 语句后面有分号;
-
练习:
1.求n!(n由用户输入) n == 3 3! => 3*2*1
3.for循环
-
逻辑:与 while 循环类似,但更加紧凑,for 循环将控制循环的变量集中在一行
for(表达式1;表达式2;表达式3) 循环体语句; ==> for(初始表达式1;判断表达式2;循环操作表达式3) 循环体语句; 运行规则: 先执行一次“表达式1”, 然后再判断“表达式2”的值,如果为非0, 则执行“语句”,然后跳到上面,执行“表达式3” 然后再判断“表达式2”的,如果为非0, 则执行“语句”,然后跳到上面,执行“表达式3” .... 如此重复 直到“表达式2”的值为0为止。 注意: 1.“表达式1”、“表达式2”、“表达式3”: 任意合法的C表达式都可以(如:赋值表达式,逗号表达式,……。都可以) 2.“表达式1”、“表达式2”、“表达式3”都可以省略, 但是 for(;;)两个;号不能省略。 for(;;) <==> while(1) 3.如果表达式2省略,则表示for循环的执行条件永远为真。 表达式2 相当于就是循环条件 4."语句" : for循环的循环体语句 单语句 ; 复合语句:{}/if/switch/while/do while/for 编程建议: 不管for后面有没有语句,先打一对{}, 以确定其“管辖范围” for (; ;) {}
语法点:
-
循环头的标准语法是: for(表达式1 ; 表达式2 ; 表达式3)
-
表达式1一般用来初始化循环控制变量
-
表达式2一般用来作为循环判定条件,为真则进入循环,为假则跳出循环
-
表达式3一般用来更新循环控制变量
-
三个表达式均可以省略,但分号不能省略
-
while注重循环条件,for注重循环次数
练习:
1.使用for循环实现1+2+...+100的和
-
打印所有的“水仙花数”水仙花数 是一个三位数(100~999),并且这个三位数它个位、十位、 百位上的数字的立方和等于其本身。
-
判断一个整数是否为质数
质数 :素数 除了1 和本身 以外没有别的因子
break(退出)与continue(继续)
-
运用场景与特点
-
break关键字只能用于循环(while for do...while)和switch语句中,表示结束循环或者跳出switch语句
-
break关键字只能跳出所属的循环
-
break关键字 不能 单独用于 if语句中,除非if语句外面包含了循环
-
-
逻辑:
-
continue关键字只能用于循环体中(while do...while for),用于结束当前循环后,提前进行下一次循环
-
continue关键字不能 单独用于 if语句或者switch 语句中,除非外面包含了循环
-
break:① 跳出所属 switch 语句; ② 跳出所属循环体
-
continue:结束当次循环,进入下次循环
-
for(i = 0; i<10; i++) { if(1) { break; i++; } } i == 0 ============ for(i = 0; i<10; i++)// { if(1) { i++; continue; } i++; } ==> 该for循环,循环了多少次?
练习:判断不断输入的单个字符,如果是字符a~z或者A-Z,则打印yes,否则打印no。如果输入的是’#‘ 则退出程序
作业:
-
求两个数的“最大公约数” 和“最小公倍数”
-
求 Sn = a + aa + aaa +... + aa...a(n个a)
-
每次从键盘输入两个整型数据,并且比较两个数据的最大值进行输出,当输入相等时结束输入,退出程序。
-
求1000以内所有的完数。
-
连续的正整数之和。一个正整数有可能可以被表示 为n(n>=2)个连续的正整数之和,如: 15=1+2+3+4+5 15=4+5+6 15=7+8 请编写一个程序,根据输入的任何一个正整数,找出所有 可能的序列(也有可能没有).
-
将一个正整数分解质因数。例如:输入90 打印 90=233*5 任何一个正整数都是可以分解质因数的 6. 求100000000!末尾有多少个0?