0.问题引入
求0~100数据之和:
int sum = 0;
sum = 1+2+3+4+....+100;
废手,那么有没有一种好的方法取操作呢?
int sum = 0;
int i =1;
sum = sum +i; // sum = 0+1;
i = i+1 ; // i = 2;
sum = sum +i ;
i = i + 1;
将上面的那两行代码重复执行100次,
那么0~100和就出来了!
循环!!!
循环的本质==>重复!!!
所有重复的代码,都可以用循环来实现。
在c语言中,能达到循环效果的语句
(1)for语句
(2)while语句
(3)do....while语句
(4)goto 和 if 构成循环
1. goto语句
goto “去哪儿”
goto:无条件跳转
让cpu到指定的地方去执行
语句:
goto 行标识符:
行标识符:
标识符,用来表示某一行。
写在一行的最前面,不需要顶格,可以有空白符
如:想办法让计算机重复执行如下两条语句
sum = sum +i ;
i = i + 1;
loop :
sum = sum +i ;
i = i + 1;
goto loop;
像上面的这个语句块,可以实现循环效果,重复执行“sum = sum +i ; i = i + 1;”
但是上面语句块,构成了一个死循环。
所以说,goto语句 一般需要和if语句配合使用,避免造成“死循环”
如:想办法让计算机重复执行如下两条语句100次
sum = sum +i ;
i = i + 1;
int sum = 0;
int i = 1;
loop:
sum = sum+i;
i = i +1;
if(i<=100)//循环次数在100之内
{
goto loop;
}
练习:请各位大佬,写一个程序,求100以内3的倍数之和(用goto语句实现)//3,6,9,12
#include <stdio.h>
int main()
{
int sum = 0;
int i = 3;
loop:
sum = sum +i;
i = i+3
if(i<=99)
{
goto loop;
}
printf("%d\n",sum);
}
NOTE:
建议要限制使用goto,
并不是goto语句有问题,但是使用goto语句的人有问题
建议不使用goto!!!
2.while语句
语法:
while(表达式)
循环体语句;
执行顺序:
当(while)“表达式”的值为非0,则执行“循环体语句”,执行完循环体语句之后
再跳转到上面继续判断“表达式”的值;
......
当(while)”表达式“的值为0,结束循环
表达式: C语言中任意合法表达式都OBJK
语句:
单语句:只有一个;号的语句
复合语句:
{}/if/switch/while....
例子:
int i = 1;
int sum = 0;
while(i<=100)
sum = sum +i;
i = i+1;
上面的这个while,只能够管到 “sum = sum +i;” 这一行语句,表达式的值一直为真
所以上面是一个“死循环”,因为i的值,一直为1,“表达式”的值一直为1(永远为真)
so:
不管while后面有没有语句,先打一对{},以确定while循环的管辖范围
练习:
用while循环来实现:逆序输出一个非负数的各个位上面的数字。
12345
54321
S1: 定义一个整型变量,从键盘赋值
int a;
scanf("%d",&a);
S2:输出a的个位上的数字
geiwe = a%10;
printf("%d",gewei);
s3:然后干掉个位
a = a/10;
s4:回到s2,知道当a为0结束循环
上面的程序,能不能用do...while来实现?
int a;
scanf("%d",&a);
do
{
//输出个位上的数字
geiwe = a%10;
printf("%d",gewei);
a = a/10;
}while(a!=0);
3.do....while
语法:
do
{
循环体语句;
}
while(表达式);
执行顺序:
先执行“循环体语句”,然后再判断“表达式的值”,如果表达式的值为非0
则回到上面,继续执行“循环体语句”;
....
直到“表达式”的值为0,结束循环
例子:求1-100之和
int i = 1;
int sum = 0;
do
sum += i;
i++;
while(i<=100);
"sum += i;
i++;" 这两行代码既不是单语句,也不是复合语句。
导致do没有和它匹配while,编译出错!!!
建议:不管do后面有没有语句,先打一对{}!!!
练习:
求n!(n是用户输入的一个正整数)
n! = 1*2*3*...*(n-1)*n
int n;
scanf("%d",&n);
int i = 1;//变量累加
int s = 1;//保存n!
s =s*i ;//s = 1*1
i++ ; // i = 2
s = s*i; // s = 1*2
i++;// i = 3
.....
重复语句
do
{
s = s*i;
i++;
}
while(i<=n);
c语言代码;
int n;
scanf("%d",&n);
int i = 1;//变量累加
int s = 1;//保存n!
do
{
s = s*i;
i++;
}
while(i<=n);
printf("%d",s);
4.for循环
语法:
for(表达式1;表达式2;表达式3)
循环体语句;
执行顺序:先执行表达式1,然后再判断表达式2的值,如果为非0,则执行循环体语句,然后再跳到上面执行
再执行表达式3;
然后再判断表达式2的值;
....
直到表达式2的值为0,结束循环
表达式1;表达式2;表达式3:
任意表达式都可以
并且“表达式1;表达式2;表达式3”都可以省略,但是两个;
是不能省略的!!!!
如果表达式2省略,则表示for循环的执行条件永远为真。
for(表达式1;;表达式3)
循环体语句;
====》
for(表达式1;1;表达式3)
循环体语句;
例子:求1~100
int sum = 0;
int i;
for(i=1;i<=100;i++);// i=101
sum = sum +i;//sum = 0+101
printf("%d\n",sum);//101
没有语法问题!!!
for循环中的“循环体语句”如果没有{},那么for语句它只能管到一个;!!!!
so:
不管这个for后面有没有语句,先打一对{}
for(;;)
{
}
练习:
1.打印所有的“水仙花数”(100-999)
水仙花数: 是一个三位数,并且这个三位数的个位,十位,百位上的数字的
立方和等于其本身。
如:
149 != 1*1*1 +4*4*4 +9*9*9
思路;
x为一个三位数
a,b,c分别为x的个位,十位,百位
x = 100
a = x%10
b = x/10%10
c = x/100
if(a*a*a+b*b*b+c*c*c)
{
printf x
}
x++
a = x%10
b = x/10%10
c = x/100
if(a*a*a+b*b*b+c*c*c==x)
{
printf x
}
.....
c语言代码:
int x,a,b,c;
for(x=100;x<1000;x++)
{
a = x%10;
b = x/10%10;
c = x/100;
if(a*a*a + b*b*b + c*c*c ==x)
{
printf("%d\n",x);
}
}
153,370,371,407
2.判断一个整数是否为质数
质数:除了1和它本身之外,没有其他的因数,称之为质数
伪代码;
i =>[2,x-1]
scanf x
i= 2
x%i == 0?
i++
x%i == 0?
i++
x%i == 0?
int i,x;
scanf("%d";&x);
int flag = 0; // 0 -是质数
// 1 -不是质数
for(i=2;i<x;i++)
{
if(x%i==0)
{
flag =1;
break;
}
}
if(flag==0)
{
printf("shi");
}
else
{
printf("bushi");
}
5.break 和 continue
break:
break 语句只能用在switch语句和循环体语句(while/for...)中,
(1)break用在switch中,用来跳出它所属的switch语句
(2)break用在循环体中,用来跳出它所属的那一个循环的。
一句话 break“跳出”
switch或循环体,是不是一定要用到break?
不一定,看您的心情!!!
continue:
continue只能用在循环体中(while/for...)中,
表示结束本次循环,继续下一次循环!!!1
例子:
输出如下数组元素值,除了值为5的那一个元素
int a[10] ={1,2,3,4,5,6,7,8,9,10};
int i;
for(i=0;i<10;i++)
{
if(a[i]==5) //i == 4
{
continue;
}
printf("%d\n",a[i]);
}
练习:
1. 求1000以内所有的完数
完数:是指除了本身以外所有的因子之和等于其本身
如:
6:1 2 3
6 == 1+2+3
分析:
1~1000
满足:它的因子之和(除去本身)等于它本身(1~x/2)
2:
1 !=2
3: 1 !=3
...
x= 1
if x所有的因子之和 == x
printf x
x++
x = 2
if x所有因子之和 == x
printf x
x++
=》
int x,i,sum;
for(x=2;x<1000;x++)//2~1000 的数
{
sum = 0;
for(i=1;i<=x/2;i++) //i:因子 范围[1,x/2]
{
if(x%i==0)
{
sum += i;//sum = sum +i
}
}
if(sum==x)
{
printf("%d\n",x);
}
}
2.求两个整数m,n 最大公约数,最小公倍数(m,n是从键盘输入的数字)
最小公倍数 = m*n/最大公约数
最大公约数:
m %l ==0
n %l ==0
l是m,n的一个公约数
设g是为m,n的最大公约数。
g=>[1,min(m,n)]
满足:m%g==0 && n%g==0
从(m,n)中最小的那一个数开始找
x = min(m,n);
if x是不是m,n 的一个公约数
则x就是最大公约数
x--
....
for(x=min(m,n);x>0;x--)
{
if(m%x==0&&n%x==0)
{
x就是最大公约数
break;
}
}
回顾:
1.goto .....if...
goto 无条件跳转指令
2.while 语句
while (表达式)
循环体语句;
3.do....while
do
{
循环体语句;
}
while(表达式);
4.for 语句
for(表达式1;表达式2;表达式3)
循环体语句;
执行顺序:
5.break 和 contiune
练习:
1. 请大家输入自己的生日(y-m-d),求自己在这个世界上浪费了多少天的公粮!!!
1.你出生的那一天到那一年的年末还有多少天
switch(m)
{
case 1:
d1 += 31;
case 2:
if(y是闰年)
d1 += 29;
else
d1 +=28;
case 3:
.....
}
d1= d1 -d;
2.你出生的第二年年初---2022年年末一共多少天
for(i=y+1;i<year-1;i++)
{
if(i是不是闰年)
d2 +=366;
else
d2 +=365;
}
3.2023已经过了多少天
2.求Sn = a + aa +aaa +...+....(n个a)
其中,n,a都是由用户输入
a =>[0,9]
如:
n = 5, a=2
Sn = 2+22+222+2222+22222
求和:
求第ai项
累加
sum + ai ->sum
例子:a = 2;
n = 5;
ai = 0;
Sn = 2 + 22+222+2222+22222;
i = 0
ai = ai*10+a
sum+=ai;
i = 1
ai = ai*10+a;
sum +=ai;
for(i=0;i<n;i++)
{
ai = ai*10+a;
sum += ai;
}
3.求10000000!末尾有多好个0
只要有一对2*5 末尾就会产生一个0
将1*2*3*.....*10000000进行质因数分解
只需要求分解质因数之和5的个数即可
int count =0; //记录末尾的0的个数
for(x=5;x<10000000;x+=5)
{
int i = x;
while(i%5==0)
{
count++;
i = i/5;
}
}
4.1024的655次方最后三位数是多少?
p = 1;
for(n = 1;n<=655;n++)
{
p= p*1024;
p = p%1000;
}
5,下面程序的功能是把316表示为两个加数的和,使两个加数分别能被13和11整除,请选择填空
(C)
#include<stido.h>
main()
{
int i=0,j,k;
do{i++;k=316-13*i;}while(__);
j=k/11;
printf("316=13*%d+11*%d",i,j);
}
A,k%11==0 B,k/11
C,k%11 D,k/11==0
6,设j和i都是int型,则以下for循环语句(B)
for(j=0,k=-1;k=1;j++,k++)
printf("****\n");
A,循环体一次也不执行
B,是无限循环
C,循环结束的条件不合法
D,循环体只执行一次
7有以下程序段
int n=0,p;
do
{
scanf("%d",&p);
n++;
}while(p!=12345&&n<3);
此处do-while循环结束的条件为?
(p的值等于12345或者n的值大于等于3)
8,以下叙述正确的是?(C)
A,用do-while构成循环时,只有在while后的表达式为非0时结束循环
B,do-while语句构成的循环不能用其他语句构成的循环来代替
C,用do-while构成循环时,只有在while后的表达式为零时结束循环
D,do-while语句构成的循环只能用break语句推出
9,以下程序的输出结果是?(10)
int k,j,s;
for(k=2;k<6;k++,k++)
{
s=1;
for(j=k;j<6;j++)
s+=j;
}
printf("%d\n",s);
10,以下程序段中,能够正确执行循环的是(B)
A,static int a;while(a)
B,int s=6;do s-=2;while(s);
C,for(i=1;i>10;i++)
D,int s=6;m:if(s<100) exit(0); else s-=2; goto m;
11,以下程序中,while循环的循环次数是(死循环,不确定次数)
main()
{
int i=0;
while(i<10)
{
if(i<1) continue;
if(i==5) break;
i++;
}
}
12,以下程序段的输出结果是?(1 -2)
int x=3;
do
{
printf("%3d",x-=2);
}while(!(--x));
13,下面程序的运行结果是?(0)
#include <stido.h>
main()
{
int y=10;
do{y--;}while(--y);
printf("%d\n",y--);
}
14,下面程序段的输出结果是? (11)
int i=0,sum=1;
do
{
sum+=i++;
}while(i<5);
printf("%d\n",sum);
15,有以下程序段:
s=1.0;
for(k=1;k<=n;k++)
s=s+1.0/(k*(k+1));
printf("%f\n",s);
请填空,使下面的程序段的功能完全与之等同,
s=0.0;
d=1.0;
k=0;
do
{
s+=d;
____;
d=(1.0)/(k*(k+1));
}while(____);
printf("%f\n",s);
(k++ k<=n)
16,下列程序的功能是输入一个整数,判断其是否为素数,如果为素数输出1,否则输出0,请填空
main()
{
int i,x,y=1;
scanf("%d",&x);
for(i=2;i<___;i++)
{
if(___){y=0;break;}
}
printf("%d\n",y);
}
(x/2 x%i==0)
17,执行以下程序后的输出结果是?(5,4,6)
{
int a,b,c,d,i,j,k;
a=10;b=c=d=5;i=j=k=0;
for(;a>b;++b)
i++;
while(a>++c)
j++;
do
k++;
while(a>d++);
printf("%d,%d,%d",i,j,k);
}
18,如果一次输入字符AB,在以下while语句执行后ch的值是?(0)
while(ch=getchar()=='A');