Con trỏ hàm

Chúng ta có thế lấy địa chỉ một hàm và lưu vào trong một con trỏ hàm. Sau đó con trỏ có thế được sử dụng đế gọi gián tiếp hàm. Ví dụ,

int (*Compare const char*, const char*);

Định nghĩa một con trỏ hàm tên là Compare có thể giữ địa chỉ của bất kỳ hàm nào nhận hai con trỏ ký tự hằng như là các đối số và trả về một số nguyên. Ví dụ hàm thư viện so sánh chuồi stranpthực hiện như thế. Vì thế:

Compare= &strcmp; // Compare trỏ tới hàm strcmp

Toán tử & không cần thiết và có thế bổ qua:

Compare= strcmp; // Compare trỏ tới hàm strcmp

Một lựa chọn khác là con trỏ có thể được định nghĩa và khởi tạo một lần:

int (*CompareX const char*, const char*)= strcmp;

Khi địa chỉ hàm được gán tới con trỏ hàm thì hai kiểu phải khớp với nhau. Định nghĩa trên là họp lệ bởi vì hàm strcmp có một nguyên mầu hàm khớp với hàm.

int strcmp(const char*, const char*);

Với định nghĩa trên của Compare thì hàm strcmp hoặc có thế được gọi trực tiếp hoặc có thể được gọi gián tiếp thông qua Compare. Ba lời gọi hàm sau là tương đương:

strcmp("Tom", "Tim"); // gọi trực tiếp

(*CompareXTomVTim"); //gọi gian tiếp

Compare("Tom", "Tim"); // gọi gián tiếp (ngắn gọn)

Cách sử dụng chung của con trỏ hàm là truyền nó như một đối số tới một hàm khác; bởi vì thông thường các hàm sau yêu cầu các phiên bản khác nhau của hàm trước trong các tình huống khác nhau. Một ví dụ đỗ hiểu là hàm tìm kiếm nhị phân thông qua một mảng sắp xếp các chuỗi. Hàm này có thế sử dụng một hàm so sánh (như là strcmp) để so sánh chuỗi tìm kiếm ngược lại chuồi của màng. Điều này có thể không thích hợp đối với tất cả các trường hợp. Ví dụ, hàm strcmp là phân biệt chữ hoa hay chữ thường. Neu chúng ta thực hiện tìm kiếm theo cách không phân biệt dạng chữ sau đó một hàm so sánh khác sẽ được cần.

Đoạn mã sau so sánh một tham số của hàm tìm kiếm, chúng ta có thế làm cho hàm tìm kiếm độc lập với hàm so sánh.

1. int BinSearch(char *item, char *table[], int n, int (*Compare)(const char *, const char*))

2. {

3. int bot = 0;

4. int top = n - 1;

5. int mid, cmp;

6.

7. while (bot <= top)

8. {

9. mid = (bot + top) / 2;

10. if ((cmp = Compare(item, table[mid])) == 0)

11. return mid; // Trả về chỉ số hạng mục

12. else if (cmp < 0)

13. top = mid - 1; // Giới hạn tìm kiếm tới nửa thấp hơn

14. else

15. bot = mid + 1; // Giới hạn tìm kiếm tới nửa cao hơn

16. }

17. return -1; // Không tim thấy

18. }

Chú giải:

  • Dòng số 1 tìm kiếm nhị phân là một giải thuật nổi tiếng để tìm kiếm thông qua một danh sách các hạng mục đã được sắp xếp. Danh sách tìm kiếm được biểu diễn bởi table - một mảng các chuồi có kích thước a Hạng mục tìm kiếm được biếu thị bởi item.
  • Dòng 1 cũng có Compare là con trỏ hàm được sử dụng để so sánh item với các phần tử của

mảng.

  • Dòng 7 mồi vòng lặp, việc tìm kiếm được giảm đi phân nữa. Điều này được lặp lại cho tới khi hai đầu tìm kiếm giao nhau (được biểu thị bởi bot và top) hoặc cho tới khi một so khớp được tìm thấy.
  • Dòng 9 chứa hạng mục được so sánh với mục ở giữa của mảng.
  • Dòng 11 nếu item khớp với hạng mục giữa thì trả về chi mục của phần sau.
  • Dòng 12 nếu item nhỏ hơn hạng mục giữa thì sau đó tìm kiếm được giới hạn tới nữa thấp hơn của mảng.
  • Dòng 15 nếu item lớn hơn hạng mục giữa thì sau đó tìm kiếm được giới hạn tới nữa cao hơn của mảng.
  • Dòng 17 Trả về -1 để chỉ định rằng không có một hạng mục so khớp.

Ví dụ sau trình bày hàm BinSearch có thể được gọi với strcmp được truyền như hàm so sánh như thế nào:

char *cities[] = {“Boston”, “London”, “Sydney”, “Tokyo”};

cout << BinSearch(“Sydney”, cities, 4, strcmp) << endl;

Điều này sẽ xuất ra 2 như được mong đợi.

results matching ""

    No results matching ""