2016-05-05 20 views
7

Se ho due valori interi posso verificare l'uguaglianza semplice:Confronto di diversi valori interi per l'uguaglianza

if (a == b) 

se ho tre valori interi poi ho potuto fare qualcosa di simile:

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

Ho una situazione in cui ho 6 valori da testare per l'uguaglianza, questo approccio sta per diventare prolisso

È un loro migliore, e più C (c-onico?) Significa raggiungere questo obiettivo?

in realtà, solo dopo aver scritto questo posso vedere che:

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

è logicamente ok, vale a dire che non è necessario tutte le combinazioni come a == b e b == c implica a == c

Ma in termini di chiarezza di espressione quanto vicino posso arrivare a:

if (a == b == c)?

+1

È possibile utilizzare una matrice per questi 6 valori? (in modo da utilizzare invece un ciclo). –

+1

Memorizzarli tutti in una matrice o vettore e eseguire XOR bit a bit? Se la risposta finale è '0', quindi' a === b == c', altrimenti no. –

+5

@abhishek_naik 1^2^3 == 0 quindi 1 == 2 e 2 == 3? –

risposta

7

Non avete intenzione di ottenere molto vicino a a == b == c.

a causare esperti programmatori C la minima sorpresa, penso che questo sia migliore è

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

cioè fondamentalmente come quello che hai già, con meno parentesi.Non sono sempre contrario all'aggiunta di parentesi che non fanno alcuna differenza per il compilatore per aiutare gli umani che non conoscono tutte le regole di precedenza, ma penso che i confronti separati da && (senza ||) siano un caso abbastanza semplice che il le parentesi sono più confuse di quanto valgano.

Se i nomi delle variabili sono lunghi, mettere tutto su una linea non sta per essere abbastanza, quindi forse

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

o questo potrebbe essere migliore in quanto la duplicazione del l'a in ogni linea sarà essere immediatamente evidente:

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

Se si vuole veramente che sia compatto, il p99 preprocessor library offre questo:

#include "p99_for.h" 

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

che assomiglia alla risposta di John Zwinck ma non richiede una funzione di supporto.

+0

bene questo è praticamente ciò che ho implementato, mantenendo il lato sinistro lo stesso è un bel tocco - p99 è nuovo per me e sembra molto interessante .. applausi per l'heads-up – bph

+0

crikey - il manuale di riferimento per p99 è lungo più di 1000 pagine! questo è un file di intestazione .. – bph

6

Se si desidera controllare sei valori, un approccio sarebbe quello di memorizzarli in un array

int a[6]; 

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

combinazione di questo con una funzione var arg potrebbe essere abbastanza bello – bph

7

posso mostrarvi come farlo in una macro variadic, in modo che possiamo scrivere questo:

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

Ecco il codice:

#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; 
} 

si prega di notare quanto sopra funziona solo per int argomenti (e probabilmente altri tipi la cui dimensione è la stessa di int, anche se mi sto preparando a qualcuno per accusarmi di promuovere un comportamento indefinito se lo pubblicizzo!).

Grazie a questa prima postale per capire come contare gli argomenti in una macro variadic: https://stackoverflow.com/a/2124433/4323

+0

forse INTEQ piuttosto che EQ per aderire al principio di sorpresa minima? – bph

+1

@bph: l'ho reso 'EQI' ora, anche se penso che sia OK usarlo su qualsiasi quantità a quattro byte. Potremmo creare un 'EQL' per quantità di otto byte. Puoi anche 'assert()' la dimensione del primo argomento è corretta, ma al di là di questo è noioso. –

+0

Bel uso del letterale composto per determinare il conteggio. – chux

2

Approcci che utilizzano gli array richiedono di modificare la struttura di dati in un array.

L'approccio mediante una macro variadica richiede una funzione aggiuntiva e una chiamata di funzione (sovraccarico).

Fatta eccezione per questi due approcci, l'unico altro modo che vedo è di scriverli. Sento che il modo migliore, o il modo più chiaro, è prendere la prima variabile e confrontarla con tutte le altre variabili. Implicitamente allora o tutti variabes sono uguali, o almeno due variabili sono disuguali:

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

Questo è in realtà per 7 variabili. Per 6 non vale la pena fare nient'altro - solo 5 confronti. Se OP si fosse realizzato in anticipo non è necessario testare 'b == c' ecc., Potrebbe non aver fatto la domanda. –

+0

Sì, ho esitato quando ho postato l'OP - ma ho sicuramente imparato qualcosa così tutto bene – bph

Problemi correlati