C語言循環結構細講


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語言中可以達到循環效果的語句

1goto語句與if構成的

2while

3do while

4for

 

1goto語句

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)breakcontinue

break C語言中有兩個作用

1breakswitch中,用來跳出它所屬的switch語句

2break用在循環語句(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;

=mn的倍數 ,nm的因子(因數)

 

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 =>am的倍數,ma的約數

b  % m == 0 =>bm的倍數,mb的約數

 

=>mab的公約數

 

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

AB的子集,BA的子集

 

AB的子集 :

GCD(a,b)

xGCD(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

=>xr的約數

xb的約數

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.連續的正整數之和。一個正整數有可能可以被表示為nn>=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;

}

 

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM