1. บทนำ
ลำดับความสำคัญของโอเปอเรเตอร์ในภาษา C มีความสำคัญอย่างมากต่อการทำความเข้าใจการทำงานของโปรแกรมอย่างถูกต้องและได้ผลลัพธ์ตามที่ต้องการ โดยเฉพาะอย่างยิ่ง หากเข้าใจลำดับการประเมินโอเปอเรเตอร์ผิด อาจเกิดผลลัพธ์ที่ไม่คาดคิดหรือเกิดบั๊กได้ บทความนี้จะอธิบายรายละเอียดเกี่ยวกับลำดับความสำคัญและกฎการเชื่อมของโอเปอเรเตอร์หลักในภาษา C พร้อมตัวอย่างเพื่อให้เข้าใจมากยิ่งขึ้น
2. ประเภทของโอเปอเรเตอร์และวิธีใช้งานเบื้องต้น
2.1 โอเปอเรเตอร์ทางคณิตศาสตร์
โอเปอเรเตอร์ทางคณิตศาสตร์เป็นโอเปอเรเตอร์พื้นฐานสำหรับการคำนวณตัวเลข ใช้งานบ่อยในโปรแกรม จึงควรเข้าใจพื้นฐานเหล่านี้ให้ดี
+
(บวก): ใช้บวกตัวเลขสองตัว-
(ลบ): ใช้ลบตัวเลขสองตัว*
(คูณ): ใช้คูณตัวเลขสองตัว/
(หาร): ใช้หารตัวเลขสองตัว (ถ้าเป็นจำนวนเต็ม ผลลัพธ์จะปัดเศษทิ้ง)%
(หารเอาเศษ): ใช้หาค่าเศษที่เหลือจากการหาร
ตัวอย่าง:
int a = 10, b = 3;
int sum = a + b; // 13
int diff = a - b; // 7
int prod = a * b; // 30
int quot = a / b; // 3
int rem = a % b; // 1
2.2 โอเปอเรเตอร์เปรียบเทียบ
โอเปอเรเตอร์เปรียบเทียบจะใช้เปรียบเทียบค่าสองค่า แล้วคืนค่าจริง (1) หรือเท็จ (0) มักใช้ในเงื่อนไขและลูป
>
(มากกว่า): เป็นจริงถ้าค่าซ้ายมากกว่าค่าขวา<
(น้อยกว่า): เป็นจริงถ้าค่าซ้ายน้อยกว่าค่าขวา>=
(มากกว่าหรือเท่ากับ): เป็นจริงถ้าค่าซ้ายมากกว่าหรือเท่ากับค่าขวา<=
(น้อยกว่าหรือเท่ากับ): เป็นจริงถ้าค่าซ้ายน้อยกว่าหรือเท่ากับค่าขวา==
(เท่ากัน): เป็นจริงถ้าค่าซ้ายและขวาเท่ากัน!=
(ไม่เท่ากัน): เป็นจริงถ้าค่าซ้ายและขวาไม่เท่ากัน
int a = 5, b = 10;
if (a < b) {
printf("a น้อยกว่า b\n"); // จะแสดงผล
}

3. ลำดับความสำคัญและกฎการเชื่อมของโอเปอเรเตอร์
3.1 ลำดับความสำคัญของโอเปอเรเตอร์
ลำดับความสำคัญของโอเปอเรเตอร์จะเป็นตัวกำหนดว่าในนิพจน์ที่มีโอเปอเรเตอร์หลายตัว ตัวไหนจะถูกประเมินก่อน ตารางด้านล่างคือลำดับความสำคัญของโอเปอเรเตอร์บางส่วนในภาษา C เรียงจากลำดับสูงสุดไปต่ำสุด
ลำดับ | โอเปอเรเตอร์ | คำอธิบาย |
---|---|---|
1 | () [] -> . | เรียกฟังก์ชัน เข้าถึงอาร์เรย์ สมาชิกของพอยน์เตอร์ |
2 | ++ -- | เพิ่มค่า/ลดค่าทีละหนึ่ง (แบบ post-fix) |
3 | ++ -- | เพิ่มค่า/ลดค่าทีละหนึ่ง (แบบ prefix), โอเปอเรเตอร์เครื่องหมาย |
4 | * / % | คูณ, หาร, หาเศษ |
5 | + - | บวก, ลบ |
6 | << >> | บิตชิฟต์ |
7 | < <= > >= | โอเปอเรเตอร์เปรียบเทียบ |
8 | == != | เท่ากัน, ไม่เท่ากัน |
9 | & | บิต AND |
10 | ^ | บิต XOR |
11 | | | บิต OR |
12 | && | AND เชิงตรรกะ |
13 | || | OR เชิงตรรกะ |
14 | ? : | โอเปอเรเตอร์เงื่อนไข |
15 | = += -= | กำหนดค่า, กำหนดค่าแบบรวม |
16 | , | โอเปอเรเตอร์คอมม่า |
3.2 กฎการเชื่อมของโอเปอเรเตอร์
กฎการเชื่อม (Associativity) จะกำหนดว่าหากมีโอเปอเรเตอร์ลำดับเดียวกันหลายตัวในนิพจน์ จะประเมินจากด้านไหนก่อน โดยส่วนใหญ่เป็นเชื่อมซ้าย แต่บางโอเปอเรเตอร์ (เช่น โอเปอเรเตอร์กำหนดค่า และโอเปอเรเตอร์เงื่อนไข) เป็นเชื่อมขวา
- เชื่อมซ้าย: เช่น
*
,+
,-
จะประเมินจากซ้ายไปขวา - เชื่อมขวา: เช่นโอเปอเรเตอร์กำหนดค่า และ
? :
จะประเมินจากขวาไปซ้าย
int a = 5, b = 10, c = 15;
int result = a - b + c; // เชื่อมซ้าย (a - b) + c = 0
4. ข้อควรระวังเกี่ยวกับลำดับความสำคัญของโอเปอเรเตอร์บางประเภท
4.1 โอเปอเรเตอร์เชิงตรรกะ
โอเปอเรเตอร์ AND เชิงตรรกะ (&&
) และ OR เชิงตรรกะ (||
) มักใช้ในการเชื่อมเงื่อนไข โดย &&
จะมีลำดับความสำคัญสูงกว่า ||
ดังนั้นต้องระวังเวลาเขียนโค้ดดังนี้
int a = 1, b = 0, c = 1;
if (a && b || c) {
printf("Truen"); // จะแสดงผล
}
ในตัวอย่างนี้ a && b
จะถูกประเมินก่อน แล้วผลลัพธ์นั้นจะนำมา OR กับ c
หากต้องการลำดับที่แน่นอนควรใช้วงเล็บเพื่อระบุ
if ((a && b) || c) {
// ชัดเจนกว่า
}
4.2 โอเปอเรเตอร์บิต
โอเปอเรเตอร์บิต (&
, |
, ^
) ใช้สำหรับการดำเนินการระดับบิต โดยปกติจะมีลำดับความสำคัญต่ำกว่าโอเปอเรเตอร์ทางคณิตศาสตร์และเปรียบเทียบ ดังนั้นหากนิพจน์ซับซ้อนควรระวัง
int x = 5; // 0101
int y = 3; // 0011
int result = x & y; // 0001 (AND บิต)
5. ตัวอย่างโปรแกรมจริง
ตัวอย่างโค้ดที่อาจทำให้เข้าใจผิดเกี่ยวกับลำดับความสำคัญของโอเปอเรเตอร์ โดยเฉพาะ ||
และ &&
#include <stdio.h>
int main() {
int a = 0, b = 1;
if (a == 0 || a == 1 && b == 0) {
printf("Truen"); // จะแสดงผล
}
return 0;
}
ในตัวอย่างนี้ a == 1 && b == 0
จะถูกประเมินก่อน ซึ่งอาจไม่ได้ผลลัพธ์ตามที่ตั้งใจไว้ หากต้องการผลลัพธ์ที่ถูกต้องควรใช้วงเล็บระบุลำดับการประเมิน
if ((a == 0 || a == 1) && b == 0) {
printf("Truen");
}
6. สรุป
ลำดับความสำคัญของโอเปอเรเตอร์ในภาษา C เป็นสิ่งสำคัญต่อการทำงานของโปรแกรมอย่างถูกต้อง เมื่อต้องจัดการกับนิพจน์ที่ซับซ้อนควรเข้าใจลำดับความสำคัญและกฎการเชื่อมให้ดี และใช้วงเล็บระบุลำดับเมื่อจำเป็น จะช่วยป้องกันบั๊กและได้โค้ดที่ถูกต้องและมีประสิทธิภาพมากขึ้น