Cách biên dịch và gọi một hàm trong C

Một phần của tài liệu giao trinh C(dttx) pot (Trang 111 - 112)

- Kết quả trả về của hàm là ký tự được ấn.

HÀM MAIN CÓ THAM SỐ – CON TRỎ HÀM

2.2. Cách biên dịch và gọi một hàm trong C

Để hiểu được các con trỏ hàm làm việc như thế nào, ta cần hiểu một chút về cách biên dịch và gọi một hàm. Khi biên dịch hàm, trình biên dịch chuyển chương trình nguồn sang dạng mã máy và thiết lập một điểm xâm nhập vào hàm (chính là vị trí của chỉ thị mã máy đầu tiên của hàm). Khi có lời gọi thực hiện hàm, máy tính sẽ thực hiện một chỉ thị call chuyển điều khiển đến điểm xâm nhập này. Trong trường hợp gọi hàm bằng tên hàm thì điểm xâm nhập này là trị tức thời (gần như là một hằng và không chứa trong biến nào cả), cách gọi hàm này gọi là cách gọi hàm trực tiếp. Trái lại, khi gọi hàm gián tiếp thông qua một biến trỏ thì biến trỏ đó phải trỏ tới chỉ thị mã máy đầu tiên của hàm đó. Cách gọi hàm thông qua biến trỏ là cách gọi hàm gián tiếp.

Ví dụ như chương trình dưới đây :

Có hai lý do khai báo strcmp() trong main(). Trước hết, chương trình phải biết kiểu của giá trị mà hàm strcmp trả về và thứ hai, trình biên dịch phải nhận biết được tên của nó là tên của một hàm. Trong C, không giống như những biến khác, một hàm

không có cách nào để trực tiếp khai báo một biến trỏ chỉ đến hàm đó, nghĩa là không có cách khai báo con trỏ kiểu hàm mà phải khai báo con trỏ kiểu void. Khi gọi hàm Check, các tham số truyền vào cho hàm này là hai con trỏ trỏ tới hai xâu kí tự và một con trỏ trỏ tới hàm strcmp. Bên trong hàm Check, hàm strcmp được gọi bằng phát biểu:

(*cmp)(a,b)

Các tham số a và b được truyền bình thường cho con trỏ hàm như trường hợp gọi theo tên.

/*Đoạn chương trình so sánh hai xâu*/ main()

{

int strcmp(); /* Khai báo một hàm */ char s1[80], s2[80]; void *p; p = strcmp; gets(s1); gets(s2); check( s1, s2, p); }

check( char *a, char *b, int (*cmp)()) {

printf("Kiểm tra hai xâu giống nhau không ?\n"); if(!(*cmp)(a,b)) printf("Giống nhau");

else printf("Khác nhau"); }

Chú ý rằng, cũng có thể gọi check theo cách trực tiếp sử dụng strcmp như sau:

Phát biểu này hạn chế bớt việc phải dùng thêm một biến trỏ. Tuy nhiên hầu hết các chương trình con đều sử dụng con trỏ chỉ đến hàm để chương trình linh động hơn. Chẳng hạn xem xét ví dụ dưới đây :

/*Đoạn chương trình so sánh hai xâu*/ #include <ctype.h>

void main() {

int strcmp(); /* Khai báo hai hàm */ int numcmp();

char s1[80], s2[80]; void *p;

gets(s1); gets(s2);

if (tolower(*s1) <= 'z' && tolower(*s1) >= 'a') p = strcmp;

else

p = numcmp; check( s1, s2, p); }

check( char *a, char *b, int (*cmp)()) {

printf("Kiểm tra hai xâu giống nhau không ?\n"); if(!(*cmp)(a,b)) printf("Giống nhau");

else printf("Khác nhau"); }

int numcmp( char *a, char *b) {

if (atoi(a)==atoi(b)) return 0; else return 1;

}

Như vậy trong chương trình này, bằng một lần gọi check duy nhất, ta có thể kiểm ta được hai chuỗi chữ cái, hoặc hai chuỗi chữ số giống nhau hay không tuỳ theo kí tự đầu tiên của chuỗi nhập vào là chữ cái hay chữ số bằng cách gọi hàm với biến trỏ p mà biến trỏ này tuỳ tình huống có thể trỏ đến hàm strcmp (khi kí tự đầu tiên là chữ cái) hay numcmp (khi kí tự đầu tiên là chữ số).

Một phần của tài liệu giao trinh C(dttx) pot (Trang 111 - 112)

Tải bản đầy đủ (DOC)

(184 trang)
w