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\n");
break; //提前結束循環
}
}
if(i== x)
{
printf("yes\n");
}
一個循環結束有兩種情況
(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\n",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\n",r);
r++;
sum += r;
}
}