Game Studio
Liên kế mạng xã hội

Game Studio


Xây Dựng Hàm Có Tham Số Tuỳ Ý Trong C

Giới thiệu

Nếu để ý, bạn sẽ thấy hàm printf, scanf và một số hàm khác trong ngôn ngữ C có tập danh sách tham số khá kì lạ. Số lượng tham số của các hàm này là không giới hạn, cả về kiểu dữ liệu lẫn số lượng tham số. Trong một số trường hợp, các hàm có dạng như thế tỏ ra khá hiệu quả trong việc xử lý dữ liệu. Mặc dù chúng ta hoàn toàn có thể dùng một số cách thay thế, nhưng code sẽ không đẹp và trông rối mắt hơn. Bài viết này sẽ giới thiệu đến các bạn cách để hiện thực những hàm tương tự như thế trong ngôn ngữ C.

Tiền đề bài viết

Xuất phát từ mục đích cá nhân, tôi muốn tìm một giải pháp để có thể xử lý các chuỗi ký tự truyền vào, cụ thể hơn là danh sách các đường dẫn đến thư viện hình ảnh trong project. Tôi đã tra cứu và tìm giải pháp khá nhiều, cuối cùng cũng tìm được chính xác những gì cần thiết. Bài viết này là món quà mà tôi dành tặng đến các bạn trong nhóm phát triển dự án của tôi, đồng thời cũng muốn chia sẻ kiến thức hay và lạ đến cho mọi người.

Đối tượng hướng đến

Bài viết có sử dụng các hàm và thư viện nâng cao trong ngôn ngữ C. Do đó, đối tượng hướng đến của bài viết là các bạn lập trình viên có kinh nghiệm trong lập trình với ngôn ngữ C. Các đối tượng khác vui lòng đọc bài ở mức độ tham khảo.

Yêu cầu

Đối với hàm có danh sách tham số tuỳ ý, các yêu cầu sau phải được thoả mãn:

  • Kiểu dữ liệu của một hoặc một vài tham số đầu tiên phải rõ ràng. Kiểu dữ liệu có thể là các kiểu dữ liệu cơ bản hoặc do người dùng tự định nghĩa trước khi xây dựng hàm.
  • Các tham số tiếp theo được thể hiện bằng dấu ba chấm “…”. Số lượng tham số là tuỳ ý, do đó phụ thuộc vào tham số đầu tiên mà chúng ta sẽ xử lý các tham số còn lại.

Cách làm trên là phổ biến, dễ hiện thực và có tính tái sử dụng cao. Tuy nhiên trong một số trường hợp, ta có thể không sử dụng tham số đầu tiên mà dùng một phương pháp nào đó, miễn là có thể đánh dấu và nhận biết thời điểm kết thúc danh sách tham số.

Xây dựng hàm

Trước tiên, để xây dựng hàm có danh sách tham số tuỳ ý, ta cần khai báo thư viện :

  1. #include

Nguyên tắc xây dựng hàm như sau:

  • Định nghĩa một hàm với tham số cuối cùng là dấu ba chấm “…”. Một hoặc các tham số trước đó phải có dấu hiệu cho biết việc kết thúc của chuỗi tham số.
  • Khởi tạo biến va_list. Biến này được định nghĩa sẵn trong thư viện , dùng để lưu trữ danh sách tham số đầu vào.
  • Sử dụng macro va_start cùng với dấu hiệu nhận biết số lượng tham số và kiểu dữ liệu (thường là một biến int) để khởi tạo danh sách tham số.
  • Sử dụng macro va_arg và biến va_list đã khởi tạo để truy cập và trích xuất từng tham số.
  • Sử dụng macro va_end để giải phóng bộ nhớ đã cấp phát cho va_list.

Ví dụ minh hoạ

Minh hoạ cho hàm tìm số lớn nhất trong các số nguyên. Đối số đầu tiên truyền vào hàm là số lượng các số nguyên sẽ truyền vào.

  1. int FindMax(int _count, ...)
  2. {
  3. va_list ap;
  4. va_start(ap, _count);
  5.  
  6. int greater = va_arg(ap, int);
  7.  
  8. for(int i = 1; i < _count; i++)
  9. {
  10. int val = va_arg(ap, int);
  11. greater = (greater > val) ? greater : val;
  12. }
  13.  
  14. va_end(ap);
  15. return greater;
  16. }
  17.  
  18. int main()
  19. {
  20. int m = FindMax(7, 489, 2258, 5622, 7411, 892, 1045, 6081);
  21. printf("The greatest one is : %d\n", m);
  22.  
  23. return 0;
  24. }

Minh hoạ việc in các chuỗi kí tự ra màn hình. Điều kiện nhận biết là kí tự NULL ở tham số cuối cùng.

  1. void PrintLines(char* _firstStr, ...)
  2. {
  3. char* str;
  4. va_list ap;
  5. va_start(ap, _firstStr);
  6.  
  7. str = _firstStr;
  8.  
  9. while(str != NULL)
  10. {
  11. printf("%s\n", str);
  12. str = va_arg(ap, char*);
  13. }
  14.  
  15. va_end(ap);
  16. }
  17.  
  18. int main()
  19. {
  20. PrintLines("STDIO", "Rye", "Welcome", NULL);
  21. return 0;
  22. }

Chia sẻ

Kiến thức là vô tận, do đó rất mong muốn được các bạn góp ý và chia sẻ để bài viết thêm hoàn thiện hơn. Trong quá trình hoàn thiện dự án, tôi đã tìm hiểu được một số kĩ thuật hay. Chắc chắn rằng trong tương lai gần tôi sẽ chia sẻ những kiến thức ấy với mọi người.

Theo: Stdio