Tóm tắt bài học
9.12 Con trỏ đến hàm
Một đặc tính mạnh mẽ của C vẫn chưa được đề cập, chính là con trỏ hàm. Dù rằng một hàm không phải là một biến, nhưng nó có địa chỉ vật lý trong bộ nhớ nơi có thể gán cho một con trỏ.
Một địa chỉ hàm là điểm đi vào của hàm và con trỏ hàm có thể được sử dụng để gọi hàm.
Để hiểu các con trỏ hàm làm việc như thế nào, thật sự cần phải hiểu thật rõ một hàm được biên dịch và được gọi như thế nào trong C. Khi mỗi hàm được biên dịch, mã nguồn được chuyển thành mã đối tượng và một điểm đi vào của hàm được thiết lập. Khi một lời gọi được thực hiện đến một hàm, một lời gọi ngôn ngữ máy được thực hiện để chuyển điều khiển đến điểm đi vào của hàm. Vì vậy, nếu một con trỏ chứa địa chỉ của điểm đi vào của hàm, nó có thể được dùng để gọi hàm đó. Địa chỉ của một hàm có thể lấy được bằng cách sử dụng tên hàm không có dấu ngoặc () hay bất kỳ đối số nào. Chương trình sau sẽ minh họa khái niệm của con trỏ hàm.
#include <stdio.h>
#include <string.h>
void check(char *a, char *b, int (*cmp)());
main()
{
char s1[80], s2[80];
int (*p)();
p = strcmp;
gets(s1);
gets(s2);
check(s1, s2, p);
}
void check(char *a, char *b, int (*cmp)()) {printf(“Testing for equality \n”);
if(!(*cmp)(a, b)) printf(“Equal”);
else
printf(“Not Equal”);
}
Hàm check() được gọi bằng cách truyền hai con trỏ ký tự và một con trỏ hàm. Trong hàm check(), các đối số được khai báo là các con trỏ ký tự và một hàm con trỏ. Chú ý cách một hàm con trỏ được khai báo. Cú pháp tương tự được dùng khi khai báo các hàm con trỏ khác bất luận đó là kiểu trả về của hàm. Cặp dấu ngoặc () bao quanh *cmp là cần thiết để chương trình biên dịch hiểu câu lệnh này một cách rõ ràng.
Tóm tắt bài học
Trong C, các hàm được dùng để thực thi một chuỗi các chỉ thị nhiều hơn một lần.
type_specifier xác định kiểu dữ liệu của giá trị sẽ được trả về bởi hàm.
Các đối số tới hàm có thể là các hằng, biến, biểu thức hay các hàm.
Các đối số còn được gọi là các đối số thực trong hàm gọi và đối số hình thức trong hàm được gọi.
Một hàm phải được khai báo trong hàm main(), trước khi nó được định nghĩa hay sử dụng.
Trong C, mặc định, tất cả các đối số của hàm được truyền bằng giá trị.
Có ba loại biến cơ bản: biến cục bộ, tham số hình thức và biến toàn cục.
• Biến cục bộ được khai báo bên trong một hàm.
• Tham số hình thức được khai báo trong định nghĩa của tham số hàm.
• Biến toàn cục được khai báo bên ngoài tất cả các hàm.
Lớp lưu trữ định nghĩa hai đặc tính của biến; thời gian sống của biến và tầm nhìn hay phạm vi.
Các biến tự động giống như các biến cục bộ.
Tất cả các biến toàn cục được khai báo trong một tập tin và giống với các biến được khai báo extern trong tất cả các tập tin.
Các biến static là các biến cố định bên trong các hàm hoặc tập tin của chúng.
Không giống các biến toàn cục, các biến tĩnh không được nhận biết bên ngoài hàm hoặc tập tin của nó, nhưng chúng duy trì được các giá trị của chúng giữa các lần gọi.
Nếu một giá trị đặc biệt được sử dụng thường xuyên, có thể dùng lớp lưu trữ register cho nó.
Cũng giống như các biến trong các chương trình có nhiều tập tin, các hàm cũng có thể được định nghĩa là static hay external.
Mã lệnh và dữ liệu được định nghĩa bên trong một hàm không thể tương tác với mã lệnh hay dữ liệu được định nghĩa trong hàm khác bởi vì hai hàm có phạm vi khác nhau.
Một hàm không thể được định nghĩa bên trong một hàm khác.
Một nguyên mẫu hàm là một sự khai báo hàm để chỉ ra các kiểu dữ liệu của các đối số.
Lời gọi một hàm từ bên trong một hàm khác được gọi là sự của lời gọi hàm.
Một con trỏ hàm có thể được dùng để gọi một hàm.