2016-05-05 12 views
7

Wenn ich zwei Integer-Werte haben kann ich einfach auf Gleichheit testen:Vergleich mehrerer Integer-Werte für die Gleichstellung

if (a == b) 

wenn ich drei ganzzahlige Werte dann könnte ich etwas tun:

if ((a == b) && (a == c) && (b == c)) 

Ich habe eine Situation, wo ich 6 Werte habe, um auf Gleichheit zu prüfen, dieser Ansatz wird ausführlich erhalten

Ist ihr ein besserer, und mehr C idiomatisch (c-onic?) Mittel, um dieses zu erreichen?

eigentlich nur das geschrieben zu haben, dass ich sehen kann:

if ((a == b) && (b == c) && (c == d)...) 

logisch in Ordnung ist, dh Sie nicht die Kombinationen alle brauchen als a == b und b == c impliziert a == c

Aber in Bezug auf Klarheit wie nah ich komme:

if (a == b == c)?

+1

Können Sie ein Array für diese 6 Werte verwenden? (so dass Sie stattdessen eine Schleife verwenden). –

+1

Speichern Sie alle von ihnen in einem Array oder Vektor und führen Sie bitweise XOR? Wenn die letzte Antwort '0' ist, dann 'a === b == c', sonst nicht. –

+5

@abhishek_naik 1^2^3 == 0 also 1 == 2 und 2 == 3? –

Antwort

7

Sie sind nicht ganz in der Nähe in Gang zu bringen, um a == b == c.

Um erfahrene C-Programmierer die geringste Überraschung zu verursachen, ich denke, das Beste ist,

if(a == b && b == c && c == d && d == e && e == f) 

das heißt im Grunde wie das, was Sie bereits haben, mit weniger Klammern.Ich bin nicht immer dagegen, Klammern hinzuzufügen, die für den Compiler keinen Unterschied machen, um Menschen zu helfen, die nicht alle Präzedenzregeln kennen, aber ich denke, Vergleiche getrennt durch && (ohne || eingemischt) sind ein einfacher Fall Klammern sind mehr Unordnung als sie wert sind.

Wenn die Variablennamen lang sind, alles auf einer Zeile setzen wird nicht schön sein, vielleicht

if(a == b && 
    b == c && 
    c == d && 
    d == e && 
    e == f) 

oder dies könnte da die Verdoppelung der die a in jeder Zeile wird besser sofort bemerkbar:

if(a == b && 
    a == c && 
    a == d && 
    a == e && 
    a == f) 

Wenn Sie es wirklich kompakt sein wollen, die p99 preprocessor library bietet dies:

#include "p99_for.h" 

if(P99_ARE_EQ(a,b,c,d,e,f)) 

, die wie John Zwinck Antwort aussieht, erfordert aber keine Hilfsfunktion.

+0

nun, das ist ziemlich genau das, was ich implementiert habe, die linke Seite gleich ist eine nette Geste - p99 ist neu für mich und sieht sehr interessant aus .. cheers for the heads-up – bph

+0

crikey - das Referenzhandbuch für p99 ist über 1000 Seiten lang! das ist eine Header-Datei .. – bph

6

Wenn Sie sechs Werte überprüfen wollen, wäre ein Ansatz, um sie zu speichern in einem Array

int a[6]; 

equals = 1; 
for (int i=0; i<5; i++) 
{ 
    if (a[i] != a[i+1]) 
    { 
     equals = 0; 
     break; 
    } 
} 
+1

Kombination von diesem mit einer var arg-Funktion könnte ganz nett sein – bph

7

ich Ihnen zeigen kann, wie es in einem variadische Makro tun, so können wir schreiben:

if(EQI(a, b, c, d, e, f)) 

Hier ist der Code:

#include <stdarg.h> 
#include <stddef.h> 

#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) 
#define EQI(...) (\ 
    alleqi(NUMARGS(__VA_ARGS__), __VA_ARGS__)) 

/* takes count number of int arguments */ 
int alleqi(size_t count, ...) 
{ 
    va_list va; 
    va_start(va, count); 

    int v0 = va_arg(va, int); 

    for (; count > 1; count--) { 
     if (v0 != va_arg(va, int)) { 
      break; 
     } 
    } 

    va_end(va); 
    return count == 1; 
} 

Bitte die oben nur für int arbeitet darauf hingewiesen werden, Argumente (und wahrscheinlich andere Typen, deren Größe die gleiche wie int ist, obwohl ich für jemanden bereit bin, mich anzuklagen, undefiniertes Verhalten zu fördern, wenn ich das annonciere!).

Dank diesen Stand der Post für herauszufinden, wie Argumente in einem variadische Makro zählen: https://stackoverflow.com/a/2124433/4323

+0

vielleicht INTEQ eher als EQ nach Prinzip der geringsten Überraschung zu halten? – bph

+1

@bph: Ich habe es jetzt "EQI" gemacht, obwohl ich denke, dass es in Ordnung ist, es in beliebigen Vier-Byte-Mengen zu verwenden. Wir könnten eine 'EQL' für 8-Byte-Mengen erstellen. Sie können sogar 'assert()' die Größe des ersten Arguments ist korrekt, aber darüber hinaus ist langweilig. –

+0

Schöne Verwendung des zusammengesetzten Literals, um "count" zu bestimmen. – chux

2

Approaches Verwendung von Arrays erforderlich, dass Sie Ihre Datenstruktur in ein Array zu ändern.

Ansätze, die ein variadisches Makro verwenden, erfordern einen zusätzlichen Funktions- und Funktionsaufruf (Overhead).

Mit Ausnahme dieser zwei Ansätze ist die einzige andere Möglichkeit, die ich sehe, sie aufzuschreiben. Ich fühle den besten Weg, oder den klareren Weg, die erste Variable zu nehmen und sie mit allen anderen Variablen zu vergleichen. Implizit dann entweder alle variabes gleich sind, oder zumindest zwei Variablen sind ungleich:

if ((a == b) && (a == c) && (a == d) 
&& (a == e) && (a == f) && (a == g) ...) 
+1

Das ist eigentlich für 7 Variablen. Für 6 lohnt es sich kaum, etwas anderes zu tun - nur 5 Vergleiche. Wenn OP im Vorfeld erkannt hat, dass "b == c" usw. nicht getestet werden muss, hat er die Frage vielleicht nicht gestellt. –

+0

Ja, ich zögerte, als ich das OP postete - aber ich habe definitiv etwas gelernt, also alles gut – bph

Verwandte Themen