Giả sử chúng ta muốn tạo các hàm có thể nhận số lượng đối số thay đổi (không cố định). Chúng ta cần ba hàm: sum(), max() và min() để tính tổng, tìm giá trị lớn nhất và nhỏ nhất của các số cho trước. Mỗi hàm sẽ nhận số lượng đối số (count) làm tham số đầu tiên. Để định nghĩa loại hàm này, ta sử dụng ba chấm (...) trong danh sách tham số và cần include thư viện stdarg.h. Đây gọi là hàm variadic (hàm biến đổi).
Để truy cập các đối số biến đổi, ta sử dụng bốn macro:
- va_list: Lưu trữ tất cả các đối số được truyền vào
- va_start: Khởi tạo việc truy cập đối số biến đổi
- va_arg: Lấy đối số tiếp theo với kiểu dữ liệu chỉ định
- va_end: Kết thúc việc truy cập danh sách đối số biến đổi
Ví dụ gọi hàm:
- sum(5, 5, 2, 8, 9, 3) → 27 (tổng 5 số)
- max(3, 5, 9, 2) → 9 (max của 3 số)
- min(6, 8, 5, 2, 6, 7, 9) → 2 (min của 6 số)
Giải thuật
- Hàm sum(): Khởi tạo va_list, duyệt cnt lần, cộng dồn va_arg(ap, int)
- Hàm min(): Khởi tạo minimum = giá trị lớn, duyệt cnt lần, cập nhật nếu hiện tại nhỏ hơn
- Hàm max(): Khởi tạo maximum = 0, duyệt cnt lần, cập nhật nếu hiện tại lớn hơn
- Mọi hàm đều kết thúc bằng va_end(ap)
Ví dụ minh họa
#include <stdio.h>
#include <stdarg.h>
int sum(int cnt, ...) {
va_list ap;
int i, n = 0;
va_start(ap, cnt);
for (i = 0; i < cnt; i++) {
n += va_arg(ap, int);
}
va_end(ap);
return n;
}
int min(int cnt, ...) {
va_list ap;
int i, current, minimum = 99999;
va_start(ap, cnt);
for (i = 0; i < cnt; i++) {
current = va_arg(ap, int);
if (current < minimum) minimum = current;
}
va_end(ap);
return minimum;
}
int max(int cnt, ...) {
va_list ap;
int i, current, maximum = 0;
va_start(ap, cnt);
for (i = 0; i < cnt; i++) {
current = va_arg(ap, int);
if (current > maximum) maximum = current;
}
va_end(ap);
return maximum;
}
int main() {
printf("%d\n", sum(5, 5, 2, 8, 9, 3));
printf("%d\n", max(3, 5, 9, 2));
printf("%d\n", min(6, 8, 5, 2, 6, 7, 9));
return 0;
}
Đầu vào
sum(5, 5, 2, 8, 9, 3) max(3, 5, 9, 2) min(6, 8, 5, 2, 6, 7, 9)
Đầu ra
27 9 2