1.
求 y = 1+2+3+4+5...+100的值
int i = 1;//加数
int sum = 0;//和
0 + 1 = 1
1 + 2 = 3;
1 + 2 + 3 = 6;
1 + 2 + 3 + 4 = 10;
。。。
sum = sum + i;
i++;
sum = sum + i;
i++;
sum = sum + i;
i++;
。。
=》循环结构
循环的本质就是重复
C语言中可以达到循环效果的语句
(1)goto语句与if构成的
(2)while
(3)do while
(4)for
(1)goto语句
goto 目标地点(在C语言中,某条指令的地址)
“指令地址” :语句标号 (它下面那条指令的地址)
“语句标号”:名字
语句标号前面只允许有空白字符
名字必须符合C语言中标识符的规定
loop:
i++;
goto loop;
语法形式:
goto 语句标号;
eg:
把求1~100的和用goto语句实现
int i = 1;//加数
int sum = 0;//和
loop:
sum = sum+i;
i++;
if(i < 100)
{
goto loop;
}
注意:
主张限制使用goto语句
如果乱用goto语句,会使程序的可读性很差
(2)while循环
语法形式:
while(表达式)
循环体语句
当 “表达式”的值为真(非0),就执行“循环体语句”
然后,在判断“表达式”的值,如果为真(非0),就继续执行“循环体语句”
.....
直到“表达式”的值为假(0)为止(循环结束)
“表达式” :C语言中任意合法的表达式
“循环体语句”:
单语句 :只有有一个;语句
复合语句
{}/if/switch/for/while/do_while
eg:
while(i < 100)
{
i++;
sum = sum +i;
}
=>编程建议
不管while后面有没有语句,先打一对{}
表示他的“管辖范围”
练习:
输入一个整数,以逆序的顺序输出
12345
=>54321
n = 12345;
x = 12345%10
printf("%d",x);
....
step1:
求取个位数
step2:
打印
========
step1:
求取个位数
step2:
打印
step3:
把个位数拿到
while(n != 0)
{
//step1:求取个位数
x = n%10;
//step2:打印
printf("%d",x);
//step3:把个位数拿掉
n = n/10;
}
(3)do while
语法形式:
do
循环体语句
while(表达式);
先执行“循环体语句”,然后在判断“表达式”的值,
当表达式的值为真(非0),返回去执行上面的“循环体语句”,然后再一次
判断“表达式”的值,如果为真,返回去执行上面的“循环体语句”,
直到“表达式”的值为假(0),循环结束
“表达式” :C语言中任意合法的表达式
“循环体语句”:
单语句 :只有有一个;语句
复合语句
{}/if/switch/for/while/do_while
eg:
do
i++;
sum = sum+i;
while(I < 100);
这个代码是有语句错误
=>编程建议
不管do后面有没有语句,先打一对{}
表示他的“管辖范围”
do
{
循环体语句
}while(表达式);
练习:
求n! (n由用户输入)
4!
4*3*2*1
类乘
int i = 1;
int s = 1;
do
{
s = s*i;
i++;
}while(i <= n);
(4)for循环
语法形式:
for(表达式1;表达式2;表达式3)
循环体语句
先做“表达式1”(仅仅执行一次),然后再去判断“表达式2”的值
如果为真(非0),则执行“循环体语句”,
执行完“循环体语句”,在执行“表达式3”
在判断“表达式2”的值,如果为真(非0),则执行“循环体语句”,
执行完“循环体语句”,在执行“表达式3”
....如此重复
直到“表达式2”的值为假(0) 循环结束
“表达式1”,“表达式2”,“表达式3”
任意C语言合法的表达式都可以
“表达式1” :一个循环只做一次,初始化条件,可一个,可多个,用逗号隔开
“表达式2”:判断表达式,它的值直接决定for循环是执行还是不执行
“表达式3”:改变循环条件的地方,每当循环体语句做完之后,执行表达式3
“表达式1”,“表达式2”,“表达式3”都可以为空
但是;一个都不能少
表达式2为空,则表示循环判断条件永远为真
for(;;) while(1);
{
}
=>编程建议
不管for后面有没有语句,先打一对{}
表示他的“管辖范围”
练习:
1.求出所有的“水仙花数” 1.c
“水仙花数”是一个三位数,并且它的个,十,百位上的数字的立方和等于它本身
[100,999]
100 ?
if(0*0*0+0*0*0+1*1*1 == 100)
{
print 100
}
101 ?
if(1*1*1+0*0*0+1*1*1 == 101)
{
print 101
}
。。。。
999
num : [100,999]
x,y,z
if(x*x*x+y*y*y+z*z*z == num)
{
}
=============
for(num = 100;num<=999;num++)
{
//求取num的个,十,百
x=
y=
z=
if(x*x*x+y*y*y+z*z*z == num)
{
}
}
2.判断一个整数x,是否为质数(素数) 2.c
质数?
除了1和它本身以外没有其他的因数,这样的数就称为质数
6 :1 2 3 6
x
[2,x-1]
2 是不是x的因子
3 是不是x的因子
。。。
x-1 是不是x的因子
=>
for(i = 2;i < x;i++)
{
if(x % i == 0)//只要发现一个因子,不需要往下判断
{
printf("no ");
break; //提前结束循环
}
}
if(i== x)
{
printf("yes ");
}
一个循环结束有两种情况
(1)判断条件满足
因为break跳出循环 =》提前结束 非正常死亡
(2)判断条件不满足
“判断表达式”的值为0
(5)break和continue
break 在C语言中有两个作用
(1)break在switch中,用来跳出它所属的switch语句
(2)break用在循环语句(while/do_while/for)中,用来跳出它所属的循环
for()
{
while()
{
if()
{
break;//跳出while
}
}
}
/*
test1.c: In function ‘main’:
test1.c:9:3: error: break statement not within loop or switch
break;
^
*/
if()
{
break;
} //有语法错误
continue:
continue只能用于循环体内(while/do_while/for)
用于提前执行下一次循环(结束本次循环,继续下一次循环)
作业:
1、求1000以内所有的“完数”
“完数”:如果一个数除了它本身以外其他因子之和等于其本身,这个数就是完数
6 :1 2 3 6
m % n == 0;
=》m是n的倍数 ,n是m的因子(因数)
num [1,1000]
int sum = 0;
for(num = 1;num <=1000;num++)
{
sum = 0;
//判断num是不是一个完数
for(x = 1; x <num;x++)
{
if(num % x == 0)
{
sum += x;
}
}
if(sum == num)
{
printf("%d ",num);
}
}
2.求两个数(a,b)的最大公约数和最小公倍数
a % m == 0 =>a是m的倍数,m是a的约数
b % m == 0 =>b是m的倍数,m是b的约数
=>m是a和b的公约数
15 45
算法一:
“穷举法”
a % x == 0 && b % x == 0
从[1,min(a,b)] 区间里面找
找最大的公约数绝对不会大于min(a,b)
=> min = a <b ? a : b;
for(;min >0;min--)
{
if(a % min== 0 && b % min == 0)
{
min就是最大公约数
break;
}
}
======
算法二:
欧几里德算法
GCD(a,b)
假设a >= b
GCD(b,a mod b)
r = a mod b = a%b
证明 :
a,b的公约数集合 == b,a mod b的公约数的集合
A == B
A是B的子集,B是A的子集
A是B的子集 :
GCD(a,b)
x是GCD(a,b)中任意一个元素
a = K1 x (K1为整数)
b = K2 x (K2为整数)
r = a mod b
=>a = K*b +r (K为整数)
=> K1x = kK2x +r
=>r = (K1-KK2)x
=>x是r的约数
x是b的约数
x属于b,r的公约数 =》x 属于 GCD(b,r)
GCD(15,10) => GCD(10,5) =>GCD(5,0) =>5就是最大公约数
GCD(125,64) =>(64,61) =>(61,3) =>(3,1) =>(1,0) =>1
int a,b;
scanf("%d%d",&a,&b);
//确保 a>= b
while(a % b != 0)
{
r = a%b;
a = b;
b = r;
}
//最大公约数为a
优化:
while(b)
{
r = a%b;
a = b;
b = r;
}
3.连续的正整数之和。一个正整数有可能可以被表示为n(n>=2)个连续的正整数之和
x = 15
15 = 1+2+3+4+5
15 = 4+5+6
15 = 7+8
"穷举法"
i :1~x/2
sum = i;
if(sum == x)
{
}
i++;
sum += i;
if(sum == x)
{
}
===========
int i,x,num,sum;
scanf("%d",&num);
for(i = 1;i < num/2+1;i++)
{
sum = i;
for(x = i+1;;x++)
{
sum += x;
if(sum == num)
{
//输出处理
break;
}
else if(sum > num)
{
break;
}
}
}
算法二:
[L,R]
sum = [l,r]区间各元素之和
1:从1开始 1+ 2 +3 + 4+5+6
if sum < num //往右边扩展区间
r++;
sum += r;
if sum >num//
sum -= l;
l++;
if sum == num //找到这个区间
//输出处理
r++;
sum += r;
15
1+2+3+4+5...15
4 +5 +6 +7
=====
for(l = 1,r = 1,sum = 1;l <= num/2;)
{
if(sum < num) //往右边扩展区间
{
r++;
sum += r;
}
else if(sum >num)//把区间最左边的那个数拿掉
{
sum -= l;
l++;
}
else
{
int i;
//输出处理
//15 = 1+2+3+4+5
printf("%d = ",num);
for(i = l;i<r;i++)
{
printf("%d+",i);
}
printf("%d ",r);
r++;
sum += r;
}
}