C, pekare i struct och programmeringsstilar
- lillahuset
- Gått bort
- Inlägg: 13969
- Blev medlem: 3 juli 2008, 08:13:14
- Ort: Norrköping
Re: C, pekare i struct
Ja, det med programmeringsstil och kommentering kan jag tänka är viktigt, specielt när man jobbar i grupp och programmen ska förstås av andra, lång tid efteråt också.
Nu så skriver jag bara program till mig själv, därför kan jag ha min egna stil som jag trivs med, det är:
Variabelnamn på svenska, för då ser man tydlig skillnad på egen kod och annat från ev. inlånad kod.
Egendefinierade typer slutar namnet på Typ
Pekare slutar på Pek
Pekartyper slutar på PekTyp
Egna data typer för tal ex: uInt8, uInt16, sInt8... o.s.v
Nu så skriver jag bara program till mig själv, därför kan jag ha min egna stil som jag trivs med, det är:
Variabelnamn på svenska, för då ser man tydlig skillnad på egen kod och annat från ev. inlånad kod.
Egendefinierade typer slutar namnet på Typ
Pekare slutar på Pek
Pekartyper slutar på PekTyp
Egna data typer för tal ex: uInt8, uInt16, sInt8... o.s.v
- lillahuset
- Gått bort
- Inlägg: 13969
- Blev medlem: 3 juli 2008, 08:13:14
- Ort: Norrköping
Re: C, pekare i struct
Datatyper rekommenderar jag ANSI C, uint8_t etc. I min vardag använder jag bara typerna i <stdint.h> men jag tror det finns motsvarande för flyttal.
Re: C, pekare i struct
Nu har jag provat och fått det att funka som jag vill.
Det ska bli en modul till LCD-displayer, .h och .c.
Anledningen till att jag krånglar med structar och pekare är att jag vill kunna använda modulen till olika displaer, olika antal tecken och rader m.m.
Så i huvudprogrammet ska jag kunna välja exempelvis vilken översättningstabell jag vill ha, utan att röra i modulen för LCD-displayer.
Jag har gjort ett nytt exempel, från det som nu funkar:bellPekTyp;
// tabell för att översätta tecken som ska visas på LCD.
const uInt8 OevTabellWin[][2]
= {
{ 'å', 0 },
{ 'ä', 0xE1 },
{ 'ö', 0xEF },
{ 'Å', 1 },
{ 'Ä', 2 },
{ 'Ö', 3 },
{ 0, 0 }
};
typedef struct // med inställningsvärden för display
{
uInt8 AntalKol;
uInt8 AntalRad;
uInt8 TABlaengd;
OevTabellPekTyp OevTabellPek;
} LCDinstTyp;
typedef LCDinstTyp* LCDinstPekTyp;
///////////////////////////////////////////////////
// i huvudprogrammet ställs structen in med värden:
LCDinstTyp LCD_16x1;
LCD_16x1.AntalKol = 16;
LCD_16x1.AntalRad = 2;
LCD_16x1.TABlaengd = 4;
// Pekaren i inställningarna till översättningstabellen ställs in,
// själva array-namnet är samma sak som en pekare
LCD_16x1.OevTabellPek = OevTabellWin;
// en pekare till structen ställs in.
// denna pekare används sen vid olika funktionsanrop.
LCDinstPekTyp LCDPek;
LCDPek = &LCD_16x1;
// inuti en funktion kan det se ut så här:
uInt8 tecken;
a = 1;
tecken = (*(LCDPek->OevTabellPek))[a][0];
///////////////////////////////////////////////////
// Det funkar också att ställa in pekaren i inställningarna
// med adressen till första elementet.
LCD_16x1.OevTabellPek = &OevTabellWin[0][0];
// Det märkliga är att det även funkar med:
LCD_16x1.OevTabellPek = &OevTabellWin;
// Detta tycker jag borde vara en pekare till en pekare, inkonsekvent!
[/code]
Det ska bli en modul till LCD-displayer, .h och .c.
Anledningen till att jag krånglar med structar och pekare är att jag vill kunna använda modulen till olika displaer, olika antal tecken och rader m.m.
Så i huvudprogrammet ska jag kunna välja exempelvis vilken översättningstabell jag vill ha, utan att röra i modulen för LCD-displayer.
Jag har gjort ett nytt exempel, från det som nu funkar:
Kod: Markera allt
typedef uInt8 OevTabellTyp[][2]; /* en array med x rader och 2 kolumner*/
typedef OevTabellTyp* OevTa[Code=c file=Untitled.txt]
// tabell för att översätta tecken som ska visas på LCD.
const uInt8 OevTabellWin[][2]
= {
{ 'å', 0 },
{ 'ä', 0xE1 },
{ 'ö', 0xEF },
{ 'Å', 1 },
{ 'Ä', 2 },
{ 'Ö', 3 },
{ 0, 0 }
};
typedef struct // med inställningsvärden för display
{
uInt8 AntalKol;
uInt8 AntalRad;
uInt8 TABlaengd;
OevTabellPekTyp OevTabellPek;
} LCDinstTyp;
typedef LCDinstTyp* LCDinstPekTyp;
///////////////////////////////////////////////////
// i huvudprogrammet ställs structen in med värden:
LCDinstTyp LCD_16x1;
LCD_16x1.AntalKol = 16;
LCD_16x1.AntalRad = 2;
LCD_16x1.TABlaengd = 4;
// Pekaren i inställningarna till översättningstabellen ställs in,
// själva array-namnet är samma sak som en pekare
LCD_16x1.OevTabellPek = OevTabellWin;
// en pekare till structen ställs in.
// denna pekare används sen vid olika funktionsanrop.
LCDinstPekTyp LCDPek;
LCDPek = &LCD_16x1;
// inuti en funktion kan det se ut så här:
uInt8 tecken;
a = 1;
tecken = (*(LCDPek->OevTabellPek))[a][0];
///////////////////////////////////////////////////
// Det funkar också att ställa in pekaren i inställningarna
// med adressen till första elementet.
LCD_16x1.OevTabellPek = &OevTabellWin[0][0];
// Det märkliga är att det även funkar med:
LCD_16x1.OevTabellPek = &OevTabellWin;
// Detta tycker jag borde vara en pekare till en pekare, inkonsekvent!
[/code]
-
- Inlägg: 982
- Blev medlem: 2 juli 2010, 23:04:07
Re: C, pekare i struct
Ah. Jag skulle istället göra översättningstabellen till en array of struct:ar så blir det lättare att läsa vad som är vad.
Dessutom så skulle du inte behöva göra någon krumbukter med multidimensionella arrayer.
I en nyare C-standard/nyare kompilatorer kan man instansiera strukturer med namn, som:
Själv brukar jag inte definiera pekartyper. Jag är van vid att se stjärnorna istället: jag tycker det blir lättare och mer konsekvent att läsa. Jag brukar också använda en mer konventionell namngivning och alltid använda Engelska för att inte behöva skriva "aa", "ae" och "oe".
Dessutom så skulle du inte behöva göra någon krumbukter med multidimensionella arrayer.
Kod: Markera allt
typedef struct {
uInt8 fraan, till;
} OevParTyp;
typedef OevParTyp* OevParPekTyp;
typedef struct {// med inställningsvärden för display
uint8 AntalKol;
uint8 AntalRad;
uint8 TABlaengd;
OevParPekTyp OevTabellPek;
} LCDinstTyp;
typedef LCDinstTyp* LCDinstPekTyp;
// Och definiera storleken så att kompilatorn kan kolla att den är rätt överallt där den används
#define OEV_TABELL_WIN_LAENGD 1
// Och ha för vana att använda const för mer kompilatorkoll
// Och använd const static där det går för att det kan leda till mer effektiv minnesanvändning
// Att skriva tecken utanför ASCII som char-literaler är ofta beroende av vilken teckenuppsättning kompilatorn använder.. så det är ofta lite vanskligt
const static OevParTyp OevTabellWin[OEV_TABELL_WIN_LAENGD] = {
{ 'å', 0 }
/* ... */
};
const static LCDinstTyp LCD_16x1 = {
16,
2,
OEV_TABELL_WIN_LAENGD,
OevTabellWin
};
const LCDinstPekTyp LCDPek;
LCDPek = &LCD_16x1;
Kod: Markera allt
const static LCDinstTyp LCD_16x1 = {
.AntalKol = 16,
.AntalRad = 2,
.TABlaengd = OEV_TABELL_WIN_LAENGD,
.OevTabellPek = OevTabellWin
};
- lillahuset
- Gått bort
- Inlägg: 13969
- Blev medlem: 3 juli 2008, 08:13:14
- Ort: Norrköping
Re: C, pekare i struct
Jag använder typedef med måtta. I princip bara till structar och variabler som kan behöva vara av olika typ i olika projekt. En av dessa är fft_t som ibland är double, ibland float, ibland int32_t och ibland int16_t.
Att använda typedef för pekare tycker jag bara rör till det, alltså inne på Findecanors linje.
Men det är väl en av tjusningarna med C, man har full valfrihet när det gäller vad man ska göra sig illa på.
Edit: I en kommersiell miljö är det nästan alltid bättre att använda engelska än det lokala språket. Tro mig, jag har plöjt en hel del kod skriven i Rumänien. Mina kunskaper i franska var till viss hjälp men man blev snabbt spyfärdig på allt som slutade på ul. Isländska varianten (Korpen flyger) är "Tungur knivur". Rumänsk variant skulle kunna vara "Couteaul lourdul" men jag har inget belägg för det.
Att använda typedef för pekare tycker jag bara rör till det, alltså inne på Findecanors linje.
Men det är väl en av tjusningarna med C, man har full valfrihet när det gäller vad man ska göra sig illa på.
Edit: I en kommersiell miljö är det nästan alltid bättre att använda engelska än det lokala språket. Tro mig, jag har plöjt en hel del kod skriven i Rumänien. Mina kunskaper i franska var till viss hjälp men man blev snabbt spyfärdig på allt som slutade på ul. Isländska varianten (Korpen flyger) är "Tungur knivur". Rumänsk variant skulle kunna vara "Couteaul lourdul" men jag har inget belägg för det.
Re: C, pekare i struct
Jag tycker nog också typedef, speciellt för pekare, bara rör till det.
Men ibland kan en onödig typedef också vara klargörande.
Antar att t.ex. den helt onödiga size_t är menad så.
Eller de i stdint.h: int8_t, int16_t , int32_t ...
För att återknyta till stilar. Det finns en hel del 'styleguides' på nätet:
https://google.github.io/styleguide/cppguide.html
http://www.sourceformat.com/coding-standard.htm
Många av dessa kanske tillhör historien, men jag undrar om det finns någon koncensus om vad som gäller idag.
Jag brukar annars försöka följa gnustilen ,men den tycks tyvärr kollidera med många vanliga bibliotek såsom t.ex Xlib eller STM32 Standard Peripheral Libraries, som ju också är rätt stilrena.
Så vad kan man följa idag? Kan man säga att googles guide för C++ gäller?
Men ibland kan en onödig typedef också vara klargörande.
Antar att t.ex. den helt onödiga size_t är menad så.
Eller de i stdint.h: int8_t, int16_t , int32_t ...
För att återknyta till stilar. Det finns en hel del 'styleguides' på nätet:
https://google.github.io/styleguide/cppguide.html
http://www.sourceformat.com/coding-standard.htm
Många av dessa kanske tillhör historien, men jag undrar om det finns någon koncensus om vad som gäller idag.
Jag brukar annars försöka följa gnustilen ,men den tycks tyvärr kollidera med många vanliga bibliotek såsom t.ex Xlib eller STM32 Standard Peripheral Libraries, som ju också är rätt stilrena.
Så vad kan man följa idag? Kan man säga att googles guide för C++ gäller?
- lillahuset
- Gått bort
- Inlägg: 13969
- Blev medlem: 3 juli 2008, 08:13:14
- Ort: Norrköping
Re: C, pekare i struct
Min erfarenhet är att stilar är ganska lokala företeelser. Varierar rätt mycket mellan olika företag. Och en titt i andra länken bekräftar.