Header filer
Header filer
Hej!
Skulle uppskatta om någon kunde förklara hur header filer ska användas. Jag har aldrig lyckats förstå det ordentligt.
Till exempel, vad lägger man i .h och vad lägger man i .c? Hur kopplar man c och h filerna (inte rent kodmässigt utan strukturellt)? Vart lägger jag mina #define? Osv osv..
Skulle uppskatta om någon kunde förklara hur header filer ska användas. Jag har aldrig lyckats förstå det ordentligt.
Till exempel, vad lägger man i .h och vad lägger man i .c? Hur kopplar man c och h filerna (inte rent kodmässigt utan strukturellt)? Vart lägger jag mina #define? Osv osv..
Re: Header filer
Definitioner läggs i *.h medan kod läggs i *.c
T.ex bör dessa hamna i huvudfilerna:
typedef struct fileio { };
extern int global_status;
#define A B
int funktion(int a, int b); // Notera semikolonet
Detta bör hamna i kodfilerna:
int global_status;
int funktion(int a, int b){
return a+b;
}
T.ex bör dessa hamna i huvudfilerna:
typedef struct fileio { };
extern int global_status;
#define A B
int funktion(int a, int b); // Notera semikolonet
Detta bör hamna i kodfilerna:
int global_status;
int funktion(int a, int b){
return a+b;
}
Re: Header filer
Såhär är det: i h-filen sätter du ditt publika gränssnitt till implementationen, allt annat "gömmer" du i c-filen.
Re: Header filer
Enkelt uttryckt.
Du har två filer, den ena fil1.c och den andra fil2.c
Om funktionerna i fil1.c skall kunna anropa funktioner och använda sig av variabler mm som finns i fil2.c, måste du tala om för fil1.c var de finns, det gör du genom att deklarera variabler och funktionsprototyper i fil2.h, som du sedan inkluderar i fil1.c.
Dock, för att undvika konstigheter så skall alla .h filer börja med
#ifndef FILx_H
#define FILEx_H
...................
....................
....................
och sluta med
#endif
Du har två filer, den ena fil1.c och den andra fil2.c
Om funktionerna i fil1.c skall kunna anropa funktioner och använda sig av variabler mm som finns i fil2.c, måste du tala om för fil1.c var de finns, det gör du genom att deklarera variabler och funktionsprototyper i fil2.h, som du sedan inkluderar i fil1.c.
Dock, för att undvika konstigheter så skall alla .h filer börja med
#ifndef FILx_H
#define FILEx_H
...................
....................
....................
och sluta med
#endif
Re: Header filer
Det har ju kommit en del konkreta förslag här, därför vill jag utveckla lite vad jag skrev tidigare.
Börja men att tänka i moduler. Försök hitta väldefinierade uppgifter som mer eller mindre fungerar stand-alone. T.ex. rutiner för att använda SPI bussen i en MCU kunde passa i en egen modul.
Den primära uppgiften för h-filen skall vara att exponera det publika gränssnittet till modulen eller c-filen. I c-filen placeras all kod som utför själva "arbetet". Det publika gränssnittet i h-filen består typiskt av datastrukturer (struct, typedef), funktionsdeklarationer, konstanter (#define), osv. Men notera, bara sådant som omvärlden *måste* känna till för att använda modulen skall finnas i h-filen. Du skall gömma allt annat i c-filen (genom att göra data och funktioner 'static') av sådant som är modulens interna angelägenheter.
I h-filen skall du också tänka på att motverka "namespace pollution". Din h-fil kan bli inkluderat på alla möjliga ställen, och då vill du ha unika och tydliga namn på saker, så att de inte "kolliderar" med nåt annat.
Om du programmerar på detta sätt bygger du upp koden modulärt, vilket leder till att det ofta blir bättre struktur på programmet som helhet, andra människor har lättare att förstå din kod, du har lättare att förstå och felsöka i din kod ett år senare. Ofta är det också lättare att återanvända gamla väldefinierade moduler i nya projekt.
Alternativet till detta kallas spagetti-kod. Funktionsanrop går kors och tvärs genom koden, en modul manipulerar direkt interna angelägenheter i en annan modul eftersom allt är exponerat för alla. Spagetti-kod kan vara helt okay i snabba mock-up program, eller om man vet att bara en själv skall pyssla med koden under mycket begränsad tid, osv. Men som regel bör man undvika spagetti-tänket.
Börja men att tänka i moduler. Försök hitta väldefinierade uppgifter som mer eller mindre fungerar stand-alone. T.ex. rutiner för att använda SPI bussen i en MCU kunde passa i en egen modul.
Den primära uppgiften för h-filen skall vara att exponera det publika gränssnittet till modulen eller c-filen. I c-filen placeras all kod som utför själva "arbetet". Det publika gränssnittet i h-filen består typiskt av datastrukturer (struct, typedef), funktionsdeklarationer, konstanter (#define), osv. Men notera, bara sådant som omvärlden *måste* känna till för att använda modulen skall finnas i h-filen. Du skall gömma allt annat i c-filen (genom att göra data och funktioner 'static') av sådant som är modulens interna angelägenheter.
I h-filen skall du också tänka på att motverka "namespace pollution". Din h-fil kan bli inkluderat på alla möjliga ställen, och då vill du ha unika och tydliga namn på saker, så att de inte "kolliderar" med nåt annat.
Om du programmerar på detta sätt bygger du upp koden modulärt, vilket leder till att det ofta blir bättre struktur på programmet som helhet, andra människor har lättare att förstå din kod, du har lättare att förstå och felsöka i din kod ett år senare. Ofta är det också lättare att återanvända gamla väldefinierade moduler i nya projekt.
Alternativet till detta kallas spagetti-kod. Funktionsanrop går kors och tvärs genom koden, en modul manipulerar direkt interna angelägenheter i en annan modul eftersom allt är exponerat för alla. Spagetti-kod kan vara helt okay i snabba mock-up program, eller om man vet att bara en själv skall pyssla med koden under mycket begränsad tid, osv. Men som regel bör man undvika spagetti-tänket.
Re: Header filer
> Men notera, bara sådant som omvärlden *måste* känna till för att använda modulen
> skall finnas i h-filen. Du skall gömma allt annat i c-filen (genom att göra data och
> funktioner 'static') av sådant som är modulens interna angelägenheter.
Nu så är det ju alltid svårt att skriva generella förklaringar i enbart ett par meningar.
Men jag vill bara göra ett tillägg till ovanstående...
Man kan ju ganska lätt tänka sig en "modul" (t.ex för SPI hantering) som i sig består av
fler än en C fil. I det fallet kan det ju vara bättre att ha interna definitier i en MODUL.H
(t.ex) och själva API't i en MODUL_API.H (eller vad man nu vill kalla det). Jag menar att
bara för att definitioner är "interna" så behöver de inte nödvändigtvis vara i C-filen...
> skall finnas i h-filen. Du skall gömma allt annat i c-filen (genom att göra data och
> funktioner 'static') av sådant som är modulens interna angelägenheter.
Nu så är det ju alltid svårt att skriva generella förklaringar i enbart ett par meningar.

Men jag vill bara göra ett tillägg till ovanstående...
Man kan ju ganska lätt tänka sig en "modul" (t.ex för SPI hantering) som i sig består av
fler än en C fil. I det fallet kan det ju vara bättre att ha interna definitier i en MODUL.H
(t.ex) och själva API't i en MODUL_API.H (eller vad man nu vill kalla det). Jag menar att
bara för att definitioner är "interna" så behöver de inte nödvändigtvis vara i C-filen...
Re: Header filer
Hehe, jag valde att inte skriva om detta undantag. Du har helt rätt sodjan.
Dessutom är det förståss fritt fram att bryta mot vedertagna normer om något annat system passar bättre för det man håller på med.
Dessutom är det förståss fritt fram att bryta mot vedertagna normer om något annat system passar bättre för det man håller på med.
Re: Header filer
Förutom funktioner som måste ligga där för att länkningen skall funka om man anropar från en annan fil tänker jag så här:
Om någon annan skall använda mitt lib eller vad det nu är, skall de inte behöva titta i c-koden.
Alltså lägger jag alla definitioner av strukturer och annat som den som ropar kan vara i behov att deklarera,
externa makron, #defines som kan behöva ändras. Kommentarer som beskriver användandet..
Saker som är internt lägger jag hellre i c-filen, även om jag inte gillar det estetiskt.
Om någon annan skall använda mitt lib eller vad det nu är, skall de inte behöva titta i c-koden.
Alltså lägger jag alla definitioner av strukturer och annat som den som ropar kan vara i behov att deklarera,
externa makron, #defines som kan behöva ändras. Kommentarer som beskriver användandet..
Saker som är internt lägger jag hellre i c-filen, även om jag inte gillar det estetiskt.
Re: Header filer
Dessutom kan du ju alltid kompilera dit lib till en objektfil, då finns det ju ingen som kan se vad du gjort, och länkaren använder .h filen för att hitta rätt.
Re: Header filer
Nu blir det lite detaljer här, men länkaren använder normalt inte .h
filerna alls. All information samlas i objektfilen och länkaren hämtar det
den behöver där. Det är kompilatorn som använder .h filerna.
filerna alls. All information samlas i objektfilen och länkaren hämtar det
den behöver där. Det är kompilatorn som använder .h filerna.
Re: Header filer
Jo, det är sant det är kompilatorn, länkaren använder symbolbordet, gick lite snabbt där.. Till mitt försvar har jag hållit mig ifrån C i 10+ år, tills förra veckan 

Re: Header filer
Jag tycker det är enklast att beskriva det så här:
Du KAN skriva ditt program i en enda fil. Då behöva inga headerfiler eller nåt utan bara en enda stor fil.
Men det blir svårt att hitta i en enda stor fil... det blir enklare om man delar upp det i mindre filer. Problemet då blir att när de mindre filerna kompileras så vet de ingenting om varandra. Det är där .h-filerna kommer in. Det som behöver kunna delas mellan olika filer lägger man i .h-filer.
Du KAN skriva ditt program i en enda fil. Då behöva inga headerfiler eller nåt utan bara en enda stor fil.
Men det blir svårt att hitta i en enda stor fil... det blir enklare om man delar upp det i mindre filer. Problemet då blir att när de mindre filerna kompileras så vet de ingenting om varandra. Det är där .h-filerna kommer in. Det som behöver kunna delas mellan olika filer lägger man i .h-filer.
Re: Header filer
> gick lite snabbt där..
Nu så var det TomasL's inlägg som jag primärt kommenterade...
Men nu när du nämner det så har du ju samma "fel" där också...
> Det är där .h-filerna kommer in. Det som behöver kunna delas mellan olika filer lägger man i .h-filer.
Det kan vara värt att också notera att det är inget speciellt med just .h filer, de är
som vilken textfil som helst som man kan göra "include" på. Där jag kör ligger de dessutom
inte som .h filer utan som ett "text library" (.tlb) som kompilatorn hämtar de olika
modulerna från. Fördelen är att det bara blir en fil som behöver öppnas...
Nu så var det TomasL's inlägg som jag primärt kommenterade...

Men nu när du nämner det så har du ju samma "fel" där också...

> Det är där .h-filerna kommer in. Det som behöver kunna delas mellan olika filer lägger man i .h-filer.
Det kan vara värt att också notera att det är inget speciellt med just .h filer, de är
som vilken textfil som helst som man kan göra "include" på. Där jag kör ligger de dessutom
inte som .h filer utan som ett "text library" (.tlb) som kompilatorn hämtar de olika
modulerna från. Fördelen är att det bara blir en fil som behöver öppnas...
Re: Header filer
Ett sätt att kontrollera om .h-filen är "godkänd" är att kompilera den.
Den skall ge 0 byte ut.
Alltså, den skall inte innehålla kod av något slag.
Se det som att du skall kunna göra "#include" på din h-fil hur många gånger som helst utan att nåt "farligt" händer.
---
Men med det sagt, ack så bekvämt det är att ibland lägga ett par oumbärliga kodsnuttar i en speciell h-fil som snabbt och smidigt includas när den behövs. Tex:
#include "mydebug.h"

Den skall ge 0 byte ut.
Alltså, den skall inte innehålla kod av något slag.
Se det som att du skall kunna göra "#include" på din h-fil hur många gånger som helst utan att nåt "farligt" händer.
---
Men med det sagt, ack så bekvämt det är att ibland lägga ett par oumbärliga kodsnuttar i en speciell h-fil som snabbt och smidigt includas när den behövs. Tex:
#include "mydebug.h"

