C# Tutorial ตอนที่ 6(loop)
posted on 12 Jun 2005 22:33 by tidno1 in csharp-and-dotnetการวนลูป
การทำอะไรบางอย่างที่เป็นการทำซ้ำ ๆ กัน เราจะเรียกว่าการวนลูป คือการทำงานเป็นวงรอบนั่นเอง
โดย loop ในภาษานี้จะมีอยู่ 3 แบบคือ
- while( )..
- do..while( )
- for(; ;)
while loop

ดูจาก flow chart ข้างบนคงพอเข้าใจกันบ้าง นั่นคือจะมีการเช็กเงื่อนไขก่อนเข้าลูป ถ้าเป็นจริง ก็จะทำงาน แล้วก็จะกลับมาเช็กเงื่อนไขใหม่ เป็นอย่างนี้ไปเรื่อย ๆ
โดยมี syntax ดังนี้
statement
คล้าย ๆ กับ if นะครับ คือไม่มี keyword do อยู่หลัง condition เหตุผลเดียวกับ if ล่ะครับ นั่นคือ วงเล็บปิด เป็นตัวบอกจุดเริ่มของ statement ที่ต้องทำงานในลูป
do .. while loop

อันนี้จะคล้าย ๆ กับ while นะครับ เพียงแต่ต่างกันตรงที่ว่า จะทำงาน statement ใน loop ก่อน 1 ครั้ง แล้วจึงค่อยเช็ก condition
มี syntax ดังนี้ครับ
statement
while(cond);
โดยปกติแล้ว loop นี้มักจะไม่ค่อยได้ใช้ เนื่องจากสามารถเขียนแทนด้วย while loop ได้(โดยการนำเอา statement ใน loop ไปเขียนข้างนอกอีกครั้ง) และ while loop ยังอ่านได้ง่ายกว่าอีกด้วย
for loop
ในภาษาอย่างเช่น pascal หรือ vb นั้น for loop เป็นเหมือนกับ while loop ที่ลดรูปลงมา ไว้ใช้สำหรับการวนลูปที่กำหนดจำนวนครั้งเอาไว้ เช่น
Begin
readln(n);
for i:=1 to n do
begin
sum = sum + i;
end;
writeln('sum is', sum);
End.
แต่ใน ภาษาตั้งแต่ C เป็นต้นมา for loop นั้นคือ while loop แท้ ๆ เลยครับ โดยมี รูปแบบ syntax ดังนี้
statement
โดยเราสามารถเปลี่ยนfor loop เป็น while loop ได้ดังนี้
while(condition) {
statement
update_expr;
}
int i, sum = 0;
for(i = 1; i <= n; i++) {
sum += i;
}
Console.WriteLine(sum);
for(i = 0; i < n; i++) {
...
}
เราสามารถเขียน initial_expr และ update_expression ได้หลาย expression โดยต้องคั่นแต่ละ expression ด้วย comma
long fac;
Console.Write("Input nonnegative number : ");
n = Int32.Parse(Console.ReadLine());
for(i = 1, fac = 1; i <= n; i++) {
f *= i;
}
Console.WriteLine("{0}! = {1}", n, fac);
programmer ทั้งหลายมักจะใช้ตัวแปร i มาเป็นตัวแปร index ในการวนลูป ดังนั้นจึงเห็นการประกาศ int i; เกือบ ๆ ทุกฟังก์ชัน
ดังนั้นตั้งแต่ C++ เป็นต้นมา จึงได้รวบบรรทัด int i; มาไว้ในลูปเลย ทำให้ไม่ต้องประกาศตัวแปรแยกอีก ดังนี้
...
}
Console.WriteLine(i);
}
Console.WriteLine(i);
expression ใน for loop นั้นสามารถละทิ้ง ไม่เขียนก็ได้ และถ้าเราไม่เขียนทั้ง 3 expression เลย ก็จะกลายเป็น
...
}
...
}
แต่ เราก็ควรจะใช้ while loop ดีกว่า เนื่องจากอ่านแล้วเข้าใจกว่า(มาก ๆ)
example : เรามาเขียน method ที่คล้าย ๆ กับ Int32.Parse กันดีกว่า(ตัวอย่างนี้ดัดแปลงมาจาก The C Programming language ของ K&R)
int i, n, sign;
for(i = 0; Char.IsWhiteSpace(s[i]); i++) // skip space
;
sign = (s[i] == '-') ? -1 : 1;
if(s[i] == '+' || s[i] == '-') // skip sign
i++;
for(n = 0; Char.IsDigit(s[i]); i++)
n = 10 * n + (s[i] - '0');
return sign * n;
}
remark : s[i] หมายถึง character ในตำแหน่งที่ i ของ string s ครับ
expression ใน for loop ไม่ได้จำกัดว่า counter จะต้องเป็นจำนวนเต็มเท่านั้น จะเป็น เลขทศนิยม, ตัวอักษร หรืออะไรก็ได้
Console.WriteLine(c);
}
s = Console.ReadLine();
Console.WriteLine(s);
}
ถ้าใครได้อ่านเรื่อง round-trip format ที่ท้ายบล็อกที่แล้ว ก็คงจะพอคุ้น ๆ กันบ้าง(ขอบคุณพี่ลิ่วที่เตือนมาครับ)
ลองมาดูตัวอย่างกันซักหน่อยครับ
Console.WriteLine(f);
}
และนี่คือเหตุผลที่มันรันไม่หยุดครับ
for(int i = 1; i <= 11; i++, f += 0.1f) {
Console.WriteLine("{0:R}", f);
}
0.1
0.2
0.3
0.4
0.5
0.6
0.700000048
0.8000001
0.9000001
1.00000012
Console.WriteLine(f);
}
เดี๋ยววันหลังจะมาเขียนเรื่อง floating-point representation ให้อ่านครับ
ในบางภาษานั้น จะไม่ยอมให้เราแก้ไขตัวแปร counter ภายใน for block ได้นะครับ แต่ถึงแม้ภาษาที่ไม่มีข้อบังคับเช่นนั้น เราก็ไม่ควรจะแก้ไขค่าของตัวแปร counter เอง เพราะจะทำให้ โปรแกรมอ่านยากขึ้น
Console.WriteLine(i--);
}
break statement
ถ้าเราจำเป็นต้องออกจากลูป โดยไม่ต้องรอให้ครบรอบ เราก็สามารถทำได้โดยใช้ break;
string s;
s = Console.ReadLine();
while(s != "") {
n = Int32.Parse(s);
if(n < 0) {
break;
}
s = Console.ReadLine();
}
string s;
while((s = Console.ReadLine()) != "") {
n = Int32.Parse(s);
if(n < 0) {
break;
}
}
continue statement
การใช้ break; จะเป็นการออกจากลูปไปทันที แต่ถ้าต้องการให้มันแค่หยุดการวนลูปรอบนั้น และกลับไปทำงานใน loop ต่อ เราก็จะใช้ continue;
max = Int32.Parse(Console.ReadLine());
while(i < max) {
n = Int32.Parse(Console.ReadLine());
if(n < 0) {
continue;
}
sum += n;
i++;
}
Console.WriteLine("average is {0}", sum / max);
การบ้าน
-
วิธีหาหาตัวหารร่วมมาก(Greatest Common Divisor - gcd) โดยใช้ Euclid Algorithm มีขั้นตอนดังนี้
- ให้ m และ n เป็นเลขจำนวนเต็มบวกสองตัว ซึ่ง m >= n
- ให้ r เป็นเศษเหลือจากการหาร m ด้วย n
- ถ้า r == 0 จะได้ว่า n เป็น gcd
- ให้ m = n และ n = r แล้วย้อนกลับไปทำขั้นตอนที่ 2
-
เรามีนิยาม
แต่ว่าจะต้องใช้ n ที่มีค่าสูงมาก(1,000,000)เพื่อให้ e มีค่าทศนิยมถูกต้องถึงตำแหน่งที่ 6 เราจึงใช้ความรู้ด้านอนุกรมมาช่วย เพื่อหาค่า e ทำให้เราได้ว่า
ให้เขียนโปรแกรมเพื่อหาค่า e ให้ถูกต้องถึงตำแหน่งที่ 10
e = 2.71828 18284 59045 23536 02874 71352 66249 77572 47093 69995 95749 66967 62772... - เลข 153 เป็นเลข 3 หลัก ที่ ผลบวกของเลขโดดทั้ง 3 หลัก ยกกำลัง 3 แล้วบวกกันมีค่าเท่ากับตัวมันเอง (13 + 53 + 33 = 153) จงหาจำนวน 3 หลักทั้งหมดที่เป็นอย่างนี้
- เลข 1634 เป็นเลข 4 หลัก ที่ ผลบวกของเลขโดดทั้ง 4 หลัก ยกกำลัง 4 แล้วบวกกันมีค่าเท่ากับตัวมันเอง (14 + 64 + 34 + 44 = 1634) จงหาจำนวน 4 หลักทั้งหมดที่เป็นอย่างนี้
-
ให้เขียนโปรแกรมที่แสดงรูปต่อไปนี้
-
*โดยรับ input เป็นจำนวนแถว
***
*****
***
* - pascal 's triangle รับ input เป็น ค่า n เพื่อระบุว่าให้พิมพ์จนถึงแถว(a+b)n
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
.
.
.
-
เรียนวิศวะคอมปี2ค่ะ ก็ต้องเจอพวกนี้เหมือนกัน
(เผื่อมีเรื่องจะมาปรึกษา อิอิอิ)

ไม่เป็นไร ไม่เป็นไร
เช่นจาก 32 กลายเป็น 23
for(n = 0; Char.IsDigit(s[i]); i++)
n = 10 * n + (s[i] - '0');
หรือว่าคิดผิดเองหว่า
#1 By zkan on 2005-06-13 07:54