การคอมไพล์แบบมีเงื่อนไข
ifdef และมาโคร
การคอมไพล์แบบมีเงื่อนไข เป็นบทเรียน C Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน
ตัวประมวลผลล่วงหน้า
ก่อนที่คอมไพเลอร์จะเห็นโค้ดของคุณ ตัวประมวลผลล่วงหน้าจะทำงานก่อน โดยจัดการทุกบรรทัดที่เริ่มต้นด้วย # ได้แก่ การรวมไฟล์ มาโคร และเงื่อนไข
การคอมไพล์แบบมีเงื่อนไขช่วยให้คุณรวมหรือตัดบล็อกโค้ดออกตามเงื่อนไขที่ประเมินในขั้นตอนนี้ ทำให้สร้างโปรแกรมคนละรูปแบบจากซอร์สเดียวกันได้
การกำหนดมาโคร
#define ใช้สร้างมาโคร หากไม่กำหนดค่าให้ มาโครนั้นจะเป็นเพียงแฟล็กที่คุณตรวจสอบภายหลังได้
มาโครรูปแบบอ็อบเจ็กต์จะแทนที่ชื่อด้วยข้อความ ส่วนแฟล็กจะทำหน้าที่เพียงระบุว่ามีการตั้งค่าไว้
#define MAX_USERS 100 /* value macro */
#define DEBUG /* flag macro */ifdef และ ifndef
#ifdef NAME จะคงบล็อกไว้เฉพาะเมื่อมีการกำหนด NAME แล้ว ส่วน #ifndef จะคงบล็อกไว้เฉพาะเมื่อยังไม่ได้กำหนดชื่อดังกล่าว
ในที่นี้ คำสั่งพิมพ์ข้อมูลการแก้จุดบกพร่องจะมีอยู่เฉพาะในบิลด์สำหรับแก้จุดบกพร่องเท่านั้น หากไม่ได้กำหนด DEBUG คอมไพเลอร์จะไม่เห็นบรรทัดนั้นเลย
#include <stdio.h>
#define DEBUG
int main(void) {
#ifdef DEBUG
printf("debug: starting\n");
#endif
printf("running\n");
return 0;
}if, elif, else
#if จะประเมินนิพจน์จำนวนเต็มค่าคงที่ ใช้ร่วมกับ #elif และ #else เพื่อเลือกจากหลายกรณี
คำสั่งนี้เลือกโค้ดตามมาโครหมายเลขรุ่น
#include <stdio.h>
#define VERSION 2
int main(void) {
#if VERSION >= 2
printf("new feature on\n");
#else
printf("legacy mode\n");
#endif
return 0;
}ตัวดำเนินการ defined
ภายใน #if คุณสามารถตรวจสอบการกำหนดชื่อด้วย defined(NAME) และรวมการตรวจสอบด้วย && กับ || ได้
วิธีนี้ยืดหยุ่นกว่า #ifdef ซึ่งตรวจสอบได้เพียงชื่อเดียว
#if defined(LINUX) && !defined(EMBEDDED)
/* desktop Linux code */
#endifการกำหนดตอนคอมไพล์
คุณไม่จำเป็นต้องเขียนมาโครตายตัวในโค้ด แฟล็ก -D ใช้กำหนดมาโครผ่านบรรทัดคำสั่งได้
ระบบสร้างโปรแกรมใช้วิธีนี้เพื่อสลับคุณลักษณะโดยไม่ต้องแก้ไขซอร์ส -DDEBUG มีความหมายเหมือนกับการเขียน #define DEBUG ไว้ด้านบนของทุกไฟล์
gcc -DDEBUG -DVERSION=3 -o app app.cการตรวจหาแพลตฟอร์ม
คอมไพเลอร์จะกำหนดมาโครที่อธิบายเป้าหมายไว้ล่วงหน้า คุณใช้มาโครเหล่านี้เพื่อเขียนโค้ดที่ทำงานได้หลายแพลตฟอร์ม
_WIN32— Windows (32 หรือ 64 บิต)__linux__— Linux__APPLE__— macOS / iOS
ใช้เงื่อนไขแยกตามมาโครเหล่านี้เพื่อเรียกใช้ API ของแพลตฟอร์มที่ถูกต้อง
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endifตัวป้องกันการรวมไฟล์ส่วนหัว
การใช้เงื่อนไขแบบคลาสสิกคือตัวป้องกันการรวมไฟล์ ซึ่งป้องกันไม่ให้ประมวลผลไฟล์ส่วนหัวซ้ำสองครั้ง
การรวมไฟล์ครั้งแรกจะกำหนดมาโครป้องกันไว้ ส่วนการรวมครั้งถัดไปจะข้ามเนื้อหา เพราะมีการกำหนดมาโครนั้นไว้แล้ว
#ifndef UTILS_H
#define UTILS_H
int add(int a, int b);
#endif /* UTILS_H */การปิดใช้โค้ดด้วยคอมเมนต์
#if 0 ... #endif ปิดใช้บล็อกได้อย่างแน่นอน แม้บล็อกนั้นจะมีคอมเมนต์อยู่แล้ว
ต่างจาก /* */ ตรงที่สามารถซ้อนกันได้อย่างปลอดภัย จึงเป็นวิธีมาตรฐานสำหรับตัดโค้ดออกชั่วคราวระหว่างการแก้จุดบกพร่อง
#if 0
legacy_function(); /* disabled for now */
/* with internal comments too */
#endifการตรวจสอบเอาต์พุตของตัวประมวลผลล่วงหน้า
หากต้องการดูสิ่งที่คอมไพเลอร์จะคอมไพล์อย่างแน่นอน ให้เรียกใช้เฉพาะตัวประมวลผลล่วงหน้าด้วย -E
คำสั่งนี้จะขยายการรวมไฟล์ มาโคร และเงื่อนไขทั้งหมด ซึ่งมีประโยชน์อย่างยิ่งเมื่อมาโครทำงานผิดพลาด
gcc -E app.c | lessการใช้สวิตช์คุณลักษณะในทางปฏิบัติ
รูปแบบที่ใช้กันทั่วไปคือการมีไฟล์ส่วนหัวสำหรับการตั้งค่าเพียงไฟล์เดียว เพื่อเปิดหรือปิดคุณลักษณะให้ทั้งโปรเจกต์
เปลี่ยน #define เพียงรายการเดียว แล้วทุกบล็อกที่มีเงื่อนไขป้องกันในทุกไฟล์จะตอบสนองตามนั้น วิธีนี้ช่วยแยกคุณลักษณะเสริมออกจากโค้ดหลักได้อย่างเป็นระเบียบ
#include <stdio.h>
#define FEATURE_LOGGING 1
int main(void) {
#if FEATURE_LOGGING
printf("logging enabled\n");
#endif
printf("app ready\n");
return 0;
}ตรวจสอบอย่างรวดเร็ว
คาดการณ์พฤติกรรมของการกำหนดค่าผ่านบรรทัดคำสั่ง
สรุปทบทวน
ขณะนี้คุณควบคุมการคอมไพล์แบบมีเงื่อนไขได้แล้ว:
#ifdef/#ifndefตรวจสอบว่ามีการกำหนดมาโครหรือไม่#if/#elif/#elseประเมินนิพจน์ค่าคงที่ร่วมกับdefined()-DNAMEกำหนดมาโครจากบรรทัดคำสั่งเพื่อสลับคุณลักษณะ- มาโครแพลตฟอร์มที่กำหนดไว้ล่วงหน้าช่วยให้เขียนโค้ดที่ทำงานได้หลายแพลตฟอร์ม และตัวป้องกันการรวมไฟล์จะป้องกันการรวมซ้ำ
ถัดไป: การจัดระเบียบโค้ดในหลายไฟล์
คำถามที่พบบ่อย
บทเรียน “การคอมไพล์แบบมีเงื่อนไข” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การคอมไพล์แบบมีเงื่อนไข” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การคอมไพล์แบบมีเงื่อนไข”
ifdef และมาโคร คุณปฏิบัติ C Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การคอมไพล์แบบมีเงื่อนไข” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C Academy นี้ได้ไหม
ได้ บทเรียน C Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การคอมไพล์แบบมีเงื่อนไข
- โปรเจกต์หลายไฟล์
- Makefile
- ไลบรารีสแตติกและไลบรารีใช้ร่วมกัน