Hallo,
ich habe eine funktion in c, der ich eine variable übergeben muss.
Die Variable bekomme ich von einer anderen Funktion (z.B.int32 48000)
Die Frequenz muss ich nun einer set_audioformat übergeben.
Diese möchte aber werte von Enums haben
1
voidset_audioformat(enumaudio_frequencyfrequency,
2
enumaudio_channelschannels,
3
enumaudio_samplesizesamplesize,
4
enumaudio_ampletypesampletype);
ein enum sieht z.B. wie folgt aus
1
enumaudio_frequency{
2
frequency_unknown=0,
3
frequency_8000=1,
4
frequency_11025=2,
5
frequency_12000=3,
6
frequency_16000=4,
7
frequency_22050=5,
8
frequency_24000=6,
9
frequency_32000=7,
10
frequency_44100=8,
11
frequency_48000=9,
12
frequency_96000=10,
13
frequency_192000=11
14
};
Der wert der Frequenz von audio_frequenzy wird dann in einem 4-Bit-Feld
in einem Header eingetragen.Wenn ich jetzt für die Frequenz einfach den
Wert 48000 übergebe, wird das natürlich nicht hinhauen. Wie bekomme ich
am besten den namen vom enum audio_frequenzy heraus um diesen zu
übergeben?
Theor schrieb:> Mit einer Kette von if-else-Anweisungen oder einer> switch-case-Anweisung.
Mhh, deswegen habe ich gefragt, in der Hoffnung das es jemand eine
schönere lösung gibt. Das wird jetzt viel umstrickerei.
Theor schrieb:> Du kannst nicht zur Laufzeit den Namen eines enum-Wertes zusammensetzen.
Das habe ich mir fast gedacht.
Aber ich danke euch trotzdem
Johannes schrieb:> Theor schrieb:>> Mit einer Kette von if-else-Anweisungen oder einer>> switch-case-Anweisung.>> Mhh, deswegen habe ich gefragt, in der Hoffnung das es jemand eine> schönere lösung gibt. Das wird jetzt viel umstrickerei.
Wieso?
Das ist ne Sache von drei Minuten. Einschliesslich Kaffee holen.
Theor schrieb:> Das ist ne Sache von drei Minuten
Das ist auch nicht das Problem. Das Problem ist einfach nur, dass jetzt
größere Blöcke reinkommen, wo ich mir den Wert hole.
Habe ich auch schon gleich alles drinn
Johannes schrieb:> Theor schrieb:>> Das ist ne Sache von drei Minuten>> Das ist auch nicht das Problem. Das Problem ist einfach nur, dass jetzt> größere Blöcke reinkommen, wo ich mir den Wert hole.
Höchsten einen "Block". Du schreibst einfach eine Funktion.
In moderneren Sprachen könnte man ein assoziatives Array/Hash machen,
der Key wäre der Integerwert, der Value dann der Enum.
In plain C gehts aber auch mit etwas Handarbeit. Ein Array bestehend aus
einem Elementtyp mit Integer und dazuhörigem Enum und dann eine
for-schleife, die den Int sucht und das Enum zurückgibt. Ist etwas
schöner als die if/switch-Spaghettis.
Georg A. schrieb:> Ein Array bestehend aus> einem Elementtyp mit Integer und dazuhörigem Enum und dann eine> for-schleife, die den Int sucht und das Enum zurückgibt. Ist etwas> schöner als die if/switch-Spaghettis.
Das ist keineswegs schöner, da der Rechenaufwand für solch eine Schleife
mit O(n) mit n: Anzahl der Tabelleneinträge skaliert. Der Compiler hat
hingegen keine Möglichkeit, die Schleife so zu optimieren, dass sie
weniger stark skaliert.
Aus einer switch/case-Konstruktion erzeugen moderne Compiler jedoch
häufig einen binären Suchbaum, der mit O(log(n)) skaliert. Außerdem ist
der gesamte Vorgang bereits zur Kompilierzeit vollständig bestimmt,
wohingegen die Schleife dynamische Elemente besitzt.
Theor schrieb:> Der von Dir angedeutete Weg funktioniert nicht.>> Du kannst nicht zur Laufzeit den Namen eines enum-Wertes zusammensetzen.
Ja. Der Name existiert nur im Compiler. Zur Laufzeit, zu der man den
Wert hat, gibt's den Namen gar nicht mehr.
Georg A. schrieb:> In plain C gehts aber auch mit etwas Handarbeit. Ein Array bestehend aus> einem Elementtyp mit Integer und dazuhörigem Enum und dann eine> for-schleife, die den Int sucht und das Enum zurückgibt. Ist etwas> schöner als die if/switch-Spaghettis.
Was soll daran schöner sein als an einem simplen:
Rolf M. schrieb:> Was soll daran schöner sein als an einem simplen:
Das könnte man sich schenken, wenn die enum-Werte den tatsächlichen
entsprechen, wie ich weiter oben vorgeschlagen habe.
Man muss nur den Sonderfall erfassen, daß eine unbekannte Frequenz
vorliegt.
Die Frage ist, ob das eine Operation ist, die zur Laufzeit des
Programmes häufiger auftritt, oder ob sowieso nur mit bekannten, d.h.
wohldefinierten Frequenzen gearbeitet wird.
Dann wäre der einzige Grund, andere enum-Konstanten zu verwenden, der
reduzierte Werteumfang und damit Speicherplatzbedarf.
Ich habe aber nicht den Eindruck, daß diese Audioanwendung hier auf
einem 8-Bit- oder 16-Bit-µC laufen soll.
Theor schrieb:> Der von Dir angedeutete Weg funktioniert nicht.>> Du kannst nicht zur Laufzeit den Namen eines enum-Wertes zusammensetzen.
Da muss ich mich dann doch, wenigstens teilweise korrigieren.
Man kann zur Kompilierungszeit mit Präprozessor-Kommandos erreichen,
dass die Identifizierer von Aufzahlungskonstanten konstruiert , und
auch passende Funktionen erzeugt werden, welche die Identifizierer einem
numerischen Wert oder umgekehrt zuordnen können.
Ich habe das zwar für möglich gehalten, hielt es aber für recht
aufwendig, dem TO das im Einzelnen zu erklären.
Dieser Thread Beitrag "Re: Enum Export für Docu" hat
aber meine Aufmerksamkeit erregt und siehe da, in Dr. Sommers Antwort
steckt eine Link zu stackoverflow
https://stackoverflow.com/questions/28828957 zu dem Thema in dem eine
Zusammenstellung von Methoden mit Präprozessorkommandos enthalten ist.
Insbesondere
https://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c
scheint mir relativ gut zu der Frage hier zu passen, wenn man den Code
auch noch verändern muss um genau das Ziel der Frage zu erreichen.
Ob das dem TO nun direkt hilft, weiß ich nicht. Es ist doch recht
komplex und ich scheue mich selbst auch eher davor, solche
Konstruktionen zu verwenden.
Aber es geht und deswegen füge ich das hier dem Thread hinzu.
Andreas S. schrieb:> Das ist keineswegs schöner, da der Rechenaufwand für solch eine Schleife> mit O(n) mit n: Anzahl der Tabelleneinträge skaliert. Der Compiler hat> hingegen keine Möglichkeit, die Schleife so zu optimieren, dass sie> weniger stark skaliert.
Mei, immer diese Theoretiker ;) Für den konkreten Fall wird das mit
einer überschaubaren Zahl von Einträgen vermutlich einmal alle heiligen
Zeiten ausgeführt.
Die Schreibweise in Tabellenform ohne viel Extraschlüsselwörter finde
ich jedenfalls schöner und vor allem recht universell anwendbar.
Rufus Τ. F. schrieb:> Rolf M. schrieb:>> Was soll daran schöner sein als an einem simplen:>> Das könnte man sich schenken, wenn die enum-Werte den tatsächlichen> entsprechen, wie ich weiter oben vorgeschlagen habe.
Klar. Ich hatte das so verstanden, dass der enum vorgegeben ist und
nicht umdefiniert werden kann.
Johannes schrieb:> Die Variable bekomme ich von einer anderen Funktion (z.B.int32 48000)
Warum arbeitet diese Funktion mit konkreten Zahlenwerten statt mit den
vorgegebenen enums?
Du solltest besser die Ursache für das Problem beheben und nicht ein
Pflaster draufkleben mit einer Mapping-Funktion.