switch..case

switch..case ก็เป็นการเขียน if clause แบบหนึ่งที่ง่ายขึ้น มีรูปแบบ syntax ดังนี้

switch(<expression>) {
    case <value> : <statement>
    case <value> : <statement>
    case <value> : <statement>
    ..........................
    [default : <statement>]
}
ตรง expression นั้นจะเป็นตัวแปร หรือ method ใด ๆ ก็ได้
โดย default นั้นเปรียบเสมือน else ... ซึ่งจะเป็น option ที่จะมีก็ได้ ไม่มีก็ได้
ลองมาดูตัวอย่างเพื่อความเข้าใจดีกว่า
int grade = Int32.Parse(Console.ReadLine());
string gradeString;

switch(grade) {
    case 4 : gradeString = "A";
    case 3 : gradeString = "B";
    case 2 : gradeString = "C";
    case 1 : gradeString = "D";
    case 0 : gradeString = "F";
    default : gradeString = "Incorrect number";
}

Console.WriteLine(gradeString);
ก็ควรจะมีผลเหมือนกับ
int grade = Int32.Parse(Console.ReadLine());
string gradeString;

if(grade == 4) {
    gradeString = "A";
} else if(grade == 3) {
    gradeString = "B";
} else if(grade == 2) {
    gradeString = "C";
} else if(grade == 1) {
    gradeString = "D";
} else if(grade == 0) {
    gradeString = "F";
} else {
    gradeString = "Incorrect number";
}

Console.WriteLine(gradeString);
ถ้านำตัวอย่างนี้ไปรันในภาษาอย่าง C,C++ หรือ Java แล้วสมมุติว่าใส่ input เป็น 3 ผลที่ได้คือ
B
C
D
F
Incorrect number
นั่นเพราะว่า ถ้า case ใดตรงกับค่าใน switch expression มันก็จะทำงานที่ case อื่น ๆ ข้างล่างทั้งหมดเลย ดังนั้น C# จึงแก้ความสับสนนี้ โดยการให้ code ด้านบนนั้นไม่ผ่านการ compile

วิธีแก้ปัญหากรณีนี้ก็คือใส่ประโยค break; ลงไปในแต่ละ case ดังนี้

int grade = Int32.Parse(Console.ReadLine());
string gradeString;

switch(grade) {
    case 4 :
        gradeString = "A";
        break;
    case 3 :
        gradeString = "B";
        break;
    case 2 :
        gradeString = "C";
        break;
    case 1 :
        gradeString = "D";
        break;
    case 0 :
        gradeString = "F";
        break;
    default :
        gradeString = "Incorrect number";
}

Console.WriteLine(gradeString);
คนที่เคยเขียน pascal มาแล้วคงสงสัย ว่าทำไมต้องใส่ break ด้วยล่ะ ทำไมไม่ทำ ประโยค switch..case ให้มันทำงานแค่ case เดียวแล้วออกเลย นั่นเพราะมันมีประโยชน์บ้างครับ ลองมาดูกัน
int grade = Int32.Parse(Console.ReadLine());
string message;

switch(grade) {
    case 4 :
    case 3 :
        message = "You 're good";
        break;
    case 2 :
    case 1 :
        message = "You should pratice more";
        break;
    case 0 :
        message = "try try and try";
        break;
    default :
        message = "Incorrect number";
}

Console.WriteLine(message);
นั่นคือถ้าได้เกรด 4 หรือเกรด 3 message ก็จะเป็นข้อความว่า You 're good แต่ถ้าได้ 2 หรือ 1 ก็จะเป็นข้อความว่า You should pratice more

*ในภาษาอื่น ๆ นั้นตรง expression นั้นต้องเป็น integral type เท่านั้น นั่นคือจะต้องเป็นพวก int short,... หรือ char แต่ว่าใน C# นั้นสามารถใส่ expression เป็น string ได้ด้วย

string gradeString = Int32.Parse(Console.ReadLine());
string message;

switch(gradeString.ToUpper()) {
    case "A" :
        message = "Excellent";
        break;
    case "B" :
        message = "Good";
        break;
    case "C" :
        message = "Cool";
        break;
    case "D" :
        message = "Try";
        break;
    case "F" :
        message = "Get out!!";
        break;
    default :
        message = "Incorrect grade";
}

Console.WriteLine(message);

Formatting String

คุ้น ๆ code ด้านล่างนี้ใช่มั้ยครับ

Console.WriteLine("Hi {0}\nYou 're {1} years old", name, age);
มันมาจาก tutorial ตอนที่ 1 เป็นสไตล์การเขียนแบบ C ครับ ถ้าเป็นใน C ก็คงเป็นอย่างนี้
printf("Hi %s\nYou 're %s years old\n", name, age);
โดย %s บอกว่าให้เอา string มาใส่ตรงนี้นะ(s คือ string ถ้าเป็น int ก็จะเป็น %d, float ก็ %f, char ก็ %c)

การเขียนอย่างนี้ไม่ได้ช่วยให้การอ่านประโยคนั้นต่อเนื่องเพียงอย่างเดียว แต่มันยังสามารถจะ format ได้อีกด้วย ลองดูตัวอย่างกัน

Console.WriteLine("{0,5}{1,5}", 123, 456);     // Right-aligned
Console.WriteLine("{0,-5}{1,-5}", 123, 456);   // Left-aligned
ผลลัพธ์
  123  456
123  456
อันนี้คือการจัดชิดซ้ายชิดขวา โดยการระบุความกว้าง(จำนวนตัวอักษร)ลงไป
ถ้าเป็น C จะเขียนอย่างนี้ (ใน C ถ้าจะขึ้นบรรทัดใหม่ ต้องใส่ '\n' เองเสมอ)
printf("%5d%5d\n", 123, 456);     // Right-aligned
printf("%-5d%-5d\n", 123, 456);   // Left-aligned
ถ้าเป็น Pascal
writeln(123:5, 456:5); { Right-aligned }
writeln(123:-5, 456:-5); { Left-aligned }
ประโยชน์ที่เห็นได้จากการจัดความกว้างก็เช่นการโชว์ข้อมูลเป็นบล็อก ๆ ให้ตรงกัน เพื่อความสวยงาม
Console.WriteLine("{0,-10}{1,-3}", "Name","Salary");
Console.WriteLine("----------------");
Console.WriteLine("{0,-10}{1,6}", "Bill", 123456);
Console.WriteLine("{0,-10}{1,6}", "Polly", 7890);
Name      Salary
----------------
Bill      123456
Polly       7890

นอกจากการกำหนดความกว้างแล้ว เรายังกำหนดรูปแบบได้อีกด้วย โดยการใส่ :(colon) แล้วตามด้วยตัวอักษรลงไปหลังตัวเลขระบุตำแหน่ง ดังนี้

Character ความหมาย
C หรือ c Currency(เงิน)
D หรือ d Decimal(แปลว่าเลขฐาน 10 นะ อย่าสับสนกับ ตัวแปรประเภท decimal)
E หรือ e Exponent(ระบบวิทยาศาสตร์)
Fหรือ f Floating poing(ทศนิยม)
G หรือ g General
N หรือ n Number(เหมือน F แต่จะใส่ comma คั่นตัวเลขทุก ๆ 3 หลัก
P หรือ p Percentage
R หรือ r Round-trip ใช้กับ floating-point value เท่านั้น โดยจะ guaruntee ว่าค่าที่ถูกเปลี่ยนไปจะมีค่าเท่ากับตัวเดิม
X หรือ x Hexadecimal(เลขฐาน 16)
int i = 123456;
Console.WriteLine("{0:C}", i);
Console.WriteLine("{0:D}", i);
Console.WriteLine("{0:E}", i);
Console.WriteLine("{0:F}", i);
Console.WriteLine("{0:G}", i);
Console.WriteLine("{0:N}", i);
Console.WriteLine("{0:P}", i);
Console.WriteLine("{0:X}", i);
฿123,456.00
123456
1.234560E+005
123456.00
123456
123,456.00
12,345,600.00 %
1E240

Console.WriteLine("{0:D6} {1:D4}", 123, 456);
000123 0456

เราสามารถรวมการจัดความกว้างและฟอร์แม็ตไปพร้อม ๆ กันได้ดังนี้

Console.WriteLine("{0,-10:D6}{1,-10:F4}", 123, 456.0000);
Console.WriteLine("{0,-12:N2}{1,9:X4}", 1234567, 240);
000123     456.0000
1,234,567.00   00F0

อ้อ ลองมาดูความแตกต่างของ F กับ R กันตรงนี้เลยครับ

double d = 1.2345678901234567890;
Console.WriteLine("{0:F16}", d);
Console.WriteLine("{0:R16}", d);
1.2345678901234600
1.2345678901234567
ตาม definition ของ R เป็นอย่างนี้ครับ
The R (round-trip) format works only with floating-point values: the value is first tested using the general format, with 15 spaces of precision for a Double and seven spaces of precision for a Single. If the value is successfully parsed back to the same numeric value, its formatted using the general format specifier. On the other hand, if the value isnt successfully parsed back to the same numeric value, the value is formatted using 17 digits of precision for a Double and nine digits of precision for a Single. Although a precision specifier can be appended to the round-trip format specifier, its ignored.
อย่าสนใจเลย แปะไว้งั้น ๆ แหละ

การจัด format สามารถทำได้ตอนสร้าง string ขึ้นมาตัวหนึ่งเลยก็ได้ ดังนี้ โดยใช้ method Format ของคลาส String ดังนี้

string s = String.Format("{0:D3}", 123);

Comment



smilebig smileopen-mounthed smileconfused smilesad smileangry smiletonguequestionembarrassedsurprised smilewinkdouble winkcry

Tweet

ความจริงน่าแปลความหมาย Round-Trip เป็นภาษาไทยนะ มีประโยชน์ดี

อ้อ ถ้าให้ดีควรมีโน๊ตให้ระวังการเทียบค่า Real ด้วยว่ามันอันตราย

เรื่องพวกนี้ตอนมัธยมไปเรียนแล้วไม่มีสอน สร้างความปวดหัวดีจริงๆ

#1 By ลิ่ว on 2005-06-09 16:27

สรุปว่า C# ต้องใส่ break; หรือเปล่าครับ

#2 By P.S. on 2005-06-09 18:59

P.S. : ต้องใส่เสมอครับ

#3 By T!D on 2005-06-09 19:18

ขอบคุณมากนะ มาสอนตอนเลิกทำ

#4 By bank on 2005-06-10 21:50

แบ้งค์ : แสดงว่าตอนทำอยู่ เขียนไม่ได้

#5 By T!D on 2005-06-11 20:34

ถ้าจะแบ่งเลขทศนิยม เช่น 22.55 ออกมาเป็น
22 กับ 55 (เลขจำนวนเต็ม) โดยใช้ function ของ C# เลยทำยังงัยคับ

#6 By johny (203.146.182.1) on 2005-07-13 12:02

#6 ถ้าจะเอาส่วนจำนวนเต็ม ใช้ การ cast ให้เป็น int ก็ได้ครับ หรือจะใช้ method Math.Floor() ก็ได้

x = (int)22.55; หรืิอ x = Math.Floor(22.55);

ถ้าจะเอาส่วนทศนิยม ก็ใช้เอาเลขเดิมมาลบด้วยส่วนจำนวนเต็ม หรือใช้ mod ด้วย 1 ก็ได้ครับ
y = 22.55 - x; หรือ y = 22.55 % 1;

#7 By T!D on 2005-07-14 14:37

#8 By (200.204.154.29 /200.204.154.29) on 2005-07-25 21:53

ทำไงดีอะ เวลา คอมไพล์ : error cs0165

Use of unassigned local variable 'sum'

using System;
class test
{
public static void Main()
{
Console.WriteLine("Calculator");
Console.WriteLine("Start? Yes type Y, No type N.");
if (Console.ReadLine() == "Y")
{
Console.WriteLine("Select Your Choise");
Console.WriteLine("Type + if you need to +.");
Console.WriteLine("Type - if you need to -.");
Console.WriteLine("Type * if you need to *.");
Console.WriteLine("Type / if you need to /.");
string a = Console.ReadLine();
Console.WriteLine("You Selected " + a + ", Press Enter to Continue.");
Console.ReadLine();
Console.WriteLine("Type type your First number");
double num1 = Double.Parse(Console.ReadLine());
Console.WriteLine("Type type your Second number");
double num2 = Double.Parse(Console.ReadLine());
double sum;
if (a == "+")
{
sum = num1 + num2;
}
else if (a == "-")
{
sum = num1 - num2;
}else if (a == "*"){
sum = num1 * num2;
}
else if (a == "/")
{
sum = num1 / num2;
}
Console.WriteLine(sum);
Console.WriteLine(" ");
Console.WriteLine("Thank You! Press Enter to exit.");
Console.ReadLine();
}
}
}

#9 By a (58.8.14.181) on 2007-01-14 16:40

Use of unasssigned local variable 'sum'
คือตัวแปร sum ไม่มีค่าตั้งต้นน่ะครับ ควรเขียนเป็น
double sum = 0;//อันนี้ผมเจอบ่อย

#10 By poonpol99 (124.120.92.42) on 2007-10-01 14:45

ทำ Switch case ในการคิดเกรดทำได้แค่กำหนดเป็น case 1: case 2: รันได้แต่ต้องการใส่ตัวเลขตร case เป็นค่าของคะแนนเช่น 80 ถึง 100 ได้ Aจะใส่ยังไงหากเราจะทำเป็นช่วงๆ ของคะแนน ผู้ที่มีจิตเมตตาเด็กตาดำๆ ช่วยตอบด้วยค่ะ ส่งไม่เกินเที่ยงคืน นี้ค่ะdouble wink tongue angry smile open-mounthed smile

#11 By juraruk_m@hotmail.com (203.158.205.32) on 2007-12-19 22:45

int grade = (Int32.Parse(textBox1.Text));
string gradeString;

switch (grade)
{
case 4: gradeString = " ได้ A เก่งมาก ";
break;

case 3: gradeString = " ได้ B ดี ";
break;

case 2: gradeString = "ได้ C พอใช้ ";
break;

case 1: gradeString = "ได้ D ค่อนข้างอ่อน";
break;

case 0: gradeString = "ได้ F ต้องปรับปรุง ";
break;

default: gradeString = "Incorrect number";
break;

}

MessageBox.Show(gradeString,"Grading", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);

}

}
}

#12 By juraruk_m@hotmail.com (203.158.205.32) on 2007-12-19 22:49

#13 By (202.28.27.5) on 2009-01-19 17:58

confused smile

#14 By (202.143.134.179) on 2009-02-03 13:31

thank you
very good

#15 By (114.128.152.246) on 2009-07-10 07:22

ลองรันตามแล้วมันerror

#16 By krung (203.158.205.32) on 2009-09-09 10:48