Aufzählungstypen in C < C/C++ < Programmiersprachen < Praxis < Informatik < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 13:18 So 20.03.2011 | Autor: | bandchef |
Aufgabe | Ich soll mit "enum" einen Aufzählungstypen "LogicLevel" deklarieren. Die Werte welcher dieser Aufzählungstyp enthalten soll sind folgende:
1, 0, X, H, L, Z
Danach soll ich eine Funktion programmieren die mir die Verschaltung von zwei solchen Werten berechnet. |
Ich hab dann mit der Programmierung schon mal angefangen. Das sieht nun so aus:
#include<iostream>
using namespace std;
enum LogicLevel {I=0, O, X, H, L, Z};
LogicLevel resolve(LogicLevel p1, LogicLevel p2)
{
}
int main()
{
int x = 0, y = 0;
LogicLevel resolve(LogicLevel x, LogicLevel y);
return 0;
}
Als erstes Problem hab ich hier schon mal, dass mir "enum" keine Zahlen nimmt. Deswegen hab ich die 1 mit einem "I" und die 0 mit einem "O" ersetzt. Kann man das so machen?
Könnt ihr mir helfen?
|
|
|
|
Hallo!
I=0 funktioniert natürlich nicht.
Ansonsten ist es eine gute Idee, 1 durch I und 0 durch O zu ersetzen.
Du willst die aufzählungstypen später ja wie gewöhnliche Variablen verwenden (obwohl dahinter intern eine feste Zahl steht, enums dienen in erster Linie dazu, das Programm übersichtlicher zu machen). Und dann ist es schlecht, wenn man Zahlen als enum-item benutzt, daher geht das nicht.
Jetzt noch 2 Dinge:
int x = 0, y = 0;
Wird (noch) nicht benutzt.
LogicLevel resolve(LogicLevel x, LogicLevel y);
nein, resolve() gibt ein LogicLevel zurück, das macht so keinen Sinn. Eher
LogicLevel result = resolve(LogicLevel x, LogicLevel y);
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 13:53 So 20.03.2011 | Autor: | bandchef |
Ich hab meinen Code jetzt mal verändert:
#include<iostream>
using namespace std;
enum LogicLevel {logic1, logic0, logicX, logicH, logicL, logicZ}; //globale Aufzählung
LogicLevel resolve(LogicLevel p1, LogicLevel p2)
{
}
int main()
{
LogicLevel result;
cout << result = resolve();
return 0;
}
Ich weiß jetzt nicht was ich beim Funktionsaufruf als Argumente reinschreiben muss. Alles was ich bisher ausprobiert habe geht schief...Was muss ich reinschreiben?
|
|
|
|
|
Hallo!
naja, wenn die Funktion ein INT als Parameter hätte, würdest du eine Zahl, also ein Element aus der menge aller INTs angeben. Genauso mußt du jetzt ein Element aus den enums angeben, also z.B.
resolve(logicX,logicH);
und
cout << result=resolve();
ist auch nicht so gut. entweder
cout << resolve();
oder
LogicLevel result=resolve();
cout << result;
bei dem cout gibt es ein weiteres problem: Wie oben bereits gesagt, der Computer selbst nummeriert die Elemente von deinem enum-typen einfach durch, und rechnet mit den Zahlen. Er weiß später nicht mehr, daß du die Elemente logicX etc. genannt hast. (Er weiß ja auch nix mehr von den Variablennamen, aber das hier geht ja noch nen Schritt weiter, weil du den Elementen Namen gibst.) Das cout wird zwar funktionieren, aber es wird dir vermutlich die Zahlen 1-5 ausgeben. Also, nicht wundern.
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 14:37 So 20.03.2011 | Autor: | bandchef |
Hm, das leuchtet ein. Ich hab jetzt die Aufzählung doch nochmal verändert. Gefällt mir so besser und dagegen sollte doch eigetnlich nichts einzuwenden sein, oder?
#include<iostream>
using namespace std;
enum LogicLevel {I, O, X, H, L, Z}; //globale Aufzählung
LogicLevel resolve(LogicLevel p1, LogicLevel p2)
{
LogicLevel result = I;
switch(p1) //Zeilen
{
case 0:
switch(p2)
{
case 0: result = I; break;
case 1: result = X; break;
case 2: result = X; break;
case 3: result = I; break;
case 4: result = I; break;
case 5: result = I; break;
}
break;
case 1:
switch(p2)
{
case 0: result = X; break;
case 1: result = O; break;
case 2: result = X; break;
case 3: result = O; break;
case 4: result = O; break;
case 5: result = O; break;
}
break;
case 2:
switch(p2)
{
case 0: result = X; break;
case 1: result = X; break;
case 2: result = X; break;
case 3: result = X; break;
case 4: result = X; break;
case 5: result = X; break;
}
break;
case 3:
switch(p2)
{
case 0: result = I; break;
case 1: result = O; break;
case 2: result = X; break;
case 3: result = H; break;
case 4: result = X; break;
case 5: result = H; break;
}
break;
case 4:
switch(p2)
{
case 0: result = I; break;
case 1: result = O; break;
case 2: result = X; break;
case 3: result = X; break;
case 4: result = L; break;
case 5: result = L; break;
}
break;
case 5:
switch(p2)
{
case 0: result = I; break;
case 1: result = O; break;
case 2: result = X; break;
case 3: result = H; break;
case 4: result = L; break;
case 5: result = Z; break;
}
break;
}
return result;
}
int main()
{
LogicLevel result = resolve(Z, H);
cout << "result: " << result;
return 0;
}
Als weitere Aufgabe ist jetzt folgendes: Ich soll jetzt mittels switch in der Funktion auswerten und berechnen.
D.h., wenn der Funktion z.B. als erster Wert Z und als zweiter Wert das H übergeben wird, soll als Ergebnis ein H zurückgeliefert werden. Welche zurückgeliefert werden sollen sieht man anhand dieser Tabelle: Tabelle
Hier gibt es aber dann doch eine ziemlich große Fülle an verschiedenen Möglichkeiten. Wie löst man das mit dem switch? Ich hab zwar jetzt mal ein switch eingebaut, aber ich kann im switch nicht mit den "LogicLevel" Bezeichnungen arbeiten, sondern muss die int-Zahlen angeben, die hinter der enum stecken. Auch in der mein nach cout bekomm ich nicht den Typ, sondern nur den Zahlenwert hinter dem Typ.
Geht das nicht anders, oder mach ich da einfach was falsch?
PS: Der erste Wert im Funktionsaufruf soll quasi mit den Zeilen und der zweite Wert soll mit den Spalten korrespondieren.
|
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 15:49 So 20.03.2011 | Autor: | felixf |
Eingabefehler: "{" und "}" müssen immer paarweise auftreten, es wurde aber ein Teil ohne Entsprechung gefunden (siehe rote Markierung)
Eingabefehler: "{" und "}" müssen immer paarweise auftreten, es wurde aber ein Teil ohne Entsprechung gefunden (siehe rote Markierung)
Eingabefehler: "{" und "}" müssen immer paarweise auftreten, es wurde aber ein Teil ohne Entsprechung gefunden (siehe rote Markierung)
Moin
> Hm, das leuchtet ein. Ich hab jetzt die Aufzählung doch
> nochmal verändert. Gefällt mir so besser und dagegen
> sollte doch eigetnlich nichts einzuwenden sein, oder?
Doch: wenn du es so machst, warum verwendest du ueberhaupt enum?!
> LogicLevel resolve(LogicLevel p1, LogicLevel p2)
> {
> LogicLevel result = I;
>
> switch(p1) //Zeilen
> {
> case 0:
> switch(p2)
> {
> case 0: result = I; break;
> case 1: result = X; break;
Wieso schreibst du hier nicht
...
case I:
...
case I: ...
case O: ...
...
Du hast doch extra die enums definiert, damit du eben nicht mit (verwirrenden) Zahlen arbeiten musst!
> Als weitere Aufgabe ist jetzt folgendes: Ich soll jetzt
> mittels switch in der Funktion auswerten und berechnen.
Der Satz ergibt auf Deutsch so ueberhaupt keinen Sinn.
> D.h., wenn der Funktion z.B. als erster Wert logicX und als
> zweiter Wert das logicH übergeben wird soll als Ergebnis
> ein logicX zurückgeliefert werden. Was zurückgeliefert
Was ist LogicX und was ist LogicH?
> werden soll sieht man anhand dieser Tabelle:
> Tabelle
>
> Hier gibt es aber dann doch eine ziemlich große Fülle
> anverschiedenen Möglichkeiten. Wie löst man das mit dem
> switch?
Na, genauso wie oben. Verschachtelte Switches.
Du kannst auch etwas die Faelle reduzieren, indem du erst per if ueberpruefst, ob der eine oder andere Parameter gleich X ist: dann ist das Ergebnis immer X.
> Ich hab zwar jetzt mal ein switch eingebaut, aber
> ich kann im switch nicht mit den "LogicLevel" Bezeichnungen
> arbeiten, sondern muss die int-Zahlen angeben, die hinter
> der enum stecken. Geht das nicht anders, oder mach ich da
> einfach was falsch?
Nein, du sollst schon die LogicLevel-Bezeichnungen verwenden! Die int-Zahlen da zu verwenden ist keine gute Idee.
LG Felix
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 15:56 So 20.03.2011 | Autor: | bandchef |
So, hab das jetzt nochmal angepasst. Das sieht jetzt so aus:
#include<iostream>
using namespace std;
//das in der Aufzählungstypen verwendete 'I' ind 'O' (Buchstaben!) entspricht in der Übung einer '1' und '0' (Zahlen)
enum LogicLevel {I, O, X, H, L, Z}; //globale Aufzählung mit der int-Zuweisung: I=0, O=1, X=2, H=3, L=4, Z=5
LogicLevel resolve(LogicLevel p1, LogicLevel p2) //p1 = Zeilen, p2 = Spalten der Tabelle auf dem Übungsblatt
{
LogicLevel result = I;
switch(p1)
{
case I:
switch(p2)
{
case I: result = I; break;
case O: result = X; break;
case X: result = X; break;
case H: result = I; break;
case L: result = I; break;
case Z: result = I; break;
}
break;
case O:
switch(p2)
{
case I: result = X; break;
case O: result = O; break;
case X: result = X; break;
case H: result = O; break;
case L: result = O; break;
case Z: result = O; break;
}
break;
case X:
switch(p2)
{
case I: result = X; break;
case O: result = X; break;
case X: result = X; break;
case H: result = X; break;
case L: result = X; break;
case Z: result = X; break;
}
break;
case H:
switch(p2)
{
case I: result = I; break;
case O: result = O; break;
case X: result = X; break;
case H: result = H; break;
case L: result = X; break;
case Z: result = H; break;
}
break;
case L:
switch(p2)
{
case I: result = I; break;
case O: result = O; break;
case X: result = X; break;
case H: result = X; break;
case L: result = L; break;
case Z: result = L; break;
}
break;
case Z:
switch(p2)
{
case I: result = I; break;
case O: result = O; break;
case X: result = X; break;
case H: result = H; break;
case L: result = L; break;
case Z: result = Z; break;
}
break;
}
return result;
}
int main()
{
LogicLevel result = resolve(Z, H);
cout << "result: " << result;
return 0;
}
Das einzige was jetzt so noch nicht funktioniert ist, dass ich in der main noch immer eine Zahl und nicht den enum Typ zurückbekomme... Muss ich da jetzt wieder mit einem switch bzw. mit einer if-Kaskade arbeiten und mir so den passenden Typ raussuchen lassen?
|
|
|
|
|
Hallo!
Leider ja. enums sind wirklich nur zum internen Gebrauch da, und eignen sich nicht sonderlich für die Ausgabe.
Ein Anwendungsfall, den ich kenne, ist ein enum, das verschiedene Farben darstellt.
Angenommen, du hast die Funktion
SetLineColor(color)
dann kann man für color einfach Zahlen einsetzen, weiß aber nicht, was man bekommt. Schöner ist es da, wenn man
SetLineColor(red)
SetLineColor(green)
SetLineColor(blue)
schreiben kann, das ist für den Programmierer verständlicher.
Zu deinem Code: Prinzipiell ist das OK, du hast aber sehr viel Schreibarbeit da drin.
beispiel:
1: | switch(p2)
| 2: | {
| 3: | case I: result = I; break;
| 4: | case O: result = X; break;
| 5: | case X: result = X; break;
| 6: | case H: result = I; break;
| 7: | case L: result = I; break;
| 8: | case Z: result = I; break;
| 9: | }
|
geht auch so:
1: | switch(p2){
| 2: | case O:
| 3: | case X:
| 4: | result = X; break;
| 5: | default:
| 6: | result = I;
| 7: | }
|
Und
1: |
| 2: | switch(p2)
| 3: | {
| 4: | case I: result = I; break;
| 5: | case O: result = O; break;
| 6: | case X: result = X; break;
| 7: | case H: result = H; break;
| 8: | case L: result = L; break;
| 9: | case Z: result = Z; break;
| 10: | } |
kannst zu zusammenkürzen zu
result=p2
|
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 19:36 So 20.03.2011 | Autor: | felixf |
Moin,
> Das einzige was jetzt so noch nicht funktioniert ist, dass
> ich in der main noch immer eine Zahl und nicht den enum Typ
> zurückbekomme... Muss ich da jetzt wieder mit einem switch
> bzw. mit einer if-Kaskade arbeiten und mir so den passenden
> Typ raussuchen lassen?
Ja, musst du.
Alternativ kannst du eine Funktion schreiben, die aus einem solchen enum-Typ einen String macht (etwa per if- oder switch-Statement). Oder du kannst (schliesslich benutzt du ja C++ und nicht C) den Ausgabeoperator fuer deinen enum ueberladen. Aber das solltest du dir erst anschauen, wenn du den Rest der Sprache besser beherrscht.
LG Felix
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 20:12 So 20.03.2011 | Autor: | bandchef |
Ich hab jetzt hier mal eine weitere Funktion gebastelt, die mir durch eine if-Kaskade den passenden char in eine Rückgabe-Variable speichert. Könnt ihr mal gucken, ob das soweit passt, oder ob ich "...und mir so den passenden Typ raussuchen lassen?" falsch verstanden habe, obwohl ich es selbst geschrieben habe?
char int2LogicLevel(LogicLevel chart_result)
{
char int2LogicLevel_chart_result = 0;
if(chart_result == I)
{
int2LogicLevel_chart_result = '1';
}
if(chart_result == O)
{
int2LogicLevel_chart_result = '0';
}
if(chart_result == X)
{
int2LogicLevel_chart_result = 'X';
}
if(chart_result == H)
{
int2LogicLevel_chart_result = 'H';
}
if(chart_result == L)
{
int2LogicLevel_chart_result = 'L';
}
if(chart_result == Z)
{
int2LogicLevel_chart_result = 'Z';
}
return int2LogicLevel_chart_result;
}
PS: Die Variable "result" für das Ergebnis des switch-Statements nach der Auswertung der Tabelle hab ich wegen gegebenem Anlass in "chart_result" umbennen müssen.
Grüße
|
|
|
|
|
Hallo!
Ja, das sieht gut so aus.
Um sich die Schreibarbeit zu sparen, könnte man auch schreiben
char Zeichen[]="10XHLZ";
cout << Zeichen[myLogicLevel]<<endl;
Das ist aber wohl nicht Sinn deiner Aufgabe, denn hier wird wieder ausgenutzt, daß hinter dem enum doch nur Zahlen stecken, und es wird das entsprechende zeichen aus dem String geholt...
|
|
|
|