1,循环语句
有时候我们需要连续重复相同/类似的代码很多遍,就需要用到循环语句
循环 -》 就是连续去做重复的事情
在c语言中,有三种循环语句 while do while for 还有一条语句可以实现循环的效果 : goto
2,while语句
语法:
while(表达式)
循环体语句块
当while()中的表达式成立,就会执行循环体语句块,执行完语句块之后,再次判断表达式是否成立 如果成立,再次执行循环体语句块,执行完语句块之后,再次判断表达式是否成立 如果成立,再次执行循环体语句块,执行完语句块之后,再次判断表达式是否成立 ....... 直到某一次判断表达式不成立,结束该while语句 如果表达式永远成立,我们称之为“死循环” 表达式:任意的合法的c语言表达式都可以 while语句的循环体建议用 {} 括起来(如果不括起来,循环体语句就只有一条), while的首字母w和 左括号{ 和右括号}在一条线上,{}里面的语句块要用 tab键往右缩进
练习: 求 [100,200]范围内所有偶数之和
3, do ... while语句
语法:
do
{
循环体语句块
}while(表达式); //必须要有分号
先无条件的执行循环语句一次 判断表达式是否成立,如果成立,则再次执行语句块,执行完之后,再次判断表达式是否成立 如果成立,则再次执行语句块,执行完之后,再次判断表达式是否成立 如果成立,则再次执行语句块,执行完之后,再次判断表达式是否成立 ... 直到某一次判断表达式不成立,结束该do while语句 练习: 1,求一个整数的 n次方 2,输入一个正整数,逆序输出这个整数的每一位 12345 -> 5 4 3 2 1 0 -> 0 3,输入一个正整数,求它的阶乘 n = 1*2*3...*n 累乘 int j = 1;//保存阶乘 int i = 1;//用来循环 int n; scanf("%d",&n); while(i<=n) { j *= i; i++; }
4,求两个正整数的最大公约数 被这两个数能同时整除,并且是最大的那一个 穷举法:把所有可能的情况一一列举出来,进行分析判断,找出符合要求的那一个 int n,m; scanf("%d%d",&n,&m); m,n的最大公约数,怎么穷举? 1,先确定范围 [1,min(n,m)] 2,再循环判断是否为公约数,保留最大的那个
5,输入一个正整数n,判断是否为质数/素数? 质数:只能被1和它本身整除 思路: 统计 [2,n-1]范围内能被n整除的个数 《-穷举 int n; scanf("%d",&n); int i=2; int count = 0; while(i<n) { if(n%i == 0)//能被整除 { count++; break; } } if(count == 0) { 是质数 } else { 不是质数 }
4, for语句
语法:
for(表达式1;表达式2;表达式3) //注意:是分号,不是逗号
循环体语句块
先运行一次表达式1,再判断表达式2是否成立,如果成立,就执行语句块,然后执行表达式3, 再判断表达式2是否成立,如果成立,就执行语句块,然后执行表达式3, 再判断表达式2是否成立,如果成立,就执行语句块,然后执行表达式3, ...... 直到表达式2不成立 表达式1,2,3都可以省略,-》空语句,但是两个分号不能省略 如果表达式2省略,表示一直成立
例子: 求 [100,200]范围内所有偶数之和 int i; int sum = 0; for(i=100;i<=200;i+=2;) { sum += i; }
int i=100; int sum = 0;//必须要置0 while(i<=200) { sum += i;//累加, sum的初始值必须为0 i+=2; }
练习: 请大家把之前用 while循环实现的功能,全部改为 for循环 练习: 1,输出所有的水仙花数 水仙花数是一个三位数,并且它个位,十位,百位的立方和等于它本身 int i; int a,b,c;//分别保存i的个十百位 for(i=100;i<1000;i++) { a = i%10; b = i/10%10; c = i/100; if(a*a*a+b*b*b+c*c*c == i) { printf("%d\n",i); } }
2,求表达式 a+aa+aaa+.... + aa..aaa(n个a) 的值 a,n由键盘输入 a的范围 [0,9] 如: a 3 n 5 求 3 + 33 + 333 + 3333 + 33333 的值 第 1 2 3 4 5 项 求第i项(i个a),用s(i)表示 i=1 3 i=2 33 i=3 333 .... s(0) = 0 s(i) = s(i-1)*10+a i>0 int si = 0;//表示第i项 int sn = 0;//表示前i项之和 for(i=1;i<=n;i++) { si = si*10 + a; sn += si; }
5,两个关键字
break 和 continue
之前讲过 break语句放在 switch语句的 case子句中,用来结束 switch语句的
break还可以放在循环语句中(while\do while\for),作用是跳出/结束当前循环语句 例子: int data = 0; while(data < 20)//打印 [0,19] { printf("%d\n",data++); } int data = 0; while(data < 20)//打印 [0,9] { if(data == 10) break; printf("%d\n",data++); } ....
continue 只能放在循环语句中,作用是跳出这一次循环(这一次的循环体语句不再继续执行)
6,多重循环
顾名思义就是循环语句里面又有循环语句
例子: int i,j; for(i=0;i<10;i++) { for(j=0;j<=i;j++) { printf("%d ",j); } printf("\n"); }
-> for(j=0;j<=0;j++) { printf("%d ",j); } printf("\n"); for(j=0;j<=1;j++) { printf("%d ",j); } printf("\n"); for(j=0;j<=2;j++) { printf("%d ",j); } printf("\n"); ... for(j=0;j<=9;j++) { printf("%d ",j); } printf("\n");
0 0 1 0 1 2 0 1 2 3 .... 0 1 2 3 4 5 6 7 8 9 练习:输出[100,200]范围内所有的质数
int n; int i=2; int count = 0;//记录 [2,n-1]范围内能被n整除的个数 for(n=100;n<=200;n++) { count = 0;//需要在每次循环的时候置0 { if(n%i == 0)//能被整除 { count++; break; } } if(count == 0) { //是质数 printf("%d\n",n); } }
7,goto语句
语法:
goto 标志; 标志是用来标识一行代码(满足c语言标识符的规定,由数字,字母,下划线组成,不能由数字开头,不能是c语言关键字), goto 标志: 效果就是跳转到标志对应的那一行代码开始执行 例如: int n = 0; flag: printf("n=%d\n",n); n++; goto flag; 效果等价于: int n = 0; while(1) { printf("n=%d\n",n); n++; } 如果不希望是死循环怎么做? 和 if语句结合起来用 -> int n = 0; flag: printf("n=%d\n",n); n++; if(n<100) { goto flag; } 注意:只能在同一个函数内跳转 还可以往后面跳转: goto flag; .... ....中间的代码不会执行了 .... flag:
建议尽量不要用goto语句,降低代码的可读性 a==b || a<c x>4 || x<-4
if(a<b) { if(b!=15) { if(!ok1) { x=1; } else if(ok2) { x=10; } else { x=-1; } } }
作业: 1,输出 1000以内的所有完数 完数是指除了它本身以外的所有因数之和等于它本身 如: 4 : 1 2 1+2!=4 4不是完数 6 : 1 2 3 1+2+3==6 6是完数 穷举法 一个一个进行判断 [2,1000] 2,打印99乘法表 3,输入两个正整数,求他们的最小公倍数 4,求连续的正整数之和,一个正整数,有可能被表示为n个(n>=2)个连续的正整数之和 4 不能被这么表示 6 = 1+2+3 10 = 1+2+3+4 15 = 1+2+3+4+5 15 = 4+5+6 15 = 7+8 输入一个正整数,输出它所有可能满足条件的连续正整数序列 假设这个序列存在,并且由1开头 1+2 1+2+3 1+2+3+4 .... 假设这个序列存在,并且由2开头 2+3 2+3+4 ..... ....... 假设这个序列存在,并且由n/2开头 5,将一个正整数分解质因数 质因数 :是一个质数 && 是这个整除的因数 如: 输入 15 输出 15 = 3*5 输入 90 输出 90 = 2*3*3*5
任何人都不能保证自己写的代码一次过 既然如此,我们必须要学会 找错,改错 最基本的最简单的方法:加一些打印语句(打印的时候一定要加换行),把程序运行过程中一些比较重要、 可能会出错的数据打印出来,看这个数据是否符合预期。 改正了之后,需要把用于调试的打印语句注释掉