Error handling with return codes · Xử lý lỗi với mã trả về
C has no try/except
- Some languages throw exceptions when something goes wrong. C does not have exceptions.
- Instead, a C function reports trouble through its return value — a status code.
- The caller checks that code after every call and decides what to do.
C không có try/except
- Một số ngôn ngữ ném ngoại lệ (throw exceptions) khi có lỗi xảy ra. C không có ngoại lệ.
- Thay vào đó, một hàm C báo cáo sự cố thông qua giá trị trả về — mã trạng thái.
- Người gọi kiểm tra mã này sau mỗi lần gọi và quyết định phải làm gì.
Return a status code
- A common rule: return
0for success and a negative number like-1for failure. - So
int do_thing(...)returns0when it worked,-1when it could not. - The real "answer" is then handed back a different way (see the next step).
Trả về mã trạng thái
- Một quy tắc phổ biến: trả về
0cho thành công và một số âm như-1cho thất bại. - Vì vậy
int do_thing(...)trả về0khi hoạt động tốt,-1khi không thể. - "Đáp án" thực tế sau đó được trao lại theo cách khác (xem bước tiếp theo).
Reporting the answer through an out-pointer
- If the return value is a status code, where does the real result go? Through an out-pointer.
- The caller passes the address of a variable; the function writes the answer with
*. - On failure, the function returns
-1and simply leaves that variable alone.
Báo cáo đáp án thông qua out-pointer
- Nếu giá trị trả về là mã trạng thái, thì kết quả thực tế đi đâu? Thông qua một out-pointer (con trỏ ra).
- Người gọi truyền địa chỉ của một biến; hàm viết kết quả với
*. - Khi thất bại, hàm trả về
-1và không thay đổi biến đó.
Sentinels for "no value"
- A sentinel is a special value that means "nothing here":
-1for an index,NULLfor a pointer. - Functions use sentinels so the caller can tell success from failure with a simple check.
- Always check for the sentinel before you trust the result.
Sentinels cho "không có giá trị"
- Một sentinel là một giá trị đặc biệt có nghĩa là "không có gì ở đây":
-1cho chỉ số,NULLcho con trỏ. - Các hàm sử dụng sentinels để người gọi có thể phân biệt thành công hay thất bại qua một phép kiểm tra đơn giản.
- Luôn kiểm tra sentinel trước khi tin vào kết quả.
#include <stdio.h>
int safe_div(int a, int b, int *result) {
if (b == 0) return -1; // failure: cannot divide by zero
*result = a / b; // success: hand back the answer
return 0;
}
int main(void) {
int r;
if (safe_div(10, 2, &r) == 0) {
printf("%d\n", r); // 5
}
return 0;
}
Common mistakes
- Return a non-zero code from
mainto signal an error. - Check the return value of any function that can fail.
Lỗi thường gặp
- Trả về mã khác 0 từ
mainđể báo lỗi. - Kiểm tra giá trị trả về của bất kỳ hàm nào có thể thất bại.
Now you try
- Return
0on success and-1on failure, and write the real answer through the out-pointer. - On failure, do not touch the out-pointer. Do not write a
main— the checker provides one.
Bây giờ bạn thử
- Trả về
0khi thành công và-1khi thất bại, và viết câu trả lời thực tế thông qua out-pointer. - Khi thất bại, đừng chạm vào out-pointer. Đừng viết một
main— bộ kiểm tra sẽ cung cấp một.
Complete int safe_div(int a, int b, int *result): if b is 0, return -1 and leave *result alone. Otherwise store a / b in *result and return 0. Do not write a main. · Hoàn thành int safe_div(int a, int b, int *result): nếu b là 0, hãy trả về -1 và để nguyên *result. Ngược lại, lưu a / b vào *result và trả về 0. Không viết một main.
Click Run to see the output here. · Nhấn Chạy để xem kết quả ở đây.
Complete int parse_int(const char *s, int *out): if s is a valid integer (digits, with an optional leading -), store its value in *out and return 0; otherwise return -1. Do not write a main. · Hoàn thành int parse_int(const char *s, int *out): nếu s là một số nguyên hợp lệ (các chữ số, có thể có dấu - ở đầu), hãy lưu giá trị của nó vào *out và trả về 0; ngược lại, trả về -1. Không viết một main.
Click Run to see the output here. · Nhấn Chạy để xem kết quả ở đây.
Complete int withdraw(int balance, int amount, int *new_balance): if amount is more than balance, return -1. Otherwise set *new_balance to balance - amount and return 0. Do not write a main. · Hoàn thành int withdraw(int balance, int amount, int *new_balance): nếu amount lớn hơn balance, trả về -1. Ngược lại, gán *new_balance cho balance - amount và trả về 0. Không viết một main.
Click Run to see the output here. · Nhấn Chạy để xem kết quả ở đây.