Har C++ bättre struktur på funktioner? […än C? — mod]

Permalänk

Har C++ bättre struktur på funktioner? […än C? — mod]

Hej.

Jag har en hel del funktioner som jag har delat in i flera grupper. Dessa funktioner är följande:

  • Output - Relä 1 ON, Relä 1 OFF, Relä 2 ON, Relä 2 OFF, Show digit on display, PC speaker pulse ON, PC speaker pulse OFF, Tempensor 1, Tempsensor 2.

  • Input - Keypad

  • Program 1 - setTemp1, SetTemp2, SetTime1, SetTime 2,

  • Program 2 - SetRelay1 ON, SetRelay2 OFF, SetTimeArray

Jag programmerar i en mikrokontroller och den mikrokontrollern är ihopkopplad med en nummerplatta för att styra vad man vill göra.
Det är en hel del funktioner och skulle C++ vara lämpligare nu att använda? Jag tänkte framför allt klasser. Men hur ska jag göra det?

Jag är totalt kass på classer inom C++, trots att jag kan skriva dem ändå med hjälp av tutorials. Men jag tycker att klasser känns både onödigt och overkill då klasser är mer tänkt för att man ska skapa ett objekt och kunna kopiera det.

Finns det inget annat bättre sätt att strukturera upp funktioner?

Tydligare rubrik; det finns fler språk än C och C++ :-)
Permalänk
Medlem
Skrivet av heretic16:

Hej.

Jag har en hel del funktioner som jag har delat in i flera grupper. Dessa funktioner är följande:

  • Output - Relä 1 ON, Relä 1 OFF, Relä 2 ON, Relä 2 OFF, Show digit on display, PC speaker pulse ON, PC speaker pulse OFF, Tempensor 1, Tempsensor 2.

  • Input - Keypad

  • Program 1 - setTemp1, SetTemp2, SetTime1, SetTime 2,

  • Program 2 - SetRelay1 ON, SetRelay2 OFF, SetTimeArray

Jag programmerar i en mikrokontroller och den mikrokontrollern är ihopkopplad med en nummerplatta för att styra vad man vill göra.
Det är en hel del funktioner och skulle C++ vara lämpligare nu att använda? Jag tänkte framför allt klasser. Men hur ska jag göra det?

Jag är totalt kass på classer inom C++, trots att jag kan skriva dem ändå med hjälp av tutorials. Men jag tycker att klasser känns både onödigt och overkill då klasser är mer tänkt för att man ska skapa ett objekt och kunna kopiera det.

Finns det inget annat bättre sätt att strukturera upp funktioner?

Fråga är först: om din microkontroller kan tolka c++/cpp?

Visa signatur

~. Citera så jag hittar tillbaka .~

Permalänk

Håller lite med dig. Nu vet jag inte riktigt hur din kod ser ut men jag kan tänka mig en situation då en klass vore mer lämplig(enligt min mening) och det är om du har data som är gemensam för funktionerna som globala variabler. Då tycker jag att det är bättre att skapa en klass som då får fungera som en behållare för både data och funktioner.

Annars är det nog en smaksak vad man föredrar. Om funktionerna inte delar någon form av data så hade jag nog bara försökt lägga dem i lite olika namespaces för att kanske förtydliga vad de gör och om funktionerna hade delat någon form av data så hade jag försökt samla dem i klasser.

Permalänk
Skrivet av Superhepper:

Håller lite med dig. Nu vet jag inte riktigt hur din kod ser ut men jag kan tänka mig en situation då en klass vore mer lämplig(enligt min mening) och det är om du har data som är gemensam för funktionerna som globala variabler. Då tycker jag att det är bättre att skapa en klass som då får fungera som en behållare för både data och funktioner.

Annars är det nog en smaksak vad man föredrar. Om funktionerna inte delar någon form av data så hade jag nog bara försökt lägga dem i lite olika namespaces för att kanske förtydliga vad de gör och om funktionerna hade delat någon form av data så hade jag försökt samla dem i klasser.

Visst måste jag då sätta varje funktion i klassen som static?

Permalänk
Skrivet av KeVVa:

Fråga är först: om din microkontroller kan tolka c++/cpp?

Arduinos språk är faktiskt C++

Permalänk
Medlem
Skrivet av heretic16:

Arduinos språk är faktiskt C++

Du nämnde aldrig att du lekte med en Arduino. Men, jo arduino använder en variant av C/C++!

Visa signatur

~. Citera så jag hittar tillbaka .~

Permalänk
Skrivet av KeVVa:

Du nämnde aldrig att du lekte med en Arduino. Men, jo arduino använder en variant av C/C++!

Ska man vara exakt så är det C++ och inte C för att i C finns det inte färdiga klasser att jobba med
Men nog om det.

Finns det ett enklare sätt att strukturera upp denna kod:

Jag kategorisera dessa som

  • Input - digitalKeyPad()

  • Output - show_digit(int i), relay_lak(), relay_kok(), speaker()

  • Program 1 - setEndTimeKok(), setBeginTimeLak(), setTempKok(), setTempLak(), getTempKok(), getTempLak()

  • Program 1 - setTimeHumle()

Det är ingen hembrännare jag ska göra. Men det har något med alkohol att göra också
Måste jag skapa en klass som heter "input" och alla funktioner har jag som statiska? Bry er inte om "void". Jag har inte tänkt ut direkt om dem ska skicka tillbaka något eller inte.

#include <LedControl.h> #include <Keypad.h> // MAX7219 inputs: DIN pin, CLK pin, LOAD pin. number of chips LedControl mydisplay = LedControl(13, 12, 11, 1); // Digital Keypad 4x4 const byte rows = 4; //four rows const byte cols = 3; //three columns char keys[rows][cols] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'#','0','*'} }; byte rowPins[rows] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad byte colPins[cols] = {6, 5, 4}; //connect to the column pinouts of the keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols ); void setup() { mydisplay.shutdown(0, false); // turns on display mydisplay.setIntensity(0, 15); // 15 = brightest pinMode(13, OUTPUT); // Green LED } void loop() { } void setTimeHumle() { } void speaker() { } void setEndTimeKok() { } void setTempKok() { } void setBeginTimeLak() { } void setTempLak() { } void relay_kok() { } void relay_lak() { } void getTempKok() { } void getTempLak() { } int tempsensor_kok() { // get average temperature } int tempsensor_lak() { // get average temperature } int digitalKeyPad() { } void show_digit(int i) { // if i is 4 digit if (i >= 1000) { String str = String(i); char charBuf[5]; str.toCharArray(charBuf, 5); int a = charBuf[0] - '0'; int b = charBuf[1] - '0'; int c = charBuf[2] - '0'; int d = charBuf[3] - '0'; mydisplay.setDigit(0, 0, a, false); mydisplay.setDigit(0, 1, b, true); mydisplay.setDigit(0, 2, c, false); mydisplay.setDigit(0, 3, d, false); } // if i is 3 digit else if (i <= 999 && i >= 100) { String str = String(i); char charBuf[4]; str.toCharArray(charBuf, 4); int a = charBuf[0] - '0'; int b = charBuf[1] - '0'; int c = charBuf[2] - '0'; mydisplay.setDigit(0, 0, 0, false); mydisplay.setDigit(0, 1, a, true); mydisplay.setDigit(0, 2, b, false); mydisplay.setDigit(0, 3, c, false); } // if i is 2 digit else if(i < 100 && i >= 10) { String str = String(i); char charBuf[3]; str.toCharArray(charBuf, 3); int a = charBuf[0] - '0'; int b = charBuf[1] - '0'; mydisplay.setDigit(0, 0, 0, false); mydisplay.setDigit(0, 1, 0, false); mydisplay.setDigit(0, 2, a, false); mydisplay.setDigit(0, 3, b, false); } else // if i is 1 digit { String str = String(i); char charBuf[2]; str.toCharArray(charBuf, 2); int a = charBuf[0] - '0'; mydisplay.setDigit(0, 0, 0, false); mydisplay.setDigit(0, 1, 0, false); mydisplay.setDigit(0, 2, 0, false); mydisplay.setDigit(0, 3, a, false); } }

Permalänk
Medlem
Skrivet av heretic16:

Ska man vara exakt så är det C++ och inte C för att i C finns det inte färdiga klasser att jobba med
Men nog om det.

Finns det ett enklare sätt att strukturera upp denna kod:

Jag kategorisera dessa som

  • Input - digitalKeyPad()

  • Output - show_digit(int i), relay_lak(), relay_kok(), speaker()

  • Program 1 - setEndTimeKok(), setBeginTimeLak(), setTempKok(), setTempLak(), getTempKok(), getTempLak()

  • Program 1 - setTimeHumle()

Det är ingen hembrännare jag ska göra. Men det har något med alkohol att göra också
Måste jag skapa en klass som heter "input" och alla funktioner har jag som statiska? Bry er inte om "void". Jag har inte tänkt ut direkt om dem ska skicka tillbaka något eller inte.

#include <LedControl.h> #include <Keypad.h> // MAX7219 inputs: DIN pin, CLK pin, LOAD pin. number of chips LedControl mydisplay = LedControl(13, 12, 11, 1); // Digital Keypad 4x4 const byte rows = 4; //four rows const byte cols = 3; //three columns char keys[rows][cols] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'#','0','*'} }; byte rowPins[rows] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad byte colPins[cols] = {6, 5, 4}; //connect to the column pinouts of the keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols ); void setup() { mydisplay.shutdown(0, false); // turns on display mydisplay.setIntensity(0, 15); // 15 = brightest pinMode(13, OUTPUT); // Green LED } void loop() { } void setTimeHumle() { } void speaker() { } void setEndTimeKok() { } void setTempKok() { } void setBeginTimeLak() { } void setTempLak() { } void relay_kok() { } void relay_lak() { } void getTempKok() { } void getTempLak() { } int tempsensor_kok() { // get average temperature } int tempsensor_lak() { // get average temperature } int digitalKeyPad() { } void show_digit(int i) { // if i is 4 digit if (i >= 1000) { String str = String(i); char charBuf[5]; str.toCharArray(charBuf, 5); int a = charBuf[0] - '0'; int b = charBuf[1] - '0'; int c = charBuf[2] - '0'; int d = charBuf[3] - '0'; mydisplay.setDigit(0, 0, a, false); mydisplay.setDigit(0, 1, b, true); mydisplay.setDigit(0, 2, c, false); mydisplay.setDigit(0, 3, d, false); } // if i is 3 digit else if (i <= 999 && i >= 100) { String str = String(i); char charBuf[4]; str.toCharArray(charBuf, 4); int a = charBuf[0] - '0'; int b = charBuf[1] - '0'; int c = charBuf[2] - '0'; mydisplay.setDigit(0, 0, 0, false); mydisplay.setDigit(0, 1, a, true); mydisplay.setDigit(0, 2, b, false); mydisplay.setDigit(0, 3, c, false); } // if i is 2 digit else if(i < 100 && i >= 10) { String str = String(i); char charBuf[3]; str.toCharArray(charBuf, 3); int a = charBuf[0] - '0'; int b = charBuf[1] - '0'; mydisplay.setDigit(0, 0, 0, false); mydisplay.setDigit(0, 1, 0, false); mydisplay.setDigit(0, 2, a, false); mydisplay.setDigit(0, 3, b, false); } else // if i is 1 digit { String str = String(i); char charBuf[2]; str.toCharArray(charBuf, 2); int a = charBuf[0] - '0'; mydisplay.setDigit(0, 0, 0, false); mydisplay.setDigit(0, 1, 0, false); mydisplay.setDigit(0, 2, 0, false); mydisplay.setDigit(0, 3, a, false); } }

Jag har aldrig skrivit Arduino object orienterat utan bara funktionellt. Man kan ju dela upp en sketch till flera små!

Är det något sånt här du vill göra? http://www.brewpi.com/

Visa signatur

~. Citera så jag hittar tillbaka .~

Permalänk
Skrivet av heretic16:

Visst måste jag då sätta varje funktion i klassen som static?

Det beror ju på hur du har tänkt att använda dig av klassen. Om du hade tänkt det så att du aldrig skall skapa klassen utan bara anropa funktionerna. Ja, då vill du ha static på nästan allt. Det är ju ett sätt man kan göra det på och det kanske är det rätta sättet att göra det på i ditt fall.

Jag tror att jag personligen inte skulle försöka göra det på det sättet. jag skulle nog vara betydligt mer omständig hehe...
Jag tror att jag skulle göra en singleton av det istället.

Permalänk
Hedersmedlem

Att byta språk bara för att kunna använda klasser på det där sättet låter kanske lite drastiskt. Vad vill du egentligen uppnå? Kan man inte bara till exempel ange gruppen i funktionsnamnen, gruppera funktionerna i .h-filen eller kanske till och med ha olika filer för olika funktionsgrupper?

Permalänk
Skrivet av Elgot:

Att byta språk bara för att kunna använda klasser på det där sättet låter kanske lite drastiskt. Vad vill du egentligen uppnå? Kan man inte bara till exempel ange gruppen i funktionsnamnen, gruppera funktionerna i .h-filen eller kanske till och med ha olika filer för olika funktionsgrupper?

Dels för att lära mig mer strukturera funktioner.
.h-filer låter inte dumt. Jag ska ta och kika på det.

Så .h filer är bara till för att deklarera andra .c filer att dem existerar?

Jag har tagit ett utdrag.
foo.h

#ifndef FOO_H_ /* Include guard */ #define FOO_H_ int foo(int x); /* An example function declaration */ #endif

foo.c

Citat:

#include "foo.h" /* Include the header (not strictly necessary here) */

int foo(int x) /* Function definition */
{
return x + 5;
}

main.c

#include <stdio.h> #include "foo.h" /* Include the header here, to obtain the function declaration */ int main(void) { int y = foo(3); /* Use the function here */ printf("%d\n", y); return 0; }

To compile using GCC

gcc -o my_app main.c foo.c

Nu är det så mycket text för mig och jag undrar om main.c hade anropat funktionen doo() också eller moo(). Hur hade det sett ut då?

Varför skrivs det ändå ut att den har header?

/* Include the header (not strictly necessary here) */

Är dessa nödvändig i början på h fil?

#ifndef NAMNPAANDRAFILEN_H_ /* Include guard */ #define NAMNPAANDRAFILEN_H_ // massa funktioner #endif

Permalänk
Hedersmedlem
Skrivet av heretic16:

Så .h filer är bara till för att deklarera andra .c filer att dem existerar?

I princip ja (tekniskt sett kan man ha dem till vad man vill). Raden

int foo(int x);

säger "det finns en funktion foo som tar en int och returnerar en int, men den definieras inte här" och är en så kallad funktionsdeklaration. Sådana rader kan man skriva överallt där man behöver tala om för kompilatorn att funktionen visst finns (om du försöker anropa doo() kommer du få ett felmeddelande om att en sådan funktion inte finns) eller också samlar man ihop många i en .h-fil och inkluderar den istället. #include x betyder bara att filen x skall klistras in på den platsen före kompilering.

Deklarationer kan man ha många av om man vill, men om man till exempel försöker definiera samma funktion flera gånger kommer kompilatorn klaga (typiskt "redefinition of x ... previous definition was here". Sådant sker lätt om man till exempel inkluderar en .h-fil som i sin tur inkluderar en .h-fil som redan har inkluderats. Med hjälp av till exempel de där ifndef-konstruktionerna kan man undvika detta genom att endast inkludera det som står mellan ifndef
och endif så länge NAMNPAANDRAFILEN_H_ (i det där fallet) inte har definierats, och det första man gör är i så fall att definiera den.

Det som inte är nödvändigt i exemplet är att inkludera .h-filen i den fil som innehåller tillhörande definitioner. Definitionen innehåller ju samma (mer till och med) information som deklaration, men det kan ändå vara en god idé att inkludera; om inte annat för att komma ihåg att uppdatera den andra om man ändrar den ena.

Permalänk

Men vi säger att jag vill anropa två funktioner.

headerfile.h

#ifndef HEADERFILE /* Include guard */ #define HEADERFILE int foo(int x); /* An example function declaration */ float doo(int y); /* An example function declaration */ #endif

headerfile.c

int foo(int x) /* Function definition */ { return x + 5; } float doo(int y) { return y - 10; }

#include <stdio.h> #include "headerfile.h" /* Include the header here, to obtain the function declaration */ int main(void) { int x = foo(3); /* Use the function here */ int y = doo(8); printf("%d\n", x); printf("%d\n", y); return 0; }

Headerfilen kommer inkludera

int foo(int x); /* An example function declaration */ float doo(int y); /* An example function declaration */

som

#include "headerfile.h" /* Include the header here, to obtain the function declaration */

Men jag hade tänkt att man skulle kunna anropa funktioner igenom.

CPU.Program1.Metod.Funktion()

Men det kanske är C++?
Hur skulle du ha gjort om du ville strukturera upp funktioner?

Permalänk
Hedersmedlem
Skrivet av heretic16:

Men vi säger att jag vill anropa två funktioner.

headerfile.h

#ifndef HEADERFILE /* Include guard */ #define HEADERFILE int foo(int x); /* An example function declaration */ float doo(int y); /* An example function declaration */ #endif

headerfile.c

int foo(int x) /* Function definition */ { return x + 5; } float doo(int y) { return y - 10; }

#include <stdio.h> #include "headerfile.h" /* Include the header here, to obtain the function declaration */ int main(void) { int x = foo(3); /* Use the function here */ int y = doo(8); printf("%d\n", x); printf("%d\n", y); return 0; }

Headerfilen kommer inkludera

int foo(int x); /* An example function declaration */ float doo(int y); /* An example function declaration */

som

#include "headerfile.h" /* Include the header here, to obtain the function declaration */

Men jag hade tänkt att man skulle kunna anropa funktioner igenom.

CPU.Program1.Metod.Funktion()

Men det kanske är C++?
Hur skulle du ha gjort om du ville strukturera upp funktioner?

Dold text

Konceptet du verkar leta efter kallas "namnrymder". C har inte direkt inbyggt stöd för sådana.

Du är dock fri att döpa dina externa funktioner till vad du vill (eller ja, det var en grov lögn, men inom [A-Za-z0-9_] så länge de inte börjar med en siffra, kort sagt), så ett konventionellt sätt att emulera namnrymder är att ge sina funktioner ett biblioteksprefix följt av ett (eller ibland två) understreck, dvs i stället för `foo` och `doo` som i ditt exempel så kanske de heter `library_foo` och `library_doo`. Vill man sedan tvunget "importera" en funktion in i huvudnamnrymden i en annan fil så kan man emulera det genom ett makro så som `#define foo library_foo`.

Jag säger inte att det är lika strukturerat som "riktiga" namnrymder, men det är den design som C lyder under, i stort. Det finns andra tankesätt för att försöka emulera mer traditionella namnrymder genom exempelvis `struct`, men det har sina egna nackdelar; inte minst är det rätt krångligt för rätt lite vinst, och kanske framför allt inte så konventionellt.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Skrivet av phz:

Konceptet du verkar leta efter kallas "namnrymder". C har inte direkt inbyggt stöd för sådana.

Du är dock fri att döpa dina externa funktioner till vad du vill (eller ja, det var en grov lögn, men inom [A-Za-z0-9_] så länge de inte börjar med en siffra, kort sagt), så ett konventionellt sätt att emulera namnrymder är att ge sina funktioner ett biblioteksprefix följt av ett (eller ibland två) understreck, dvs i stället för `foo` och `doo` som i ditt exempel så kanske de heter `library_foo` och `library_doo`. Vill man sedan tvunget "importera" en funktion in i huvudnamnrymden i en annan fil så kan man emulera det genom ett makro så som `#define foo library_foo`.

Jag säger inte att det är lika strukturerat som "riktiga" namnrymder, men det är den design som C lyder under, i stort. Det finns andra tankesätt för att försöka emulera mer traditionella namnrymder genom exempelvis `struct`, men det har sina egna nackdelar; inte minst är det rätt krångligt för rätt lite vinst, och kanske framför allt inte så konventionellt.

Arduinos språk är ju C++ då det är objektorienterat så jag tänkte lämna C bakom mig nu och gå vidare. C var bra, men C++ gör det lite enklare att skriva koden då allt det svåra är redan färdigt.

Bibliotek som redan är skrivna och importerade får vara importerade. Jag hade bara tänkt och anropa mina funktioner som C++ stil.
Typ att jag börjar först med CPU som hufvudklassen eller vad man ska och sedan vilket del av programmen man vill köra. Det ska vara två olika program. Program1, Program2, Program3. Dessa program ska ha ett visst antal funktioner man kan välja mellan. Vissa funktioner retunerar ett värde, vissa inte.

Jag vill börja på enkelt nivå så jag gör bara en klass av de funktioner jag har skapat och inte vad andra har skapat från sina bibliotek

Permalänk
Hedersmedlem
Skrivet av heretic16:

Men jag hade tänkt att man skulle kunna anropa funktioner igenom.

CPU.Program1.Metod.Funktion()

Men det kanske är C++?
Hur skulle du ha gjort om du ville strukturera upp funktioner?

Det "är" varken c eller c++; ofta försöker man nog inte "strukturera" sina funktioner utom möjligtvis i dokumentation eller liknande. Många bibliotek och liknande (främst c++ då (boost till exempel)) är dock uppbyggda med namnrymder och klasser (så att man kan skriva saker som boost::asio::io_service), men då är det nog snarare en konsekvens av att man utnyttjar klasser för att ärva funktionalitet och göra biblioteket modulärt än att man vill strukturera funktionerna.

Permalänk
Skrivet av Elgot:

Det "är" varken c eller c++; ofta försöker man nog inte "strukturera" sina funktioner utom möjligtvis i dokumentation eller liknande. Många bibliotek och liknande (främst c++ då (boost till exempel)) är dock uppbyggda med namnrymder och klasser (så att man kan skriva saker som boost::asio::io_service), men då är det nog snarare en konsekvens av att man utnyttjar klasser för att ärva funktionalitet och göra biblioteket modulärt än att man vill strukturera funktionerna.

Om det verkligen inte är C eller C++. Då tror jag tar tillbaka allt sagt om C++ och förhåller mig vid C som vanligt.
Då får jag väll ha funktioner utspridda lite överallt och sedan anropa dessa när jag känner för det.

Permalänk
Hedersmedlem
Skrivet av heretic16:

Om det verkligen inte är C eller C++. Då tror jag tar tillbaka allt sagt om C++ och förhåller mig vid C som vanligt.
Då får jag väll ha funktioner utspridda lite överallt och sedan anropa dessa när jag känner för det.

På många sätt ser ju c och c++ rätt lika ut och "funktioner utspridda lite överallt" är väl rätt vanligt i båda. Med hjälp av till exempel klasser kan man ju dock få det att se ut ungefär som du beskriver, men då har man nog som sagt vanligtvis utnyttjat klasser för att implementera funktionaliteten snarare än klämt in sina utspridda funktioner i klasser för att få det snyggare*.
Andra språk (java till exempel) är petigare med att allt skall vara objektorienterat.

*Nu säger jag alltså inte att man inte får göra hur man vill, men det är kanske inte praxis att göra så.

Permalänk
Skrivet av Elgot:

På många sätt ser ju c och c++ rätt lika ut och "funktioner utspridda lite överallt" är väl rätt vanligt i båda. Med hjälp av till exempel klasser kan man ju dock få det att se ut ungefär som du beskriver, men då har man nog som sagt vanligtvis utnyttjat klasser för att implementera funktionaliteten snarare än klämt in sina utspridda funktioner i klasser för att få det snyggare*.
Andra språk (java till exempel) är petigare med att allt skall vara objektorienterat.

*Nu säger jag alltså inte att man inte får göra hur man vill, men det är kanske inte praxis att göra så.

Men om du hade ett program som såg ut så här. Hur skulle du strukturera klasser?
http://pastebin.com/C22Aw0ME

Detta är hur jag struktuerar min kod. Funktionen loop() körs hela tiden. Funktionen Setup() körs bara en gång.
Globala variabeln PROGRAM talar om vilket program som ska köras.

Är detta ett bra sätt att programera eller är detta dålig programmeringsvana?

Permalänk
Hedersmedlem
Skrivet av heretic16:

Är detta ett bra sätt att programera eller är detta dålig programmeringsvana?

Det är väl inget som är speciellt dåligt med det där. Det är väl ungefär så c bukar se ut och det är ju varken fel eller ovanligt i c++ heller (även om man kanske får höra att skriver som en c-programmerare). Man skulle ju kunna tänka sig att man gör en objektorienterad lösning istället, men inget säger att det skulle vara bättre™.

Permalänk
Hedersmedlem
Skrivet av heretic16:

Om det verkligen inte är C eller C++. Då tror jag tar tillbaka allt sagt om C++ och förhåller mig vid C som vanligt.
Då får jag väll ha funktioner utspridda lite överallt och sedan anropa dessa när jag känner för det.

Samla relaterade funktioner i separata filer. Inkludera motsvarande headerfil när du vill använda dessa funktioner. Ifall du får problem med namnkollisioner (men det är rätt osannolikt om du ger saker vettiga namn) eller om du vill så kan du exempelvis jobba med biblioteksprefix som nämndes ovan. Att lägga saker i olika filer ger dock de flesta separationsfördelar man kan önska i praktiken. För ett projekt i din storlek så ska du inte behöva "gå vilse".

Vill du ha tre olika "program" så gör du väl enklast just tre separata program (separata kodfiler till separata binärer) som var och ett inkluderar gemensamma funktioner och variabler genom `#include`. Av din kod att döma så är det du kallar "program" kanske snarare "funktioner". Beroende på vad de ska göra så kanske det är logiskt att definiera dem i en och samma fil, eller i separata.

Det du kallar `void loop()` låter som något som skulle kunna vara din `main`-funktion. Inuti den bör du inte lusa in för mycket implementationsdetaljer, utan bara beskriva programmets strukturella gång, där allt "tungt" arbete sker i funktionsanrop. I din `setup`-funktion så tycker jag inte du borde börja lyssna på indata, utan den borde bara se till att initialisera displayen (och då kanske snarare heta just `initialize_display`) så att användarindata kan centraliseras i en generell indataloop i `main`.

Om användarindataloopen blir alltför invecklad så kan man lägga ut den i en egen funktion, men så som den står så ser jag inget konstigt i att låta den vara en del av `main`, så länge som inte logiken börjar breda ut sig alltför mycket. Du skriver också i en kommentar att `loop` beskriver ett "switch statement", men i praktiken har du ju skrivit en `else if`-kedja — inte så viktigt i praktiken, men det är annars en typuppgift för just en `switch`-sats där.

Av dina frågor att döma så verkar du inte ha läst referensverket The C programming language av Kernighan/Ritchie . Det kan rekommenderas att titta genom den. Den tar bland annat upp just grundläggande struktur av program i C, headerfiler och annat (kapitel 4). Den borde om inte annat gå att låna på bibliotek runt om i landet. Andra läroböcker tar säkert upp liknande saker för den delen.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Skrivet av Elgot:

Det är väl inget som är speciellt dåligt med det där. Det är väl ungefär så c bukar se ut och det är ju varken fel eller ovanligt i c++ heller (även om man kanske får höra att skriver som en c-programmerare). Man skulle ju kunna tänka sig att man gör en objektorienterad lösning istället, men inget säger att det skulle vara bättre™.

Jag vill ju få det så strukturerat så bra som möjligt för att enkelt hålla koll på koden. Det är mitt mål.
Som jag brukar kalla det som jag programmerar är flödesprogrammering. Programmet inväntar ett kommando och gör en viss operation efter ett visst kommando.

Men ibland blir det stökitgt

Permalänk
Hedersmedlem
Skrivet av heretic16:

Men om du hade ett program som såg ut så här.

En annan detalj är att String-klassen också verkar ha indexeringsstöd. Istället för

char charBuf[5]; str.toCharArray(charBuf, 5); int a = charBuf[0] - '0';

borde du kunna skriva

int a = str[0] - '0';

Permalänk
Skrivet av Elgot:

En annan detalj är att String-klassen också verkar ha indexeringsstöd. Istället för

char charBuf[5]; str.toCharArray(charBuf, 5); int a = charBuf[0] - '0';

borde du kunna skriva

int a = str[0] - '0';

Det är så att jag delar upp t.ex 1023 i delar. Men du, det verkligen fungerar!
Nu förstår jag varför stringklassen används i Arduino. Tack så mycket!

Om du är intresserad så har jag kommit så långt nu på koden
http://pastebin.com/aciHhwmQ