2016-10-14 1 views
16

Wenn ich If-Else-Anweisungen in C schreibe, gibt es einen Grund, warum man den Operator "gleich" über "ungleich" verwenden würde. , wenn beide zum selben Ergebnis führen können?"Gleich" gegenüber "ungleich" Operatoren in einer If-Else-Anweisung

Der folgende Code enthält den Kontext. Wenn der Argumentwert gleich 2 ist, wird eine Zeichenfolge vom Benutzer abgerufen. Wenn jedoch ein anderer Wert von Argumenten erhalten wird, wird eine Fehlermeldung angezeigt.

int main(int argc, string argv[]) 
{ 
    string msg; 

    if (argc == 2) 
    { 
     msg = GetString(); 
    } 
    else 
    { 
     printf("ERROR: Please only enter a single key! \n"); 
     return 1; 
    } 

Allerdings kann ich genau das gleiche Ergebnis wie die oben erreichen, indem er den Zustand des if-else-Schleife Wechsel zu sein „nicht gleich zu“, und die damit verbundenen Aktionen spiegeln. Siehe unten:

Wie auch immer, da beide das gleiche Ergebnis produzieren, sollte man bevorzugt gegenüber dem anderen verwendet werden?

+0

Wenn Sie denken, dass es wichtig ist, dann sollten Sie erwarten, dass der Compiler eine so triviale Transformation für Sie vornimmt. – jamesdlin

+0

Es gibt auch die Frage, was 'string' in diesem Code ist, da' main() 'ein Array von ihnen akzeptiert. Wenn 'string' nicht äquivalent zu' char * 'ist, hat der Code ein undefiniertes Verhalten. Es gibt möglicherweise auch undefiniertes Verhalten, wenn 'GetString()' etwas anderes als ein 'char *' zurückgibt. Wenn in diesem Codefragment ein nicht definiertes Verhalten vorliegt, ist die Debatte darüber, wie die 'if'-Anweisung implementiert wird, strittig. – Peter

+8

Können wir bitte aufhören, jede einzelne Frage des Codierungsstils grundsätzlich zu schließen? Diese Dinge sind sehr wichtig zu diskutieren und es gibt kein Forum für sie überall. Programmierbücher erwähnen typischerweise Stil nicht, auch Programmierer nicht. Und damit sind die meisten C- und C++ - Programme unlesbar. Pragmatische Argumente von erfahrenen Programmierern über Stil zu hören, ist sehr hilfreich für alle. SO ist ideal für diesen Zweck. – Lundin

Antwort

12

Es gibt einen technischen Grund in C++, und das ist, weil, wenn Sie die Angewohnheit haben, == über != zu verwenden, müssen Sie nicht so viele Operatoren überladen.

Dies ist wichtig, wenn Sie mit Funktionsobjekten ("Funktoren") zu tun haben. Zum Beispiel, wenn Sie eine Standard-Container-Klasse verwenden, um Ihre eigenen benutzerdefinierten Objekte zu speichern und sie automatisch sortieren zu lassen. Damit das Funktionsobjekt (zum Beispiel std :: equal_to) funktioniert, muss Ihre Klasse nur den Operator == überladen. Sie müssen == und != nicht beide überladen.

Ebenso müssen andere Funktionsobjekte nur < und nicht alle < > == != <= >= überladen.


Im Allgemeinen sind Negationen für das menschliche Gehirn nicht einfach zu verstehen. Vor allem, wenn Sie doppelte Negationen haben. In den meisten Programmiersprachen ist es üblich, zuerst die Gleichheitsprüfung zu schreiben, wenn die Reihenfolge technisch nicht wichtig ist. Meistens macht es den Code leichter zu lesen.

Aber so oft mit Programmierung und Codierung Stil, gibt es keine schwarzen oder weißen Regeln. Wenn der Grund für die Überprüfung darin besteht, einen Fehler zu finden, hat der lesbarste Weg zum Schreiben der Fehlerbehandlung Vorrang vor "Menschen finden Negationen schwerer zu lesen".

das Betrachten nicht allzu gut geschriebenen Code:

if(input == good) 
{ 
    if(format == expected) 
    { 
    do_stuff(); 
    return ok; 
    } 
    else 
    { 
    return error_format; 
    } 
} 
else 
{ 
    return error_input; 
} 

Stellen wir noch mehr Fehlerbehandlung dazu hinzufügen müssen. Ein ziemlich üblicher Fall: Angenommen, wir schreiben einen Parser oder einen Datenprotokolldecoder mit viel Fehlerbehandlung. Die vielen Ebenen geschachtelter Klammern würden den Code bald in ein totales Chaos verwandeln.

Wir können die Notwendigkeit verschachtelte if-Anweisungen loswerden, wenn wir von == zu! = Wechseln.

Dies wird viel besser lesbar und gut skalieren, wenn wir weitere Fehlerprüfungen hinzufügen müssen. Indem wir zu! = Gewechselt haben, haben wir den Code lesbarer gemacht.

13

Es ist nur ein Problem mit dem Codierungsstil. Ich hasse die Hauptlogik nisten, werde ich es schreiben, wie:

int main(int argc, string argv[]) 
{ 
    if (argc != 2) 
    { 
     printf("ERROR: Please only enter a single key! \n"); 
     return 1; 
    } 

    string msg = GetString(); 
} 

BTW: Die signatrue von mainint main(int argc, char *argv[]) sein sollte.

+1

Es könnte "nur" ein Stilproblem sein, aber trotzdem ist es gut, einen guten Stil zu haben. Vor allem für C ist Ihre Lösung deutlich sauberer und idiomatischer als jede andere Option in der Frage von OP. –

5

Normalerweise bevorzuge ich "gleich", weil es Code für einen Menschen "lesbarer" macht. Es macht den Code einfacher. Es wäre eher eine "nette Kodierungsrichtlinie" als eine "Regel", da es die Laufzeit überhaupt nicht beeinflusst (es war Teil der Kodierungsrichtlinien meiner früheren Firma).

prüfen dies:

if (!isEmpty()) 

Es Ihr Gehirn ein paar Millisekunden mehr dauern wird, zu verstehen, was der Test funktioniert, als wenn Sie schreiben:

if (isEmpty()) 

Auch wenn es keine Auswirkungen auf die Laufzeit hat, Ich bevorzuge normalerweise "ist gleich" zu "ist nicht gleich".

Die gleichen Argumente gelten für Variablen und Funktionsnamen. Bevorzugen Sie isSet Attribut/Methode über isNotSet. Ein Stück Code wie if (!isNotSet()) zu lesen ist einfacher als wenn if (isSet()), auch wenn sie am Ende gleichwertig sind.

Wenn Sie Code verwenden, haben Sie keine Kontrolle über und dies stellt ein Mitglied eine negativen Fragen zu beantworten, dann:

if (isNotSet()) 

ist auf jeden Fall einfacher für einen Entwickler zu lesen als:

if (!isNotSet()) 
0

Dies ist eine Programmdesignfrage. Als Programmierer müssen Sie entscheiden, welcher für die Ausführung, Wartung, Lesbarkeit und Leistung besser fließt. Darüber hinaus sind dies zwei völlig unterschiedliche Aussagen. Wenn die Funktion NUR aufrufen soll, wenn argc gleich 2 ist, anstatt GetString() aufzurufen; immer wenn die Nummer nicht 2 ist.

+0

Die beiden Codefragmente in der Frage haben das gleiche Verhalten. – user3386109

1

Wie andere gesagt haben, ist es ein Stilproblem. Es gibt keinen wirklichen Unterschied.

Eine Sache zu beachten ist jedoch, zu versuchen, konsistent zu sein. Wenn Sie einen Block haben, der prüft, ob value1 == 2, versuchen Sie nicht, den nächsten Block zu überprüfen value2 != 4. Der einzige schlechte Stil ist inkonsistenter Stil.

+0

Was ist, wenn Sie die Logik der Funktion kurzschließen und früh zurückkommen können, wenn 'value1 == 2', und ein bedeutender Teil der Logik gilt nicht, wenn' value2 == 4', obwohl? 'if (value2! = 4) {/ * logic * /}' ist viel sauberer als 'if (value2 == 4) {} else {/ * logic * /}' und sauberer als 'if (! (value2 == 4)) {/ * Logik * /} '. Unter der Annahme, dass der Typ beide Operatoren definiert hat, ist es in der Regel sauberer, das zu verwenden, was am besten für das geeignet ist, was Sie testen müssen. –

0

Heutzutage gibt es keinen semantischen Unterschied zwischen den beiden Fällen, wie auch die einfachere Optimierung von Compilern angewandt den „beabsichtigten Ausführungsfluss“ stören könnte.

Vielleicht vor 30 bis 40 Jahren hätte es einen Unterschied zwischen den beiden Möglichkeiten geben können, wenn der Codegenerationsschritt des C-Compilers dem geschriebenen Code sehr nahe kam.

Der tatsächliche Unterschied ist heute in der Syntax und Stil Klarheit.

Also, beim Schreiben

while(*dst++=*src++); 

heute die gleichen Maschinencode wie

for(i=0; src[i] != 0; i++) 
    dst[i] = src[i]; 
dst[i] = '\0'; 

Letztere im Allgemeinen sein könnte viel einfacher zu lesen erzeugen könnte, wie in

gesehen
if(! isOK()) 
    dontDoIt(); 
else 
    doIt(); 

und in

if(isOK()) 
    doIt() 
else 
    dontDoIt(); 

Aber seien Sie versichert, "Klarheit" ist kein absoluter Wert: Es hängt nicht nur von den "Programmierfähigkeiten und Geschmack" der Leser/Gutachter, sondern auch im Code selbst ab.

Fazit: Treffen Sie eine Wahl und bleiben Sie dabei für Einheitlichkeit!

Verwandte Themen