Bin grad dabei einen Code zu schreiben.
Wie könnte man das vereinfachen...?
if (a==0) write_0();
if (a==1) write_1();
if (a==2) write_2();
if (a==3) write_3();
if (a==4) write_4();
if (a==5) write_5();
if (a==6) write_6();
if (a==7) write_7();
if (a==8) write_8();
if (a==9) write_9();
danke für eure antworten
mach ein array, das du schon zur design-zeit mit konstanten werten
füllst (für die jeweiligen ziffern der 7seg. anzeige)
dann musst du nurnoch die entsprechende zahl auswählen aus diesem
array
pseudocode ungefähr so:
array ziffern[11000, 00101, 10111] (die versch. kodierungen der
ziffern)
darauf kannst du dann mit einem index zugreifen, z.b. willst du die
zahl "1" auf der 7seg. ausgeben, machst du:
port = ziffern[1]
ziffern[1] hätte in diesem beispiel den wert 00101, dies wär dann das
was auf dem port ausgegeben wird.
--> spart code, rechenzeit und nerven
hab mal einen bekannten gefragt der hat gemeint das geht mit einer
sprungtabelle am besten geht wenn es durchgängige werte sind.
wie heißt das im c im fachjargon? -> zu sprungtabelle hab ich im google
fast nichts gefunden.
mfg
Sprungtabellen sind arrays von Funktions-Pointern. Also z.B.
void(*)(void) sprungTabelle[10] = {
write_1,
write_2, ...
};
in main dann :
sprungTabelle[a]();
Ist aber in deinem Fall ueberfluessig, Stefans Vorschlag erscheint mir
auch am sinnvollsten.
Einfachster Code ( wie in Teilen bereits oben vorgeschlagen):
uint8_t digits =
{
0b0000000, // Eine 1 z.B. für das Segment, das leuchten soll
0b0000011,
... // usw. jeweils die bitmuster die Du brauchst
}
void write( uint8_t i )
{
PORT = digits[i]
}
Nicht ganz.
Ingo hat einen Fehler eingebaut :-)
uint8_t digits [] =
****
Und Peters Art die Konstanten zu bestimmen ist wesentlich
schöner und übersichtlicher als die Bitmuster selbst
zu bestimmen. Nach dem Motto: Lass den Compiler sich
um die Bitdetails kümmern, der Programmierer soll sich
nicht mit so einem Taschenrechnerkram rumärgern.
Sprungtabelle:
Statt der Werte die Ausgegeben werden sollen stehen in der Tabelle die
Adressen der jeweiligen Ausgabefunktion => Unnötiger Overhead im
Quadrat
==> Sprungtabelle == Mit Kanonen auf Spatzen schießen!
> ==> Sprungtabelle == Mit Kanonen auf Spatzen schießen!
Im gegenstaendlichen Fall: Ja, klar. Voellig unnoetig.
Aber um mal das Prinzip zu demonstrieren:
Ich hab vor Jahren mal eine Z80 Simulation am PC gemacht
(in C++).
Die wesentliche Hauptschleife sah so aus:
void CPU::Run()
{
BYTE OpCode;
while( 1 ) {
OpCode = m_Ram[m_PC++];
(this->*m_Fnktions[OpCode])();
}
}
Dazu gibts dann einen Haufen Funktionen, die die Funktionalitaet
einzelner OP-Codes implementieren: zb
void CPU::CALL ()
{
WORD Address = FetchAddress();
PushStack( m_PC );
m_PC = Address;
}
void CPU::RET ()
{
m_PC = PopStack();
}
...
Dazu gibt es dann ein Array von Funktionszeigern ....
class CPU
{
....
void( CPU::* m_Fnktions[256] )();
}
... welches die Verknüpfung von Op_Codes zu den einzelnen
Funktionen herstellt:
CPU::CPU()
{
...
m_Fnktions[0xC9] = RET;
...
m_Fnktions[0xCD] = CALL;
...
In der Run-Schleife wird ueber den Program-Counter m_PC der
nechste OP-Code aus dem (simulierten) RAM geholt
OpCode = m_Ram[m_PC++];
dieser OpCode als Index in die Funktionszeiger-Tabelle genommen
m_Fnktions[OpCode]
und die entsprechende Funktion aufgerufen:
(this->*m_Fnktions[OpCode])();
(stoert euch jetzt nicht an der Syntax. Die ist in C++ so
notwendig, wenn man Funktionszeiger auf Memberfunktionen machen
moechte).
War also der OpCode gleich 0xCD dann wird die Funktion CALL
dafuer aufgerufen.
Sehr elegante Lösung!
Kannst Du mir bitte erklären warum man:
(this->*m_Fnktions[OpCode])();
schreiben muss und nicht
(this->m_Fnktions[OpCode])();
Im Array steht doch ein Zeiger auf eine Memberfunktion. Eigentlich ist
dann doch
(this->m_Fnktions[OpCode])
der Zeiger auf die Funktion, und
(this->m_Fnktions[OpCode])();
Dereferenzierung und Aufruf?
Fragt sich
Ingo
(this->m_Fnktions[OpCode])();
koenntest Du benutzen, wenn in m_Fnktions lauter
Pointer auf freistehende Funktionen stünden. Das ist
aber hier nicht der Fall. m_Fnktions enthaelt Pointer
auf Memberfunktionen einer Klasse.
Memberfunktionen muessen aber anders aufgerufen werden
(der this Pointer innerhalb der Funktion muss ja besetzt
werden). Daher ist eine neue Syntax notwendig: ->*
Eine eigene Frage?
Dieser Thread ist über 20 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.