- 1 1. Sissejuhatus
- 2 2. Eeltöötluse ja makrode alused
- 3 3. #ifdef direktiivi põhistruktuur
- 4 4. #ifdef peamised kasutusalad
- 5 5. #ifdef ja #ifndef erinevus
- 6 6. Mitu tingimust harudes
- 7 7. #ifdef kasutamise tähelepanekud ja parimad tavad
- 8 8. Korduma kippuvad küsimused (KKK)
- 9 9. Kokkuvõte
1. Sissejuhatus
Mis on C-keele #ifdef?
C-keele #ifdef
on eeltöötlusdirektiiv tingimusliku kompileerimise jaoks. See võimaldab kontrollida, kas teatud osa programmist kompileeritakse või mitte, muutes koodi haldamise ja hooldamise lihtsamaks. Eriti oluline on see suurtes projektides ja platvormispetsiifilise koodi haldamisel.
Kas sul on järgmised mured?
- Soovid hõlpsalt vahetada eri platvormidele mõeldud koodi.
- Soovid hallata ainult silumiseks mõeldud koodi.
- Soovid vältida vigu, mis tekivad sama päisefaili mitmekordsel kaasamisel.
Mida see artikkel aitab sul lahendada
Selles artiklis selgitame üksikasjalikult #ifdef
põhistruktuuri ja praktilisi kasutusviise. Õpid tingimuslikku kompileerimist paindlikult rakendama.
#ifdef
direktiivi põhikasutus.- Platvormispetsiifilise ja silumiskoodi vahetamine.
- Korduvate definitsioonide vältimine include guard’i abil.
- Praktilised koodinäited kasutuse mõistmiseks.
- Olulised tähelepanekud ja parimad tavad.
See artikkel sobib nii algajatele kui ka kesktasemel programmeerijatele. Järgnevas peatükis liigume samm-sammult edasi.

2. Eeltöötluse ja makrode alused
Mis on eeltöötleja?
Eeltöötleja on mehhanism, mis töötleb käske enne, kui C-keele kompilaator koodi tõlgendab. See võimaldab tõhusalt hallata koodi ja teha tingimuslikku kompileerimist. Kõik eeltöötlemise käsud algavad #
-märgiga. Levinumad näited on:
#include
: välise faili kaasamine.#define
: makrodefineerimine.#ifdef
: tingimuslik kompileerimine.
Makrodefineerimise põhitõed
Makrod võimaldavad määratleda konstante või lühivorme, mida kasutatakse koodis. #define
abil määratletud sümboleid saab programmis korduvalt kasutada.
Näide: π (pi) defineerimine
#define PI 3.14159
printf("Ringjoone ümbermõõdu arv on %f\n", PI);
Selles näites asendatakse sümbol PI
väärtusega „3.14159”. Makrode abil hallatavad konstandid parandavad loetavust ja lihtsustavad muudatuste tegemist.
Makrode kasutamise eelised
- Parem loetavus: tähendusrikaste nimede abil on koodi mõte selgem.
- Lihtsam hooldus: väärtusi saab muuta ühest kohast.
- Koodi maht väheneb: korduva tegevuse puhul saab koodi lihtsustada.
Tähelepanek
Makrod teevad ainult lihtsaid asendusi, ilma tüübikontrollita, seega tuleb olla ettevaatlik vigade vältimiseks.
3. #ifdef direktiivi põhistruktuur
Põhistruktuur ja kasutamine
#ifdef
kontrollib, kas määratud makro on defineeritud, ja kompileerib vastava koodiploki ainult juhul, kui tingimus on täidetud.
Näide süntaksist
#ifdef DEBUG
printf("Silumisrežiim on aktiivne\n");
#endif
Selles näites kompileeritakse printf
funktsioon ainult siis, kui makro DEBUG
on defineeritud. Kui see pole määratletud, jäetakse koodiosa vahele.
ifdef ja endif roll
#ifdef
: aktiveerib koodi, kui määratud makro on defineeritud.#endif
: tähistab tingimusliku kompileerimise lõppu.
Nende paar võimaldab programmi osi vastavalt vajadusele sisse või välja lülitada.
Koodinäide: juhtimine silumisflagiga
#define DEBUG
#ifdef DEBUG
printf("Silumisteave: vigu ei leitud\n");
#endif
Kuna DEBUG
on määratletud, kuvatakse silumisteade. Kui #define DEBUG
eemaldada, ei kompileerita silumiskoodi.
Tingimusliku kompileerimise eelised
- Silumise haldus: tootmiskeskkonnas saab kompileerida ilma silumiskoodita.
- Platvormi tugi: eri keskkondade jaoks mõeldud koodi saab hallata ühe lähtefaili sees.
- Modulaarsus: teatud funktsioone saab testimiseks sisse või välja lülitada.
4. #ifdef peamised kasutusalad
1. Include guard
Include guard’i kasutatakse selleks, et vältida päisefaili mitmekordset kaasamist. Sama faili mitu korda kaasates võib tekkida sümbolite dubleerimise viga. Selle vältimiseks kasutatakse koos #ifndef
ja #define
direktiive.
Koodinäide: include guard
#ifndef HEADER_H
#define HEADER_H
void hello();
#endif
2. Platvormispetsiifilise koodi vahetamine
Erinevate platvormide jaoks mõeldud koodi saab lihtsalt vahetada. Näiteks saab #ifdef
abil eristada Windowsi ja Linuxi käitumist.
Koodinäide: OS-spetsiifiline kood
#ifdef _WIN32
printf("Windowsi keskkond\n");
#else
printf("Muu keskkond\n");
#endif
3. Silumiskoodi juhtimine
#ifdef
on kasulik ka siis, kui soovid silumiskoodi tootmises keelata.
Koodinäide: silumisrežiimi vahetamine
#define DEBUG
#ifdef DEBUG
printf("Kuvatakse silumisteave\n");
#else
printf("Töörežiim\n");
#endif
Kokkuvõte
Nende kasutusviiside kaudu parandab #ifdef
koodi loetavust ja haldamise lihtsust. Järgmisena vaatleme #ifdef
ja #ifndef
erinevusi.
5. #ifdef ja #ifndef erinevus
Võrdlustabel
Direktiiv | Selgitus |
---|---|
#ifdef | Käivitatakse kood, kui määratud makro on defineeritud. |
#ifndef | Käivitatakse kood, kui määratud makro ei ole defineeritud. |
Koodinäide: #ifdef kasutamine
#define DEBUG
#ifdef DEBUG
printf("Silumisrežiim on aktiivne\n");
#endif
Koodinäide: #ifndef kasutamine
#ifndef RELEASE
#define RELEASE
printf("Töörežiim\n");
#endif
Erinevuse kokkuvõte
#ifdef
täidab koodi, kui makro on määratletud.#ifndef
täidab koodi, kui makro ei ole määratletud.
Oluline punkt
Kombineerides mõlemat, saab luua paindlikumaid tingimuslauseid. Järgmisena käsitleme mitme tingimuse põhiseid harutusi.
6. Mitu tingimust harudes
1. #if ja #elif kasutamine tingimuste kontrolliks
#if
direktiiv hindab avaldist ja kompileerib koodi ainult siis, kui tingimus on tõene. #elif
töötab nagu else if
, võimaldades kontrollida mitut tingimust järjest.
Koodinäide: mitme tingimuse kontroll
#if defined(WINDOWS)
printf("Windowsi keskkond\n");
#elif defined(LINUX)
printf("Linuxi keskkond\n");
#elif defined(MACOS)
printf("MacOSi keskkond\n");
#else
printf("Muu keskkond\n");
#endif
2. Loogikaoperaatorite kasutamine
#if
direktiivis saab kasutada ka loogikaoperaatoreid, et luua keerulisemaid tingimusi.
Kasutatavad loogikaoperaatorid
&&
(JA): täidetakse ainult siis, kui kõik tingimused on tõesed.||
(VÕI): täidetakse, kui vähemalt üks tingimus on tõene.!
(MITTE): tingimuse eitamine.
Koodinäide: loogikaoperaatoritega kombineerimine
#if defined(WINDOWS) || defined(LINUX)
printf("Toetatud keskkond\n");
#else
printf("Mitte toetatud keskkond\n");
#endif
3. Makro väärtuse põhjal tingimused
Tingimusi saab määrata ka makro väärtuste võrdlemise kaudu, mis on kasulik versioonihalduseks või seadistuste põhjal otsustamiseks.
Koodinäide: numbriline võrdlus
#define VERSION 2
#if VERSION == 1
printf("Versioon 1\n");
#elif VERSION == 2
printf("Versioon 2\n");
#else
printf("Toetamata versioon\n");
#endif
Tingimuslausete laiendatud näide
Koodinäide: silumis- ja väljalaskerežiimi vahetamine
#if defined(DEBUG) && !defined(RELEASE)
printf("Silumisrežiim\n");
#elif !defined(DEBUG) && defined(RELEASE)
printf("Väljalaskerežiim\n");
#else
printf("Seadistuse viga\n");
#endif
Kokkuvõte
Kombineerides mitut tingimust ja loogikaoperaatoreid, saab luua paindlikku ja täpset tingimuslikku kompileerimist.
7. #ifdef kasutamise tähelepanekud ja parimad tavad
1. Tähelepanekud kasutamisel
1. Väldi liigset keerukust
Liigne tingimuslausete pesastamine muudab koodi raskesti loetavaks. Eriti #ifdef
sügavad pesad tuleks hoida minimaalsena.
Halb näide: liiga sügav pesastamine
#ifdef OS_WINDOWS
#ifdef DEBUG
printf("Windowsi silumisrežiim\n");
#else
printf("Windowsi väljalaskerežiim\n");
#endif
#else
#ifdef DEBUG
printf("Muude OS-ide silumisrežiim\n");
#else
printf("Muude OS-ide väljalaskerežiim\n");
#endif
#endif
Parandatud näide: tingimuste lihtsustamine
#ifdef DEBUG
#ifdef OS_WINDOWS
printf("Windowsi silumisrežiim\n");
#else
printf("Muude OS-ide silumisrežiim\n");
#endif
#else
#ifdef OS_WINDOWS
printf("Windowsi väljalaskerežiim\n");
#else
printf("Muude OS-ide väljalaskerežiim\n");
#endif
#endif
2. Hoia makronimed ühtsena
Makronimede ühtne stiil parandab koodi loetavust ja arusaadavust.
Näide: ühtne nimereegel
- OS-iga seotud makrod:
OS_WINDOWS
,OS_LINUX
- Silumise makrod:
DEBUG
,RELEASE
- Versioonihaldus:
VERSION_1_0
,VERSION_2_0
3. Lisa kommentaare
Mitu tingimust võivad muuta koodi eesmärgi ebaselgeks. Kommentaarid aitavad selgust tuua.
Näide kommentaaridega
#ifdef DEBUG // Silumisrežiim
printf("Silumisrežiim\n");
#else // Väljalaskerežiim
printf("Väljalaskerežiim\n");
#endif
4. Eemalda kasutamata makrod
Koodi arenedes võivad mõned makrod muutuda tarbetuks. Need tuleks eemaldada, et hoida kood puhtana.
Kokkuvõte
Õigesti kasutatud #ifdef
parandab koodi hooldatavust. Järgmisena vaatleme korduma kippuvaid küsimusi.

8. Korduma kippuvad küsimused (KKK)
K1: Kas pean alati kasutama #ifdef direktiivi?
V: Ei, #ifdef
ei ole kohustuslik. Kuid see on väga kasulik järgmistes olukordades:
- Silumiskoodi haldamine: võimaldab hõlpsalt silumiskoodi sisse või välja lülitada.
- Platvormipõhised harud: koodi saab kohandada vastavalt erinevatele OS-idele ja keskkondadele.
- Include guard: väldib päisefailide mitmekordset kaasamist.
K2: Kas #ifdef töötab ka teistes programmeerimiskeeltes?
V: Ei, #ifdef
on saadaval ainult C ja C++ keeles kui eeltöötlusdirektiiv.
Teistes keeltes kasutatakse sarnaste funktsioonide jaoks muid meetodeid:
- Java ja Python: tingimuslauseid
if
saab kasutada, kuid kompileerimistaseme juhtimist ei ole. - Rust ja Go: kasutatakse ehitustähiseid või tingimusliku kompileerimise valikuid.
K3: Kas on olemas muid viise silumiskoodi haldamiseks peale #ifdef?
V: Jah, on mitmeid alternatiive.
- Välise seadistusfaili kasutamine:
Komplekteerimisel loetakse konfiguratsioonifaili ja tingimuslauseid juhitakse dünaamiliselt.
#include "config.h"
#ifdef DEBUG
printf("Silumisrežiim\n");
#endif
- Kompilaatori valikute kasutamine:
Makro saab määratleda kompileerimise ajal ilma koodi muutmata.
gcc -DDEBUG main.c -o main
K4: Kas keerulised tingimused tuleks hallata #ifdef abil?
V: Parem on hoida see minimaalsena.
Liiga keeruline tingimusloogika #ifdef
abil võib vähendada loetavust ja hooldatavust. Sügavad pesad muudavad veaotsingu ja muudatused raskemaks.
Parandussoovitused:
- Kui tingimusi on palju, kasuta väliseid seadistusfaile või funktsioone, et koodi lihtsustada.
- Mõned seaded määra kompilaatori valikutega ja hoia koodis tingimused võimalikult lihtsad.
Kokkuvõte
KKK jaotises selgitasime #ifdef
põhilist kasutust, täiustatud näiteid ja erinevusi teiste keeltega. Järgmisena võtame teema tervikuna kokku.
9. Kokkuvõte
1. #ifdef põhifunktsioon ja roll
- Tingimusliku kompileerimise eeltöötlusdirektiiv, mis võimaldab aktiveerida või deaktiveerida teatud koodiplokke.
- Kasutatav silumiskoodi ja platvormipõhise koodi haldamiseks ning include guard’ina mitmekordsete definitsioonide vältimiseks.
2. Kasutusnäited ja praktilised lahendused
- Include guard: väldib päisefaili mitmekordset kaasamist.
- Platvormipõhine kood: võimaldab harutada OS-i või keskkonna järgi.
- Silumiskoodi juhtimine: lihtne vahetamine arenduse ja tootmise vahel.
- Mitu tingimust: keerulisemate tingimuste loomine loogikaoperaatoritega.
3. Tähelepanekud ja parimad tavad
- Hoia kood loetav: väldi liigset pesastamist.
- Ühtne makronime stiil: kasuta selgeid ja järjepidevaid nimesid.
- Kommentaarid ja seadistusfailid: tee koodist arusaadav ja hallatav.
- Kompilaatori valikud: võimaldavad seadistusi paindlikult muuta.
4. KKK-st saadud põhipunktid
- #ifdef ja #if kasutus: lihtsate olemasolu kontrollide jaoks
#ifdef
, arvuliste ja loogiliste avaldiste jaoks#if
. - Teiste keelte erinevused:
#ifdef
on C/C++-spetsiifiline. - Silumiskoodi juhtimine: väline konfiguratsioon või kompilaatori valikud annavad paindlikkuse.
Lõppsõna
#ifdef
on C-keele programmeerimises paindlik ja võimas tööriist, kuid seda tuleks kasutada mõistlikult.
Loetavuse ja hooldatavuse säilitamine ning tingimuste hoidmine minimaalsena aitavad luua efektiivseid ja vigadeta programme.
Loodetavasti andis see artikkel sulle põhjaliku ülevaate #ifdef
kasutamisest ja rakendamisest sinu arendusprojektides.