Hàm (Function) là gì?
Khối code độc lập thực hiện một nhiệm vụ cụ thể. Giúp: tái sử dụng, giảm độ dài chương trình, dễ debug, lập trình module (top-down).
Cấu trúc hàm
kiểu_trả_về tên_hàm(danh_sách_tham_số) {
// Thân hàm
return giá_trị; // Bắt buộc nếu không phải void
}
Các thành phần
| Thành phần | Mô tả | Ví dụ |
|---|---|---|
| Kiểu trả về | Kiểu dữ liệu của kết quả | int, float, void, struct... |
| Tên hàm | Định danh | tinhTong, main, printf |
| Tham số | Đầu vào (có thể không có) | (int a, int b) |
| Thân hàm | Code thực thi | { return a+b; } |
| Return | Trả kết quả cho caller | return a+b; |
Khai báo nguyên mẫu (Prototype)
// Trước main hoặc trong header
int tong(int a, int b);
float dtHinhTron(float r);
void inMenu(void); // void rõ ràng: không tham số
Chương trình cơ bản
#include <stdio.h>
// Prototype
int tong(int a, int b);
int main() {
int x = 10, y = 20;
int kq = tong(x, y); // Gọi hàm
printf("Tong = %d\n", kq);
return 0;
}
// Definition
int tong(int a, int b) {
return a + b; // Trả về giá trị
}
Return - Trả về giá trị
- Mỗi hàm non-void phải có
return(trừ main - tự động return 0) - Chỉ trả về 1 giá trị
- Giá trị trả về có thể bỏ qua:
tong(1,2);(hợp lệ nhưng lãng phí) returnthoát khỏi hàm ngay lập tức
Ví dụ: Hàm tính tổng mảng
int tongMang(int arr[], int n) {
int sum = 0;
for (int i = 0; i < n; i++) sum += arr[i];
return sum;
}
Trả về nhiều giá trị
C chỉ return 1 giá trị. Cách giải quyết:
Cách 1: Con trỏ (Output parameter)
void tinhToan(int a, int b, int *tong, int *hieu, int *tich, float *thuong) {
*tong = a + b;
*hieu = a - b;
*tich = a * b;
*thuong = (float)a / b;
}
Cách 2: Trả về Struct
struct KetQua {
int tong, hieu, tich;
float thuong;
};
struct KetQua tinhToan(int a, int b) {
return (struct KetQua){a+b, a-b, a*b, (float)a/b};
}
Đặc điểm quan trọng
| Đặc điểm | Giải thích |
|---|---|
| Tái sử dụng | Gọi nhiều lần với tham số khác nhau |
| Độ dài code | Giảm đáng kể |
| Debug | Dễ isolate lỗi theo hàm |
| Module | Hàm = đơn vị độc lập |
| Đệ quy | Hàm gọi chính nó |
| Con trỏ hàm | Hàm là dữ liệu, truyền như tham số |
Hàm main() đặc biệt
// 2 dạng chuẩn
int main(void) { return 0; }
int main(int argc, char *argv[]) { return 0; }
// Nếu không viết return 0; → C99 tự động return 0
// return khác 0 = báo lỗi cho OS/shell
Lưu ý thường gặp
- Quên
return→ Warning "control reaches end of non-void function" - Trả về địa chỉ biến local → Dangling pointer (biến chết khi hàm kết thúc)
- Hàm không tham số:
void f(void)(C) vsvoid f()(C++/old C) - Default return type = int (C89, deprecated, không dùng)
Best Practice
- Luôn viết prototype trước khi dùng (hoặc trong header)
- Dùng
constcho tham số chỉ đọc - Hàm ngắn, làm 1 việc (Single Responsibility)
- Tên hàm động từ:
tinhTong,docFile,sapXep - Tránh biến global, dùng tham số
- Kiểm tra con trỏ NULL trước khi dereference