สร้างไฟล์ส่วนหัวของคุณเองใน C


176

ทุกคนสามารถอธิบายวิธีสร้างไฟล์ส่วนหัวใน C ด้วยตัวอย่างง่ายๆตั้งแต่ต้นจนจบ


24
คุณอ่านหนังสือเกริ่นนำเกี่ยวกับ C หรือไม่? ต่อไปนี้เป็นสิ่งออนไลน์: สิ่งพิมพ์ . gbdirect.co.uk/c_book
Oliver Charlesworth

คำตอบ:


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;
}

main.c

#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;
}

เพื่อรวบรวมโดยใช้ GCC

gcc -o my_app main.c foo.c

2
@Anu: ฉันไม่สามารถอ่านได้ในรูปแบบนี้ คุณสามารถแก้ไขคำถามเดิมของคุณเพื่อรวมรหัสนี้
Oliver Charlesworth

3
เป็นที่น่าสังเกตว่ารหัสนี้ใช้ไม่ได้หากคุณพยายามสร้างโดยใช้ปุ่ม ("build and run" ใน Code :: Blocks เป็นต้น) มันอาจดูเหมือนชัดเจนสำหรับคุณ แต่สำหรับฉันมันเป็นครั้งแรกที่มันเกิดขึ้นและฉันใช้เวลาพอสมควรที่จะทราบว่าปัญหาอยู่ที่ไหน
Jeyekomon

5
@Jeyekomon: ดีที่เป็นปัญหาหรือไม่
Oliver Charlesworth

2
ไม่มีใครบอกฉันว่าปุ่ม "สร้างและเรียกใช้" ไม่เพียงพอสำหรับทุกสิ่ง :-) มันค่อนข้างแปลกใจสำหรับฉัน (ฉันเป็นมือใหม่) ตอนนี้ฉันเดาว่าฉันต้องเรียนรู้การใช้ commandline หรือ makefiles ก่อน
Jeyekomon

1
ฉันสงสัยว่าคุณสามารถอธิบายอย่างละเอียดเกี่ยวกับวิธีการรวบรวมไฟล์ที่จำเป็นทั้งหมดและไม่ต้องรวม foo.c ลงในอาร์กิวเมนต์โปรแกรม gcc เทคนิคนี้เรียกว่าอะไรหรือโปรแกรมใดที่สามารถทำให้สิ่งนี้สำเร็จนอกเหนือจาก IDE - ทำให้อยู่ในใจฉัน
nf071590

26
#ifndef MY_HEADER_H
# define MY_HEADER_H

//put your function headers here

#endif

MY_HEADER_H ทำหน้าที่เป็นยามรวมสองครั้ง

สำหรับการประกาศฟังก์ชั่นคุณจะต้องกำหนดลายเซ็นนั่นคือโดยไม่มีชื่อพารามิเตอร์เช่นนี้:

int foo(char*);

หากคุณต้องการจริงๆคุณสามารถรวมตัวระบุพารามิเตอร์ได้ แต่ไม่จำเป็นเพราะตัวระบุจะใช้เฉพาะในเนื้อหาของฟังก์ชัน (การนำไปใช้) ซึ่งในกรณีที่ส่วนหัว (ลายเซ็นพารามิเตอร์) หายไป

นี้ประกาศฟังก์ชั่นfooที่ยอมรับและส่งกลับchar*int

ในไฟล์ต้นฉบับคุณจะต้อง:

#include "my_header.h"

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

พวกมันถูกเรียกว่าการประกาศฟังก์ชันหรือฟังก์ชันต้นแบบไม่ใช่ "function headers" ส่วนหัวคือไฟล์ที่คุณรวมไม่ใช่ประกาศภายใน
Jonathan Wakely

@JonathanWakely นั่นคือไฟล์ส่วนหัว ชื่อบอกทุกอย่าง: ไฟล์ส่วนหัวมีส่วนหัว แต่ขอบคุณสำหรับคำติชมมันทำให้ฉันคิดเป็นวินาที
Flavius

ไม่ส่วนหัวเป็นไฟล์เองไม่ใช่การประกาศที่มี คุณสามารถค้นหาการอ้างอิงที่มีชื่อเสียงเพียงครั้งเดียวเพื่อสำรองการใช้ "header" ของคุณได้หรือไม่? มันขัดแย้งกับ K&R มาตรฐาน C, UNIX Programming EnvironmentและWikipediaเป็นต้น
Jonathan Wakely

@Jathanathan คุณอ่าน K&R จริงหรือเปล่า? TOC มีส่วน "4.5 Header files" และ "header files" ถูกเขียนเป็นตัวเอียงเพื่อระบุคำศัพท์ ในส่วนที่เหลือของหนังสือเล่มนี้ผู้เขียนเขียนบางครั้งก็เป็นแค่ "ส่วนหัว" เพื่อความกะทัดรัด แต่ผ่านการจัดรูปแบบและ TOC มันชัดเจนว่าคำศัพท์ที่ถูกต้องคืออะไร ดังนั้นโปรดเป็นมืออาชีพและรู้จักเมื่อคุณผิด
Flavius

ใช่และ "header" อ้างถึงไฟล์ไม่ใช่การประกาศในไฟล์ ในรุ่นที่ 2 ดูที่หน้า 241 สำหรับการอภิปรายของส่วนหัวมาตรฐานและหน้า 33 ซึ่งพูดถึงคำจำกัดความและการประกาศ (ซึ่งคุณเรียกว่า "ฟังก์ชันส่วนหัว" โดยไม่ตั้งใจ) และกำหนดหัวข้ออย่างชัดเจน: "การปฏิบัติตามปกติคือการรวบรวมexternการประกาศตัวแปรและ ฟังก์ชั่นในไฟล์ที่แยกต่างหากในอดีตเรียกว่าส่วนหัวซึ่งรวมอยู่#includeที่ด้านหน้าของไฟล์ต้นฉบับแต่ละไฟล์ตัวอย่างเช่นฟังก์ชั่นของไลบรารีมาตรฐานจะถูกประกาศในส่วนหัวเช่น<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();เป็นประกาศfunction(42);ที่ไม่ได้ป้องกันไม่ให้สายเช่น ใช้voidในการประกาศเช่นvoid function(void);
chux - Reinstate Monica

5

ไฟล์ส่วนหัวมีต้นแบบสำหรับฟังก์ชั่นที่คุณกำหนดในไฟล์. c หรือ. cpp / .cxx (ขึ้นอยู่กับว่าคุณใช้ c หรือ c ++) คุณต้องการวาง # ifndef / # กำหนดรอบรหัส. h ของคุณเพื่อให้คุณรวม. h เดียวกันสองครั้งในส่วนต่าง ๆ ของโปรแกรมของคุณต้นแบบจะรวมเพียงครั้งเดียว

client.h

#ifndef CLIENT_H
#define CLIENT_H

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


#endif /** CLIENT_H */

จากนั้นคุณต้องติดตั้ง. h ในไฟล์. c ดังนี้:

client.c

#include "client.h"

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

"ดังนั้นถ้าคุณรวม. h เดียวกันสองครั้งในส่วนต่าง ๆ ของโปรแกรมของคุณต้นแบบจะรวมเพียงครั้งเดียวเท่านั้น" นี่เป็นสิ่งที่ทำให้เข้าใจผิด พวกเขาป้องกันการรวมไฟล์ส่วนหัวเดียวกันสองครั้งจากไฟล์ต้นฉบับเดียวกัน (รวมถึงส่วนหัวสองครั้งในสองไฟล์ต้นฉบับที่แตกต่างกันก็โอเคและโดยปกติจะต้อง!) และการประกาศฟังก์ชั่นต้นแบบใหม่ไม่ได้เป็นปัญหา คือสิ่งที่ต้องระวัง
โจนาธาน Wakely
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.