C Academy · Lektion

Include guards

Forhindr dobbelt inklusion.

Lektion 2 af 413 trin

Include guards er en gratis C Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C Academy-kurset indeholder 4 lektioner i alt.

Problemet med dobbelt inklusion

Headere inkluderer ofte andre headere. Det er nemt for én header at ende med at blive inkluderet to gange i den samme kildefil.

Når det sker, forekommer alle deklarationer i den to gange. For typedefinitioner som struct eller typedef er det en kompileringsfejl: en type kan ikke defineres mere end én gang.

Sådan opstår problemet

Antag, at a.h og b.h begge inkluderer types.h. En kildefil, der inkluderer begge, ender med at have types.h indsat to gange.

Præprocessoren kopierer blindt headerteksten, så definitionerne i types.h bliver duplikeret, hvilket udløser en fejl om gentagen definition.

/* a.h */ #include "types.h"
/* b.h */ #include "types.h"
/* main.c */
#include "a.h"
#include "b.h"   /* types.h now seen twice */

Inklusionsbeskyttelsen

En inklusionsbeskyttelse er et lille præprocessortrick, der gør en header sikker at inkludere mange gange.

Den omslutter hele headeren i en betingelse, så indholdet kun behandles første gang. Senere inklusioner springes helt over.

#ifndef TYPES_H
#define TYPES_H

/* header contents here */

#endif /* TYPES_H */

Sådan fungerer beskyttelsen

Første gang headeren ses, er TYPES_H ikke defineret, så #ifndef er sand, og indholdet behandles. Derefter sætter #define makroen.

Ved alle senere inklusioner findes TYPES_H allerede, så #ifndef er falsk, og præprocessoren springer frem til #endif.

#ifndef TYPES_H   /* true only the first time */
#define TYPES_H   /* remember we've been here */
/* ... body ... */
#endif

En komplet beskyttet header

Her er en realistisk header med en beskyttelse, der beskytter en typedefinition.

Selv hvis mange filer inkluderer point.h direkte eller indirekte, defineres Point-strukturen præcis én gang pr. translationsenhed.

/* point.h */
#ifndef POINT_H
#define POINT_H

typedef struct {
    int x;
    int y;
} Point;

Point point_add(Point a, Point b);

#endif

Valg af makronavn

Beskyttelsesmakroen skal være unik i hele projektet, ellers kan to headere kollidere og skjule hinanden uden en tydelig fejl.

En almindelig konvention danner navnet ud fra filnavnet med store bogstaver: point.h bliver til POINT_H, og net/socket.h bliver til NET_SOCKET_H.

#ifndef NET_SOCKET_H
#define NET_SOCKET_H
/* ... */
#endif

Undgå reserverede navne

Identifikatorer, der begynder med en understregning efterfulgt af et stort bogstav, eller som indeholder dobbelte understregninger, er reserveret til compileren og standardbiblioteket.

Undgå beskyttelser som __POINT_H__. En enkel afsluttende form som POINT_H er sikker og tydelig.

#ifndef _POINT_H_   /* risky: reserved name pattern */
#ifndef POINT_H     /* preferred */

Alternativet #pragma once

De fleste moderne compilere understøtter #pragma once, en enkelt linje øverst i en header, der udfører den samme opgave.

Det er kortere og undgår navnekollisioner, men det er ikke en del af C-standarden. Traditionelle #ifndef-beskyttelser fungerer overalt.

/* point.h */
#pragma once

typedef struct { int x; int y; } Point;

Beskyttelser kontra pragma

#ifndef-beskyttelser er fuldt portable og standardiserede, men kræver en unik makro for hver header.

#pragma once er kompakt og uden kollisionsrisiko, men afhænger af compilerens understøttelse. Nogle projekter bruger begge dele: en pragma plus en klassisk beskyttelse for maksimal sikkerhed.

#pragma once
#ifndef POINT_H
#define POINT_H
/* ... */
#endif

Beskyttelser gælder pr. translationsenhed

En inklusionsbeskyttelse forhindrer dobbelt inklusion i en enkelt kildefil, mens den kompileres.

Den forhindrer ikke, at en header behandles én gang i hver separat .c-fil. Det er helt i orden, fordi hver kildefil er en særskilt translationsenhed.

Gør det til en vane

Tilføj en inklusionsbeskyttelse til hver header, du skriver, helt fra første linje. Det koster tre linjer og forhindrer en hel klasse af forvirrende fejl.

Selv simple headere kan senere blive inkluderet indirekte gennem andre, så du sparer problemer ved at beskytte dem fra starten.

/* config.h */
#ifndef CONFIG_H
#define CONFIG_H
#define MAX_USERS 100
#endif

Hurtig kontrol

Kontrollér, hvor godt du forstår inklusionsbeskyttelser.

Opsummering

Du har lært, hvorfor inklusion af en header to gange forårsager fejl med gentagne definitioner, og hvordan en inklusionsbeskyttelse forhindrer det.

Brug #ifndef/#define/#endif med en unik makro eller #pragma once. Derefter ser vi på, hvordan variabler deles mellem filer med extern.

Gratis at komme i gang

Lær C med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
39
Lektioner
144

Ofte stillede spørgsmål

Er lektionen “Include guards” gratis?

Ja — hele teksten til “Include guards” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C Academy-kurset, skal du opgradere til CoddyKit PRO. C Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Include guards”?

Forhindr dobbelt inklusion. Du øver dig i C Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på C Academy?

Der kræves ingen tidligere erfaring. C Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.

Hvor lang tid tager lektionen “Include guards”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne C Academy-lektion?

Ja. Alle C Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Header- og source-filer
  2. Include guards
  3. extern og linkage
  4. Kompilér flere filer
← Tilbage til C Academy