Trả lời nhanh: thay đổi int testlib()
để int testlib(void)
xác định rằng hàm không có đối số.
Một nguyên mẫu theo định nghĩa là một khai báo hàm chỉ định loại (các) đối số của hàm.
Một khai báo hàm không nguyên mẫu như
int foo();
là một khai báo kiểu cũ không chỉ định số lượng hoặc loại đối số. (Trước tiêu chuẩn ANSI C năm 1989, đây là loại khai báo hàm duy nhất có sẵn trong ngôn ngữ.) Bạn có thể gọi một hàm như vậy với bất kỳ số lượng đối số tùy ý nào và trình biên dịch không bắt buộc phải khiếu nại - nhưng nếu cuộc gọi không phù hợp với định nghĩa , chương trình của bạn có hành vi không xác định.
Đối với một hàm có một hoặc nhiều đối số, bạn có thể chỉ định loại của từng đối số trong khai báo:
int bar(int x, double y);
Các hàm không có đối số là một trường hợp đặc biệt. Về mặt logic, các dấu ngoặc rỗng sẽ là một cách tốt để xác định rằng một đối số nhưng cú pháp đó đã được sử dụng cho các khai báo hàm kiểu cũ, vì vậy ủy ban ANSI C đã phát minh ra một cú pháp mới bằng void
từ khóa:
int foo(void); /* foo takes no arguments */
Một định nghĩa hàm (bao gồm mã cho những gì hàm thực sự làm) cũng cung cấp một khai báo . Trong trường hợp của bạn, bạn có một cái gì đó tương tự như:
int testlib()
{
/* code that implements testlib */
}
Điều này cung cấp một tuyên bố không nguyên mẫu cho testlib
. Theo định nghĩa, điều này cho trình biên dịch testlib
không có tham số, nhưng như một khai báo, nó chỉ cho trình biên dịch testlib
lấy một số số và loại (các) đối số không xác định.
Nếu bạn thay đổi ()
để (void)
khai báo trở thành một nguyên mẫu.
Ưu điểm của một nguyên mẫu là nếu bạn vô tình gọi testlib
bằng một hoặc nhiều đối số, trình biên dịch sẽ chẩn đoán lỗi.
(C ++ có các quy tắc hơi khác nhau. C ++ không có khai báo hàm kiểu cũ và dấu ngoặc đơn trống có nghĩa là hàm không có đối số. C ++ hỗ trợ (void)
cú pháp để thống nhất với C. Nhưng trừ khi bạn đặc biệt cần mã của mình để biên dịch cả hai C và là C ++, có lẽ bạn nên sử dụng cú pháp trong ()
C ++ và (void)
cú pháp trong C.)