Lỗi logic là gì?
Lỗi logic (logic error) là sai sót trong cách suy luận của chương trình, khiến nó cho ra kết quả sai mà không bị dừng đột ngột hay hiện thông báo lỗi nào. Code hợp lệ và mọi dòng đều chạy, nhưng chương trình không làm đúng điều lập trình viên muốn.
Cập nhật 24 tháng 9, 2026
Ba điểm kiểm tra 80, 90 và 100 có điểm trung bình là 90. Chương trình này chạy không một lời phàn nàn nhưng lại in ra một con số khác:
Average: 203.33333333333334
Python làm đúng y như dòng code viết. Phép chia được thực hiện trước phép cộng, nên chỉ điểm cuối cùng bị chia cho 3, và kết quả là 80 + 90 + 33,33. Lập trình viên muốn viết (scores[0] + scores[1] + scores[2]) / 3. Thêm dấu ngoặc vào và chương trình in ra Average: 90.0.
Vì sao không có thông báo lỗi
Máy tính kiểm tra xem code có hợp lệ không, chứ không kiểm tra code có đúng không. Bộ phân tích cú pháp (parser) kiểm tra ngữ pháp, nhờ đó bắt được lỗi cú pháp. Môi trường thực thi kiểm tra từng phép toán, nhờ đó bắt được lỗi thực thi như chia cho 0. Cộng ba số và chia một trong số đó cho 3 là ngữ pháp hợp lệ và là phép toán hợp lệ, nên cả hai bước kiểm tra đều qua.
Chỉ người viết chương trình mới biết nó phải tính điểm trung bình. Ý định đó không nằm ở đâu trong code, nên không công cụ nào so sánh được kết quả với nó. Lỗi logic chính là khoảng cách giữa điều bạn bảo máy tính làm và điều bạn thực sự muốn nó làm.
Nguyên nhân thường gặp của lỗi logic
Phần lớn lỗi logic đến từ một danh sách ngắn các mẫu quen thuộc.
- Lỗi lệch một đơn vị. Vòng lặp chạy thừa hoặc thiếu một lần.
range(1, 5)cho ra 1, 2, 3 và 4, vì giá trị cuối bị loại trừ. Xem lặp. - Thứ tự ưu tiên toán tử.
a + b / 2chỉ chiab, như ví dụ điểm trung bình ở trên. - So sánh sai. Dùng
<khi cần<=, hoặcandkhi cầnor. Điều kiện là các biểu thức boolean, và chỉ một toán tử sai cũng đảo ngược kết quả với một số đầu vào. - Điều kiện sai thứ tự. Trong chuỗi
ifvàelif, điều kiện đúng đầu tiên sẽ thắng, nên một phép kiểm tra rộng đặt lên đầu sẽ che mất các phép kiểm tra hẹp hơn bên dưới. - Dùng nhầm biến. Cập nhật
totaltrong vòng lặp nhưng lại in rasubtotal. - Giả định sai về số.
0.1 + 0.2 == 0.3làFalsetrong Python, Java và JavaScript, vì số thực dấu phẩy động chỉ là giá trị xấp xỉ.7 // 2bằng 3, không phải 3,5.
Đây là lỗi sai thứ tự điều kiện. Điểm 95 lẽ ra phải là A:
D
D
F
95 lớn hơn hoặc bằng 60, nên nhánh đầu tiên thắng và elif không bao giờ được xét tới. Đặt ngưỡng cao nhất lên đầu và mọi kết quả đều đúng.
Các loại lỗi trong lập trình
Lỗi lập trình thường được chia thành ba loại, theo thời điểm chúng xuất hiện và thứ báo ra chúng.
| Lỗi cú pháp | Lỗi thực thi | Lỗi logic | |
|---|---|---|---|
| Khi nào xuất hiện | Trước khi chương trình chạy | Trong lúc chạy | Trong lúc chạy, hoặc không bao giờ bị phát hiện |
| Thứ phát hiện ra | Parser hoặc trình biên dịch | Môi trường thực thi hoặc hệ điều hành | Con người hoặc một bài test |
| Chương trình có chạy không? | Không | Đến dòng gây lỗi | Có, đến cuối |
| Thông báo lỗi | Có, kèm số dòng | Có, kèm traceback | Không có |
| Ví dụ Python | if x > 3 thiếu dấu hai chấm | 10 / 0 | a + b / 2 để tính trung bình |
| Cách tìm | Đọc thông báo | Đọc traceback | So sánh đầu ra với đáp án đã biết |
Một số sách liệt kê nhiều loại hơn, và phần lớn đều nằm gọn trong ba loại này. Lỗi kiểu mà trình biên dịch Java từ chối, như incompatible types: String cannot be converted to int, được phát hiện lúc biên dịch giống lỗi cú pháp, và một số sách gọi nó là lỗi ngữ nghĩa. Lỗi liên kết (linker error) xảy ra ở bước cuối khi build một chương trình C hoặc C++, khi một hàm đã được khai báo nhưng không tìm thấy code của nó ở đâu cả. Lỗi số học, lỗi tài nguyên và lỗi tệp, như chia cho 0, hết bộ nhớ hay mở một tệp không tồn tại, đều là lỗi thực thi. Một số khóa học cũng dùng thuật ngữ "lỗi ngữ nghĩa" như tên gọi khác của lỗi logic, nên hãy xem giáo trình đang dùng nghĩa nào.
Cách tìm lỗi logic
- Thử với một đáp án bạn đã biết. Tự tính kết quả đúng bằng tay với một đầu vào nhỏ, rồi so sánh. Ba điểm số dễ kiểm tra hơn ba nghìn.
- In ra các giá trị ở giữa. In
scorevà nhánh được chọn, hoặc bộ đếm vòng lặp ở mỗi lượt, sẽ cho thấy chính xác bước mà thực tế đi lệch khỏi kế hoạch của bạn. - Chạy từng bước bằng debugger. Đặt breakpoint và chạy từng dòng một cũng cho kết quả tương tự mà không cần sửa code.
- Thử các trường hợp biên. Thử 0, 1, giá trị lớn nhất, danh sách rỗng và đúng giá trị ngưỡng (60 và 90 trong ví dụ chấm điểm).
- Giải thích code thành lời. Mô tả từng dòng cho người khác, hoặc cho một chú vịt cao su, buộc bạn phải nói dòng đó thực sự làm gì thay vì điều bạn giả định nó làm.
Câu lệnh assert biến một đáp án đã biết thành một bước kiểm tra tự động. Nó không làm gì khi điều kiện đúng và dừng chương trình khi điều kiện sai:
Traceback (most recent call last):
File "main.py", line 10, in <module>
assert grade(95) == "A", "95 should be an A"
^^^^^^^^^^^^^^^^
AssertionError: 95 should be an A
Một bài test thất bại biến lỗi logic im lặng thành lỗi ồn ào có kèm số dòng. Đó chính là toàn bộ ý tưởng đằng sau unit test.
Lỗi logic trong các ngôn ngữ khác
Các mẫu lỗi ở đâu cũng giống nhau, nhưng mỗi ngôn ngữ có cái bẫy riêng. Trong JavaScript, "5" + 3 là chuỗi "53", còn "5" - 3 là số 2, nên một giá trị đọc từ form dưới dạng văn bản có thể bị cộng sai mà không báo lỗi gì. Trong C, if (x = 5) gán 5 cho x và luôn đúng. Clang mặc định cảnh báo điều này (using the result of an assignment as a condition without parentheses), nhưng code vẫn biên dịch và chạy, nên hãy đọc cảnh báo của trình biên dịch nghiêm túc như đọc lỗi.
Đọc tiếp
So sánh trang này với các trang lỗi cú pháp và lỗi thực thi để thấy mỗi loại được báo ra thế nào. Vòng lặp là nơi lỗi lệch một đơn vị hay xuất hiện, nên trang lặp và hướng dẫn Python về vòng lặp for là những bài nên đọc tiếp. Để luyện tìm kết quả sai trong các bài tập thực tế, hãy thử khóa học Python.
Câu hỏi thường gặp
Lỗi cú pháp và lỗi logic khác nhau thế nào?
Lỗi cú pháp vi phạm ngữ pháp của ngôn ngữ, nên chương trình bị từ chối trước khi chạy và bạn nhận được thông báo kèm số dòng. Lỗi logic tuân thủ ngữ pháp hoàn toàn và chạy đến cuối, nhưng kết quả sai và không có thông báo nào cả. Bạn tìm lỗi cú pháp bằng cách đọc thông báo; bạn tìm lỗi logic bằng cách kiểm tra đầu ra.
Lỗi logic trong Python là gì?
range(1, 5) khi bạn muốn từ 1 đến 5 tính cả 5, a + b / 2 khi bạn muốn (a + b) / 2, và các nhánh if được kiểm tra sai thứ tự. Python không thể phát hiện chúng, vì nó không có cách nào biết bạn muốn gì.5 loại lỗi trong lập trình là gì?
Một danh sách năm loại thường gặp gồm lỗi cú pháp, lỗi ngữ nghĩa (lỗi kiểu), lỗi liên kết (linker), lỗi thực thi và lỗi logic. Ba loại đầu được phát hiện khi chương trình đang được build, lỗi thực thi xuất hiện khi chương trình chạy, còn lỗi logic chỉ lộ ra qua kết quả sai. Nhiều khóa học chỉ dạy ba loại: cú pháp, thực thi và logic.
Lỗi logic có phải là bug không?
Có. Bug là bất kỳ khiếm khuyết nào khiến chương trình hoạt động khác với ý định, và lỗi logic là loại phổ biến nhất. Chương trình dừng đột ngột hay thông báo lỗi cũng là bug, nhưng chúng tự lộ diện, còn lỗi logic phải được con người hoặc một bài test phát hiện.
Vì sao lỗi logic khó tìm?
Vì không có gì chỉ ra chúng. Không có số dòng, không có thông báo, và kết quả sai có thể trông hợp lý, như điểm trung bình 203 của ba bài kiểm tra mà không ai kiểm tra lại. Lỗi logic được tìm ra bằng cách so sánh đầu ra với một đáp án bạn đã biết trước, đó là lý do các bài test có kết quả biết trước rất quan trọng.