Tạo tệp tiêu đề của riêng bạn trong C


Câu trả lời:


299

foo.h

#ifndef FOO_H_   /* Include guard */
#define FOO_H_

int foo(int x);  /* An example function declaration */

#endif // FOO_H_

foo.c

#include "foo.h"  /* Include the header (not strictly necessary here) */

int foo(int x)    /* Function definition */
{
    return x + 5;
}

C chính

#include <stdio.h>
#include "foo.h"  /* Include the header here, to obtain the function declaration */

int main(void)
{
    int y = foo(3);  /* Use the function here */
    printf("%d\n", y);
    return 0;
}

Để biên dịch bằng GCC

gcc -o my_app main.c foo.c

2
@Anu: Tôi không thể đọc nó ở định dạng này. Bạn có thể chỉnh sửa câu hỏi ban đầu của bạn để bao gồm mã này.
Oliver Charlesworth

3
Điều đáng chú ý là mã này không hoạt động nếu bạn cố gắng chỉ xây dựng nó bằng nút (ví dụ: "xây dựng và chạy" trong Code :: Blocks chẳng hạn). Nó có vẻ rõ ràng đối với bạn nhưng đối với tôi đó là lần đầu tiên nó xảy ra và tôi đã mất khá nhiều thời gian để tìm ra vấn đề ở đâu.
Jeyekomon

5
@Jeyekomon: Vâng, nơi vấn đề?
Oliver Charlesworth

2
Không ai nói với tôi rằng nút "xây dựng và chạy" không đủ cho tất cả mọi thứ. :-) Đó là một điều khá bất ngờ đối với tôi (tôi là người mới). Bây giờ tôi đoán tôi phải học cách sử dụng dòng lệnh hoặc makefiles trước.
Jeyekomon

1
Tôi đã tự hỏi nếu bạn có thể giải thích cách biên dịch với tất cả các tệp cần thiết và không phải đưa foo.c vào đối số chương trình gcc. Kỹ thuật này được gọi là gì hoặc chương trình nào có thể thực hiện được điều này ngoài IDE - Hãy đến với tâm trí của tôi
nf071590

26
#ifndef MY_HEADER_H
# define MY_HEADER_H

//put your function headers here

#endif

MY_HEADER_H phục vụ như một bảo vệ bao gồm kép.

Đối với khai báo hàm, bạn chỉ cần xác định chữ ký, nghĩa là không có tên tham số, như thế này:

int foo(char*);

Nếu bạn thực sự muốn, bạn cũng có thể bao gồm số nhận dạng của tham số, nhưng không cần thiết vì số nhận dạng sẽ chỉ được sử dụng trong phần thân của hàm (triển khai), trong trường hợp tiêu đề (chữ ký tham số), nó bị thiếu.

Điều này khai báo hàm foochấp nhận a char*và trả về một int.

Trong tệp nguồn của bạn, bạn sẽ có:

#include "my_header.h"

int foo(char* name) {
   //do stuff
   return 0;
}

Chúng được gọi là khai báo hàm hoặc nguyên mẫu hàm , không phải là "tiêu đề hàm". Tiêu đề là các tệp bạn bao gồm, không phải là khai báo bên trong chúng.
Jonathan Wakely

@JonathanWakely Đó là các tệp tiêu đề. Tên này nói lên tất cả: các tệp tiêu đề chứa các tiêu đề. Nhưng cảm ơn về phản hồi, nó làm tôi suy nghĩ trong một giây.
Flavius

Không, tiêu đề là chính các tệp, không phải là khai báo mà chúng chứa. Bạn có thể tìm thấy một tài liệu tham khảo có uy tín để sao lưu việc sử dụng "tiêu đề" của bạn không? Chẳng hạn, nó bị mâu thuẫn bởi K & R, tiêu chuẩn C, Môi trường lập trình UNIXWikipedia .
Jonathan Wakely

@JonathanWakely bạn đã thực sự đọc K & R chưa? TOC có một phần "4,5 tệp tiêu đề" và "tệp tiêu đề" được viết bằng chữ in nghiêng, biểu thị thuật ngữ. Trong phần còn lại của cuốn sách, các tác giả đôi khi chỉ viết "tiêu đề" cho ngắn gọn, nhưng thông qua định dạng và TOC, rõ ràng thuật ngữ đúng là gì. Vì vậy, xin vui lòng, là một chuyên gia và nhận ra khi bạn sai.
Flavius

Có, và "tiêu đề" đề cập đến các tệp , không phải các khai báo trong đó. Trong phiên bản 2, xem trang 241 để thảo luận về các tiêu đề tiêu chuẩn và trang 33 nói về các định nghĩakhai báo (mà bạn gọi nhầm là "các tiêu đề hàm") và định nghĩa rõ ràng một tiêu đề : "Cách thông thường là thu thập các externkhai báo các biến và các hàm trong một tệp riêng biệt, theo lịch sử được gọi là tiêu đề , được bao gồm #includeở phía trước của mỗi tệp nguồn. Chẳng hạn, các chức năng của thư viện chuẩn được khai báo trong các tiêu đề như <stdio.h>. "
Jonathan Wakely

8

myfile.h

#ifndef _myfile_h
#define _myfile_h

void function();

#endif

myfile.c

#include "myfile.h"

void function() {

}

void function();như một tuyên bố không ngăn chặn các cuộc gọi như thế nào function(42);. Sử dụng voidtrong khai báo nhưvoid function(void);
chux - Tái lập lại

5

tệp tiêu đề chứa các nguyên mẫu cho các chức năng bạn xác định trong tệp .c hoặc .cpp / .cxx (tùy thuộc vào việc bạn đang sử dụng c hoặc c ++). Bạn muốn đặt # ifndef / # định nghĩa xung quanh mã .h của mình để nếu bạn bao gồm cùng một .h hai lần trong các phần khác nhau của chương trình, các nguyên mẫu chỉ được đưa vào một lần.

khách hàng

#ifndef CLIENT_H
#define CLIENT_H

short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize);


#endif /** CLIENT_H */

Sau đó, bạn sẽ triển khai .h trong tệp .c như vậy:

khách hàng

#include "client.h"

short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize) {
 short ret = -1;
 //some implementation here
 return ret;
}

"để nếu bạn bao gồm cùng một .h hai lần trong các phần khác nhau của chương trình, các nguyên mẫu chỉ được đưa vào một lần." Điều này là sai lệch. Họ bảo vệ chống lại việc bao gồm cùng một tệp tiêu đề hai lần từ cùng một tệp nguồn (bao gồm một tiêu đề hai lần trong hai tệp nguồn khác nhau và thường được yêu cầu!) Và các nguyên mẫu hàm khai báo lại không phải là vấn đề, xác định lại các loại và biến toàn cục là những gì phải được bảo vệ chống lại.
Jonathan Wakely
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.