C-Programm optimieren
Hallo,
hätte da mal ne kleine Frage bzgl. C, nämlich ob man den folgenden Teil auch kürzer schreiben könnte. Bei PHP würd ich ja aus den 2 double-Werten und dem Operationssymbol einen neuen String zusammensetzen und den mit eval() ausführen. Gibt es in C vielleicht eine ähnliche, oder bessere, Methode?
Grüße,
OnkelJürgen
hätte da mal ne kleine Frage bzgl. C, nämlich ob man den folgenden Teil auch kürzer schreiben könnte. Bei PHP würd ich ja aus den 2 double-Werten und dem Operationssymbol einen neuen String zusammensetzen und den mit eval() ausführen. Gibt es in C vielleicht eine ähnliche, oder bessere, Methode?
|
|
Quellcode |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
if(strcmp(op,"+")==0) {
element->value = (b + a);
} else if(strcmp(op,"-")==0) {
element->value = (b - a);
} else if(strcmp(op,"*")==0) {
element->value = (b * a);
} else if(strcmp(op,"/")==0) {
if(a==0.0) {
printf("Fehler: Division durch 0 nicht erlaubt!\n");
element->value = b;
} else {
element->value = (b / a);
}
}
|
Grüße,
OnkelJürgen
Auf jede Frage gibt es eine Antwort, man muss nur lange genug danach suchen.
z.B. auf www.netscripter.de :-P
RE: C-Programm optimieren
Zitat
Original von OnkelJürgen
Bei PHP würd ich ja aus den 2 double-Werten und dem Operationssymbol einen neuen String zusammensetzen und den mit eval() ausführen.
Und dich ganz weit vom Optimieren entfernen. Du schaffst a) eine potentielle Sicherheitslücke, da Eingaben an eval() weitergegeben werden (hier muss also ordentlich gefiltert werden) und b) führst du zusätzliche Stringoperationen aus. Ich wette mal ganz stark, dass auch in PHP Strings konstant sind und daher beim zusammenfügen ein neuer erstellt wird. Das natürlich 2 mal...
Und wofür? Kürzester Code? Der gewinnt nicht.
Willst du Flexibilität? Arbeite mit C++, Objekten und Strategiepattern.
Willst du effizientes Laufzeitverhalten werf die strcmp raus. Die Operatoren sind doch nur ein Zeichen lang, da kannst du die erste Stelle des char-Arrays direkt vergleichen; Chars sind ind C doch auch nur Zahlen...
@narfnarf
Das mit PHP war ja nur ein Beispiel, dass ich das rundherum noch absichern müsste ist klar, aber da hätte ich ja auch nicht derartige Eingaben.
C++ darf ich in dem Fall nicht verwenden, es wird ausdrücklich C vorausgesetzt.
@silence
Ist kein Char, sondern ein String, weil u.a. auch längere Zeichenketten verarbeitet werden, da hatte ich auch Probleme das derart zu vergleichen, deswegen strcmp ... aber so genau kenn' ich mich in C natürlich auch noch nicht aus.
Trotzdem danke euch beiden.
Das mit PHP war ja nur ein Beispiel, dass ich das rundherum noch absichern müsste ist klar, aber da hätte ich ja auch nicht derartige Eingaben.

C++ darf ich in dem Fall nicht verwenden, es wird ausdrücklich C vorausgesetzt.

@silence
Ist kein Char, sondern ein String, weil u.a. auch längere Zeichenketten verarbeitet werden, da hatte ich auch Probleme das derart zu vergleichen, deswegen strcmp ... aber so genau kenn' ich mich in C natürlich auch noch nicht aus.
Trotzdem danke euch beiden.
Auf jede Frage gibt es eine Antwort, man muss nur lange genug danach suchen.
z.B. auf www.netscripter.de :-P
Es gibt in C keine Strings. "Strings" sind doch nur Arrays mit Chars drin (und hoffentlich null terminiert...). Da nimmst du einfach die erste Stelle.
Mir ist schon klar, dass PHP nur ein Beispiel war. Nur stellte sich mir die Frage, was du mit einer solchen Vorgehensweise erreichen willst. IMHO stellt das keine Verbesserung dar.
Zu Strings, Chars und dergleichen Teufelszeug:
String stellt man in C ja wie folgt dar:
Möchtest du prüfen, ob und welche Rechenoperation gewünscht ist reicht ein Vergleich folgender Art:
Davon mal abgesehen ist es relativ kritisch, Gleitkommazahlen auf Gleichheit mit 0.0 zu prüfen. Nach wenigen Rechenoperationen nehmen die diesen Wert aufgrund von möglichen Rundungsfehlern nämlich oftmals nie wieder an.
Bsp:
a sei eine Gleitkommazahl im Bereich von 1-10,
q=563957593012421346345;
a/q = b;
b*q = c;
Jetzt sollte theoretisch c == a gelten (bzw. (a - c) == 0). Je nach dem konkreten Wert von q und vor allem dem Verhältnis von a und q ist das aber nicht der Fall. Da bleibt dann oft ein klitzekleiner Rest, der ein == 0.0 an die Wand fahren lässt.
Eigentlich macht das kein Problem, weil ja auch de facto nicht durch 0.0 geteilt wird. Da könnten aber schon unerwartete Ergebnisse auftreten.
Im obigen Beispiel würde ein Benutzer erwarten, das q/(a-c) verboten sei und nicht aufgrund von technischen Eigenheiten doch funktioniert.
Nach den
Mir ist schon klar, dass PHP nur ein Beispiel war. Nur stellte sich mir die Frage, was du mit einer solchen Vorgehensweise erreichen willst. IMHO stellt das keine Verbesserung dar.
Zu Strings, Chars und dergleichen Teufelszeug:
String stellt man in C ja wie folgt dar:
|
|
Quellcode |
1 2 |
char name1[16] = "Frans Coenen";
char name2[16] = {'F','r','a','n','s',' ','C','o','e','n','e','n','\0'};
|
Möchtest du prüfen, ob und welche Rechenoperation gewünscht ist reicht ein Vergleich folgender Art:
|
|
Quellcode |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
if(op[0] == "+")
{
element->value = (b + a);
}
else if(op[0] == "-")
{
element->value = (b - a);
}
else if(op[0] == "*")
{
element->value = (b * a);
}
else if(op[0] == "/")
{
if(a==0.0) {
printf("Fehler: Division durch 0 nicht erlaubt!\n");
element->value = b;
}
else
{
element->value = (b / a);
}
}
|
Davon mal abgesehen ist es relativ kritisch, Gleitkommazahlen auf Gleichheit mit 0.0 zu prüfen. Nach wenigen Rechenoperationen nehmen die diesen Wert aufgrund von möglichen Rundungsfehlern nämlich oftmals nie wieder an.
Bsp:
a sei eine Gleitkommazahl im Bereich von 1-10,
q=563957593012421346345;
a/q = b;
b*q = c;
Jetzt sollte theoretisch c == a gelten (bzw. (a - c) == 0). Je nach dem konkreten Wert von q und vor allem dem Verhältnis von a und q ist das aber nicht der Fall. Da bleibt dann oft ein klitzekleiner Rest, der ein == 0.0 an die Wand fahren lässt.
Eigentlich macht das kein Problem, weil ja auch de facto nicht durch 0.0 geteilt wird. Da könnten aber schon unerwartete Ergebnisse auftreten.
Im obigen Beispiel würde ein Benutzer erwarten, das q/(a-c) verboten sei und nicht aufgrund von technischen Eigenheiten doch funktioniert.
Nach den
Hi zusammen,
kann man dan nichtr auch mit ner case-Anweisung realisieren?
So ähnlich würd ichs in java realisieen (ja ich bring C und Java gerade n bissel durcheinander aber vllt hilfts ja weiter...)
Gruß,
proNFP
kann man dan nichtr auch mit ner case-Anweisung realisieren?
|
|
Quellcode |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
char op = '*';
switch op[0] {
case '+':
element->value = (b + a);
break;
case '-':
element->value = (b - a);
break;
case '*':
element->value = (b * a);
break;
case '/':
if(a==0.0) {
printf("Fehler: Division durch 0 nicht erlaubt!\n");
element->value = b;
}
else
{
element->value = (b / a);
}
break;
default:
printf("Fehler: Falsche Angabe!\n");
}
|
So ähnlich würd ichs in java realisieen (ja ich bring C und Java gerade n bissel durcheinander aber vllt hilfts ja weiter...)
Gruß,
proNFP
Stimmt, auf [0] bin ich bei so ner Überprüfung gar nicht gekommen. Bei längeren Ausdrücken wie inv, neg usw. dann aber auch schon wieder unpraktischer ... am liebsten wäre mir eben eine Möglichkeit gewesen das Symbol direkt einzusetzen, statt mehrer einzelner Bedingungen, aber ich seh langsam ein, dass das Vorhaben wohl eher unpraktikabel ist.
Letztendlich ist das ganze sowieso nur für mich persönlich, die eigentliche Aufgabe sollte bei weitem erfüllt sein. Die Tatsache mit den Dualzahlen und deren Speicherung als Vorzeichen, Charakteristik und Mantisse ist mir durchaus auch bewusst.
Strings als Array, okay, müsste ich wissen. *g*
Danke trotzdem nochmal vielmals.
Letztendlich ist das ganze sowieso nur für mich persönlich, die eigentliche Aufgabe sollte bei weitem erfüllt sein. Die Tatsache mit den Dualzahlen und deren Speicherung als Vorzeichen, Charakteristik und Mantisse ist mir durchaus auch bewusst.

Strings als Array, okay, müsste ich wissen. *g*
Danke trotzdem nochmal vielmals.
Auf jede Frage gibt es eine Antwort, man muss nur lange genug danach suchen.
z.B. auf www.netscripter.de :-P
Nein.Im grunde ist jeder Pointer ein array.
Aktuell nutze ich: Windows, Linux, MacOS X, Solaris...weil die Welt nicht nur S/W ist!
Blog
Blog
Stimmt in C ebenfalls nicht - ein Zeiger ist lediglich ein maschinenabhängiger, ganzzahliger Wert - bei 32Bit wäre er 4Byte lang, bei 64Bit 8Byte. Dieser verweist auf eine Speicheraddresse, unter der dann der Inhalt abgelegt ister meinte es wahrscheinlich anders herum ...
was gegen einzuwenden, wenn man einen Array als eine Art Liste von Zeigern, Referenzen bezeichnen würde?
edit: -mal abgesehen von Sammlungen primitiver Datentypen-
Ein Array ist eine Sammlung von Elementen, deren Typ ist aber beliebig und besteht keineswegs nur aus Referenzen, Zeigern und primitiven Datentypen.
In Java stimmt die Aussage jedoch.
Aktuell nutze ich: Windows, Linux, MacOS X, Solaris...weil die Welt nicht nur S/W ist!
Blog
Blog
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »silence« (15. April 2008, 18:50)


