Programmeringsstil i C

Elektronikrelaterade (på komponentnivå) frågor och funderingar.
pucko
Inlägg: 29
Blev medlem: 16 oktober 2006, 18:49:09

Programmeringsstil i C

Inlägg av pucko »

Hej

Hur brukar ni strukturera upp era program/projekt i C? Finns det några allmänna standarder för att struktuerar C program som går igen i varje seriöst/professionellt projekt?

Försöker ni göra det objektorienterat så mycket som möjligt eller?

Gick en AVR kurs där läraren förespråkade att man för t.ex. en display skapar en display struct typ och sedan tillhörande funktioner till denna där man bifogar en instansierad display med varje funktionsanrop.


Tack...
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Det är väl där som det kan skilja sig en del.

Efter vad jag vet finns det inte en standart men självbevarelsesdriften gör att man strukturerar ordentligt.

Nu frågar du på 'C' men användar klasser..... 'class' tillhör C++!

Jag gillar personligen C++ just för att man kan packetera klasser osv, det ger ett variabelskydd som är bra.

Jag försöker att göra alla hårdvarugrejer på ett sätt som ger mig en standart att anropa, jag har t.ex. en Send2LCD, Send2UART1 osv som tar strängar och skickar ut dom via bufferter med interruptstyrning osv, detta ger mig en standart som tar samma sorts data oavsett vilken enhet som ska nyttja dom.
Användarvisningsbild
digitaliz
Inlägg: 278
Blev medlem: 10 oktober 2003, 21:27:38
Ort: Stockholm, Sverige

Inlägg av digitaliz »

Man ska alltid försöka skriva modulärt med så få beroenden som möjligt mellan modulerna. Då får man återanvändbar och lättestad kod. Om jag skriver kod för en LCD t.ex, så gör jag en lcd.c och en lcd.h.

Sen brukar döpa funktionerna i mina moduler på detta sätt:
LCD_Init();
LCD_Write(char c);
LCD_Goto(char pos);

I h-filen brukar jag lägga definitioner som t.ex:
#define LCD_ROWS 2

Jag kunde så klart skicka med såna parametrar med LCD_Init(), men eftersom man oftast bara har en LCD i ett projekt så blir det effektivare att "hårdkoda" det på detta sätt.

Om jag har en global variabel, typ vilken kolumn LCD:ns markör ligger på, så brukar jag göra så här i c-filen:
unsigned char _LCD_Column;

och så här i h-filen:
#define LCD_GetColumn() _LCD_Column
#define LCD_SetColumn(x) _LCD_Column = x
extern unsigned char _LCD_Column;

Detta kostar inte mer kodutrymme, men gör interfacet mot din kod abstrakt, så om man senare t.ex. vill läsa kolumnsiffran från själva LCD-modulen istället för att hålla reda på den själv, så går det lätt att fixa utan att någon annan kod påverkas.
På samma sätt kan man göra om LCD_SetColumn() till en funktion och låta den skicka över kolumnsiffran till LCD-modulen automatiskt.

Resultatet blir inte alltför olikt ett objektorienterat programmeringssätt.

Om man har nått "objekt" som används flera gånger, så lägger man lämpligen alla variabler i struct och gör precis som din lärare sa. Dock "kostar" det ganska mycket kod att skicka med parametrar till funktionerna, iaf om man använder PIC med 3-byte pekare och parametrarna läggs på stacken.
Användarvisningsbild
$tiff
Inlägg: 4941
Blev medlem: 31 maj 2003, 19:47:52
Ort: Göteborg
Kontakt:

Inlägg av $tiff »

Intressant ämne! Jag undrar detsamma, i hur stor grad man använder strukturer och försöker "efterlikna" objektorienterad programmering när man skriver större/modulära C-projekt till exempelvis de mindre µC (PIC/AVR 8-bitare).

Imorgon börjar jag en kurs i C-programmering som sägs vara tuff, det ska bli intressant att veta hur föreläsaren tycker att man ska göra. Jag tror förvisso den är riktad till större plattformar än 8-bitare, men C är alltid C.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Jag tror förvisso den är riktad till större plattformar än 8-bitare, men C är alltid C.

Jo, sant å sätt och vis.

Men ju "större" plattform, ju mindre behöver man ta hänsyn till själva plattformen och istället skriva mer "ren" C.

På mindre plattformar (där PIC/AVR nog får räknas in) är det inte alltid bara att skriva sin C-kod "by-the-book"... :-)
Användarvisningsbild
$tiff
Inlägg: 4941
Blev medlem: 31 maj 2003, 19:47:52
Ort: Göteborg
Kontakt:

Inlägg av $tiff »

Ja, det "göttiga" med C är att det är tillräckligt hårdvarunära för att kunna skriva optimerat för plattformen.

Men! Å andra sidan är det alltid bra att kunna strukturera sitt projekt, möjligtvis på bekostnad av lite kodutrymme och kanske en smula prestanda.

Skräckexemplet är väl när man helt plötsligt sitter där med 50 globala variabler bara för att man implementerat fem regulatorer, och de logiska namnen börjar ta slut... :doh:

Som vanligt, lagom av varje är bäst!
Användarvisningsbild
JimmyAndersson
Inlägg: 26586
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Icecap gjorde (för några månader sedan) en tråd med bra exempel.
Har letat massor utan att hitta den. Någon kanske vet var den är?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Men! Å andra sidan är det alltid bra att kunna strukturera sitt projekt,...

Vilket ju inte är unikt för C på något vis.

Om man t.ex utnyttjar MPASM/MPLINK ordentligt, så går det bra
att skiva väl strukturerad kod, men lokala variabler, separate moduler,
återanvändbar kod, relokerbar kod, dynamisk allokering av minne o.s.v.
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Jo, det är väl inte C-relaterad men allmänt programmeringsrelaterad att ha ordning och reda, välbyggda funktioner osv.

Jag ser det som överlevnadsstrategi: blir det för rörigt blir det nära nog omöjligt att hitta buggar i och/eller uppdatera med nya/ändrade funktioner.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 47013
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Inlägg av TomasL »

En googling på C-Programming style gav dessa dokument bl.a.

http://sel.gsfc.nasa.gov/website/docume ... 94-003.pdf verkar vara tämligen heltäckande.
http://faculty.cs.tamu.edu/welch/teaching/cstyle.html
http://www.w3.org/Library/User/Style/
pucko
Inlägg: 29
Blev medlem: 16 oktober 2006, 18:49:09

Inlägg av pucko »

Jag tycker det är estetiskt roligt att få till ett välordnat program. När allt har ordning blir oftast funktionen mer stabil som sagt.

Tack för länkarna de ser lovande ut. Sökte själv utan resultat.

Om man har nått "objekt" som används flera gånger, så lägger man lämpligen alla variabler i struct och gör precis som din lärare sa. Dock "kostar" det ganska mycket kod att skicka med parametrar till funktionerna, iaf om man använder PIC med 3-byte pekare och parametrarna läggs på stacken.
Om man skickar med adressen till displayobjektet då? Menar du att även 1 parameter kostar? Lägger kompilatorn dessa parametrar på stacken tillsammans med PC? Hur gör den det då man med vanlig assembler inte kan komma åt stacken direkt?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Mjukvarustack...
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Inlägg av blueint »

Det finns några punkter man bör tänka på:
Modulärt
Lättläst
Abstraktion
Dokumenterat

Modulärt för att det gör det lättare att uppgradera koden från säg uppgift eller chip X till Y osv..
Dessutom underlättar det felsökning enormt dåd du kan ringa in problem.

Lättläst innebär att göra så att man förstår det vid första anblicken. Behöver inte nödvändligtvis vara superkonskvent.

Abstraktion så att om dina I/O portar osv flyttar på sig så slipper du skriva om koden.

Dokumenterat så alla som inte vet vad bit 5 på port 0xFE gör kan förstå det. Eller vad tr_tmp ^= 0x98; är bra för.
Användarvisningsbild
$tiff
Inlägg: 4941
Blev medlem: 31 maj 2003, 19:47:52
Ort: Göteborg
Kontakt:

Inlägg av $tiff »

Enligt länkarna från TomasL verkar det inte finnas någon vedertagen standard för funktionsprologer ("function prolog"), likt det som finns i t.ex. javadoc? Eller det är upp till varje kompilatorpaket att välja standard, om det ens finns ett system för att generera dokumentation?

Jag menar något i stil med detta:

Kod: Markera allt

/*
 * This function calculates the metric equivalent in centimeters
 * of the values in the variables feet and inches.
 *
 * @param feet   feet part of height
 * @param inches inches part of height
 * @return       height in centimeters
 */

float calculateHeight( int feet, int inches )
   {
   ...
   }
JJ
Inlägg: 366
Blev medlem: 16 maj 2005, 21:33:02

Inlägg av JJ »

doxygen liknar javadoc men används i C/C++-världen.
Skriv svar