Was ist besser: "if/else" oder "? :" ?



  • Hallo Leute,

    angenommen ich möchte eine Abfrage schreiben, welche einen bool nimmt, und diesen wenn er true ist auf false setzt, und umgekehrt.
    Ich habe nun zwei simple Lösungen mit denen ich das erreichen kann. Die erste, relativ einfache Methode wäre eine if/else Abfrage:

    if(condition) {
    condition = false;
    } else {
    condition = true;
    }
    

    Ich könnte aber auch die kürzere und überschaubarere Variante mit

    ? :
    

    verwenden. Das sähe dann so aus:

    condition = (condition) ? false : true;
    

    Beide Methoden erreichen das gewünschte Ziel, aber welche Methode ist schneller, bzw. effizienter.

    Ich würde mich über Antworten freuen 🙂



  • condition = !condition
    


  • SG1 schrieb:

    condition = !condition
    

    Okay, schlechtes Beispiel meinerseits. Mal angenommen wir haben jetzt keinen Bool, sondern einen Integer. Ich habe mal beispiel haft eine Situation geschrieben wo das passieren könnte. Die praktische Anwendungsmöglichkeit ist hierbei zu vernachlässigen:

    #include <iostream>
    
    int positive(int i)
    {
    	return i + abs(3*i);
    }
    
    int negative(int i)
    {
    	return i - 2 * i;
    }
    
    int main()
    {
    	int i = 2;
    
    	while (1)
    	{
    		i = (i > 0) ? negative(i) : positive(i);
    		std::cout << i << std::endl;
    	}
    
    	return 0;
    }
    

    Statt dem im Beispiel verwendeten "? :" könnte ich auch ein if/else statement verwenden. Aber jetzt wieder die Frage: was ist schneller bzw. effizienter?



  • D4RKS0UL23 schrieb:

    Aber jetzt wieder die Frage: was ist schneller bzw. effizienter?

    Sollte in deinem Beispiel exakt gleich schnell sein, weil vermutlich sogar meistens exakt der selbe Code generiert werden wird. Bzw. wenn nicht (theoretisch ist es halt doch möglich dass der Compiler unterschiedlichen Code generiert), dann kann man unmöglich voraussagen was schneller sein wird.



  • Ich würde bei solchen Situationen das ? : bevorzugen.
    Warum? Es hat eine Redundanz weniger. Du schreibst das condition = bloß einmal hin, statt einmal im if und einmal im else .

    Außerdem ist diese Funktionalität ohnehin ganz gut z.B. bei Funktionsaufrufen:

    DoSomething(a == b ? 3 : 5, a < 0 ? -1 : 1);
    

    Also sollte man das auch ausgiebig nutzen.

    Zumindest, solange es sich tatsächlich um Auswertungen von Ausdrücken handelt.
    Von PHP-Entwicklern hab ich nämlich schon oft gesehen, dass das mal eben als simple Kurzschreibweise für if und else missbraucht wird, ohne den Ausdruck auszuwerten oder Redundanzen zu vermeiden:

    if (a)
        DoThis();
    else
        DoThat();
    

    wird dann zu

    a ? DoThis() : DoThat();
    

    Das ist natürlich Bullshit, weil es dem Zweck dieses Operators widerspricht (je nach Bedingung einen anderen Wert zurückgeben) und ohnehin nur geht, wenn die Funktionen zufällig auch was zurückgeben (was dann auch noch typmäßig miteinander kompatibel sein muss, aber das schert so einen PHP-Entwickler ja nicht, da es dort ohnehin keine expliziten Datentypen gibt).



  • Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum MFC (Visual C++) in das Forum C++ (alle ISO-Standards) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    C-er schrieb:

    DoSomething(a == b ? 3 : 5, a < 0 ? -1 : 1);
    

    Ich würde ein ernstes Wort mit dem Mitarbeiter wechseln, der sowas einfach stehen lässt.


  • Mod

    Arcoth schrieb:

    C-er schrieb:

    DoSomething(a == b ? 3 : 5, a < 0 ? -1 : 1);
    

    Ich würde ein ernstes Wort mit dem Mitarbeiter wechseln, der sowas einfach stehen lässt.

    Und was genau würdest du sagen?



  • camper schrieb:

    Arcoth schrieb:

    C-er schrieb:

    DoSomething(a == b ? 3 : 5, a < 0 ? -1 : 1);
    

    Ich würde ein ernstes Wort mit dem Mitarbeiter wechseln, der sowas einfach stehen lässt.

    Und was genau würdest du sagen?

    "Das hast Du Knallcharge doch eins-zu-eins aus dem Internet kopiert!"


  • Mod

    camper schrieb:

    Arcoth schrieb:

    C-er schrieb:

    DoSomething(a == b ? 3 : 5, a < 0 ? -1 : 1);
    

    Ich würde ein ernstes Wort mit dem Mitarbeiter wechseln, der sowas einfach stehen lässt.

    Und was genau würdest du sagen?

    Die Argumente könnte man mindestens in ordentlich benannte Variablen auslagern. Und das zweite sieht mir schon fast nach signum aus. Ich habe auf jeden Fall keine Lust so einen Rotz zu parsen.



  • Antwort A schrieb:

    "Das hast Du Knallcharge doch eins-zu-eins aus dem Internet kopiert!"

    Also, ich hab's mir zumindest spontan selbst ausgedacht und nicht aus dem Internet kopiert.

    Arcoth schrieb:

    Die Argumente könnte man mindestens in ordentlich benannte Variablen auslagern.

    Dann pack's eben in Variablen. War auch nur ein Beispiel.

    Mein Argument (benutze den ?:-Operator, wenn's geht) bleibt ja bestehen:

    Das hier:

    int temp1 = (a == b ? 3 : 5);
    int temp2 = (a < 0 ? -1 : 1);
    
    DoSomething(temp1, temp2);
    

    ist besser als das hier:

    int temp1;
    int temp2;
    
    if (a == b)
        temp1 = 3;
    else
        temp1 = 5;
    
    if (a < 0)
        temp2 = -1;
    else
        temp2 = 1;
    
    DoSomething(temp1, temp2);
    


  • C-er schrieb:

    Mein Argument (benutze den ?:-Operator, wenn's geht) bleibt ja bestehen:

    Das hier:

    int temp1 = (a == b ? 3 : 5);
    int temp2 = (a < 0 ? -1 : 1);
    
    DoSomething(temp1, temp2);
    

    ist besser als das hier:

    int temp1;
    int temp2;
    
    if (a == b)
        temp1 = 3;
    else
        temp1 = 5;
    
    if (a < 0)
        temp2 = -1;
    else
        temp2 = 1;
    
    DoSomething(temp1, temp2);
    

    Kann man so sehen. Muss man aber nicht - kommt drauf an was man gewohnt ist zu lesen.

    Was wohl noch besser wäre:

    int ComputeFoo(int a, int b)
    {
        if (a == b)
            return 3;
        else
            return 5;
    }
    
    int ComputeBar(int a)
    {
        if (a < 0)
            return -1;
        else
            return 1;
    }
    
    // ...
    
    DoSomething(ComputeFoo(a, b), ComputeBar(a));
    

    Wer es so super cool findet dass er es unbedingt machen will kann dann ja ComputeFoo mit ? statt if implementieren. Das tut dann nicht mehr so weh, weil ein einfaches

    int ComputeFoo(int a, int b)
    {
        return (a == b) ? 3 : 5;
    }
    

    lässt das WTF-O-Meter lange nicht so weit ausschlagen wie ein

    DoSomething(a == b ? 3 : 5, a < 0 ? -1 : 1);
    

    ps:
    Ganz schlaue können auch

    int ComputeFoo(int a, int b)
    {
        return 5 - 2 * (a == b);
    }
    

    schreiben. Wobei ich mit denen dann nicht unbedingt was zu tun haben möchte.



  • hustbaer schrieb:

    Was wohl noch besser wäre:

    Wieso ist es besser, ne fette Funktion zu deklarieren, nur um nen winzigen Audruck, den man einmal an dieser einen speziellen Stelle und sonst nie wieder braucht, zu benutzen?



  • Noch ein anderes Argument für ?: ist der Fall, dass man ja in der Regel den Scope einer Variablen klein halten will und sie zusätzlich auch gerne const deklariert, was in dem if-Fall nicht geht.

    Interessant ist natürlich auch, wenn man als Typ nicht einen einfachen Typ hat, sondern eine komplizierte Klasse, ggf. sogar mit nicht-trivialem default-Konstruktor.

    Sobald das ?:-Konstrukt aber zu kompliziert/unübersichtlich wird, würde ich an eine Funktion denken. Besonders schön sind mehrfach verschachtelte ?:-Konstrukte 😉



  • C-er schrieb:

    Antwort A schrieb:

    "Das hast Du Knallcharge doch eins-zu-eins aus dem Internet kopiert!"

    Also, ich hab's mir zumindest spontan selbst ausgedacht und nicht aus dem Internet kopiert.

    Das war ein Witz...
    Und das sollte Arcoth sein, wie er mit seinem hypothetischen Kollegen spricht. Der Deinen Code von hier kopiert hat.

    Sorry, wenn Du Dich angegriffen fühltest.


Anmelden zum Antworten