0Pricing
C Academy · บทเรียน

โปรเจกต์หลายไฟล์

ส่วนหัวและหน่วยแปล

โปรเจกต์หลายไฟล์ เป็นบทเรียน C Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุผลที่ควรแยกไฟล์

โปรแกรมจริงไม่ได้อยู่ในไฟล์ .c เพียงไฟล์เดียว การแยกโค้ดเป็นหลายไฟล์ช่วยให้:

  • จัดกลุ่มฟังก์ชันที่เกี่ยวข้องกันไว้ด้วยกัน
  • ให้คอมไพเลอร์สร้างใหม่เฉพาะส่วนที่เปลี่ยนแปลง
  • นำโค้ดกลับมาใช้ซ้ำในหลายโปรเจกต์
  • ให้ทีมทำงานร่วมกันได้โดยไม่เกิดข้อขัดแย้งตลอดเวลา

การทำความเข้าใจว่าชิ้นส่วนต่าง ๆ เชื่อมโยงกันอย่างไรเป็นสิ่งสำคัญ

หน่วยแปล

ไฟล์ .c แต่ละไฟล์ หลังจากตัวประมวลผลล่วงหน้าขยาย #include แล้ว จะกลายเป็นหน่วยแปล

คอมไพเลอร์จะแปลงหน่วยแปลแต่ละหน่วยเป็นไฟล์อ็อบเจ็กต์ (.o) แยกจากกัน โดยในขั้นตอนนี้ยังไม่รู้จักไฟล์อื่น

การประกาศกับการนิยาม

การประกาศบอกคอมไพเลอร์ว่ามีฟังก์ชันอยู่และระบุลายเซ็นของฟังก์ชัน ส่วนการนิยามจะระบุเนื้อหาจริงของฟังก์ชัน

ไฟล์อื่นต้องการเพียงการประกาศเพื่อเรียกใช้ฟังก์ชัน ส่วนการนิยามจะอยู่ในที่เดียวเท่านั้น

int add(int a, int b);          /* declaration: a promise */

int add(int a, int b) {         /* definition: the body */
    return a + b;
}

ไฟล์ส่วนหัว

การประกาศจะอยู่ในไฟล์ส่วนหัว (.h) ไฟล์ใดก็ตามที่ต้องการใช้ฟังก์ชันจะรวมไฟล์ส่วนหัวนี้

ไฟล์ส่วนหัวคืออินเทอร์เฟซสาธารณะ ส่วนไฟล์ .c ที่ตรงกันคือการนำไปใช้งานภายใน

/* math_utils.h */
#ifndef MATH_UTILS_H
#define MATH_UTILS_H

int add(int a, int b);
int mul(int a, int b);

#endif

ไฟล์การนำไปใช้งาน

ไฟล์ .c จะรวมไฟล์ส่วนหัวของตนเองและนิยามฟังก์ชันต่าง ๆ

การรวมไฟล์ส่วนหัวของตนเองช่วยให้คอมไพเลอร์ตรวจสอบได้ว่าการนิยามตรงกับการประกาศ

/* math_utils.c */
#include "math_utils.h"

int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }

การใช้โมดูล

ไฟล์อื่นจะรวมไฟล์ส่วนหัวและเรียกใช้ฟังก์ชัน โดยไม่จำเป็นต้องเห็นเนื้อหาภายในฟังก์ชัน

คอมไพเลอร์เชื่อถือการประกาศ ส่วนตัวเชื่อมโยงจะเชื่อมการเรียกใช้เข้ากับการนิยามจริงในภายหลัง

/* main.c */
#include <stdio.h>
#include "math_utils.h"

int main(void) {
    printf("%d\n", add(2, 3));
    return 0;
}

การคอมไพล์และการเชื่อมโยง

มีสองขั้นตอน ขั้นแรกคอมไพล์แต่ละไฟล์เป็นไฟล์อ็อบเจ็กต์ด้วย -c จากนั้นเชื่อมโยงอ็อบเจ็กต์เหล่านั้นเข้าด้วยกันเป็นไฟล์ที่เรียกใช้ได้หนึ่งไฟล์

ตัวเชื่อมโยงจะค้นหาการนิยามใน math_utils.o เพื่อแก้การเรียกใช้ add แต่ละรายการ

gcc -c main.c          # -> main.o
gcc -c math_utils.c    # -> math_utils.o
gcc main.o math_utils.o -o app

เครื่องหมายอัญประกาศกับวงเล็บแหลม

ไวยากรณ์การรวมไฟล์จะควบคุมเส้นทางการค้นหา:

  • #include "math_utils.h" จะค้นหาไดเรกทอรีโปรเจกต์ของคุณก่อน
  • #include <stdio.h> จะค้นหาเฉพาะเส้นทางรวมไฟล์ของระบบ

ใช้เครื่องหมายอัญประกาศกับไฟล์ส่วนหัวของคุณเอง และใช้วงเล็บแหลมกับไลบรารีมาตรฐาน

คีย์เวิร์ด extern

หากต้องการใช้ตัวแปรโกลบอลร่วมกันระหว่างไฟล์ ให้นิยามตัวแปรนั้นครั้งเดียวในไฟล์ .c และประกาศด้วย extern ในไฟล์ส่วนหัว

extern หมายความว่า 'ตัวแปรนี้มีอยู่ที่อื่น' จึงช่วยหลีกเลี่ยงการนิยามซ้ำ

/* in config.h */
extern int g_verbose;   /* declaration */

/* in config.c */
int g_verbose = 0;      /* the single definition */

คีย์เวิร์ด static

ในขอบเขตไฟล์ static จะทำให้ฟังก์ชันหรือตัวแปรเป็นส่วนตัวสำหรับหน่วยแปลของตนเอง

ฟังก์ชันช่วยแบบ static ไม่สามารถเชื่อมโยงจากไฟล์อื่นได้ จึงป้องกันชื่อชนกันและซ่อนรายละเอียดการนำไปใช้งาน นี่คือวิธีของ C ในการระบุว่าสิ่งใดเป็นส่วนภายใน

/* visible only inside this .c file */
static int helper(int x) {
    return x * 2;
}

กฎการนิยามเพียงครั้งเดียว

ฟังก์ชันที่ไม่ใช่แบบ static หรือโกลบอล อาจถูกนิยามได้เพียงครั้งเดียวเท่านั้นทั่วทั้งโปรแกรม คุณสามารถประกาศฟังก์ชันนั้นในหลายไฟล์ได้ แต่ต้องนิยามไว้ในไฟล์เดียว

การนิยาม add สองครั้งจะทำให้เกิดข้อผิดพลาดจากตัวเชื่อมโยง เช่น multiple definition of 'add' นี่จึงเป็นเหตุผลที่ไม่ควรใส่ตัวฟังก์ชันไว้ในไฟล์ส่วนหัว

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ลองพิจารณาว่าสิ่งใดควรอยู่ในไฟล์ส่วนหัว

ทบทวน

ตอนนี้คุณสามารถจัดโครงสร้างโครงการที่มีหลายไฟล์ได้แล้ว:

  • แต่ละไฟล์ .c เป็นหน่วยแปลภาษาที่คอมไพล์เป็น .o ได้อย่างอิสระ
  • ไฟล์ส่วนหัวเก็บการประกาศ ส่วนแต่ละการนิยามจะอยู่ในไฟล์ .c หนึ่งไฟล์
  • ตัวเชื่อมโยงจะจัดการการเรียกใช้ข้ามไฟล์ออบเจ็กต์
  • extern ใช้แบ่งปันตัวแปรโกลบอล ส่วน static จะทำให้สัญลักษณ์เฉพาะไฟล์เป็นแบบส่วนตัว

ถัดไป: ทำให้กระบวนการสร้างเป็นอัตโนมัติด้วย Makefile

คำถามที่พบบ่อย

บทเรียน “โปรเจกต์หลายไฟล์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “โปรเจกต์หลายไฟล์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “โปรเจกต์หลายไฟล์”

ส่วนหัวและหน่วยแปล คุณปฏิบัติ C Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “โปรเจกต์หลายไฟล์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C Academy นี้ได้ไหม

ได้ บทเรียน C Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การคอมไพล์แบบมีเงื่อนไข
  2. โปรเจกต์หลายไฟล์
  3. Makefile
  4. ไลบรารีสแตติกและไลบรารีใช้ร่วมกัน
← กลับไปที่ C Academy