2009-12-29 10 views
7

Va bene, ho visto molti post qui circa idiomi dispari e pratiche comuni in C che potrebbero non essere inizialmente intuitiva. Forse alcuni esempi sono in ordineC Modi di dire e fatti poco noti

elementi di un array:

#define ELEMENTS(x) (sizeof (x)/sizeof (*(x))) 

Odd array indexing:

a[5] = 5[a] 

Single line if/else/while/for safe #defines

#define FOO(X) do { f(X); g(X); } while (0) 
#define FOO(X) if (1) { f(X); g(X); } else 

La mia domanda al perito programmatori C là fuori è: Che idiomi , pratiche, snippits di codice o fatti poco noti mostrano molto nel codice C ma potrebbero non essere molto intuitivi ma offrono una buona conoscenza della programmazione C?

+6

dovrebbe essere wiki della comunità –

+0

Peccato che fosse chiuso, bot non essendo una domanda ... –

risposta

11

Il "operatore freccia" per conto alla rovescia da n-1 a 0:

for (int i = n; i --> 0;) ... 

Non è estremamente comune, ma è un'illustrazione interessante che in qualche modo le parti inizializzazione/test/aggiornamento di una for il ciclo è convenzione. Questo è il solito schema, ma puoi comunque inserire espressioni arbitrarie.

È anche un piccolo promemoria su come funziona l'analisi lessicale.

+0

http://cplusplus.co.il/2009/12/28/the-omnipotent-arrow-operator/ – rmn

+0

C'è semplicemente non fuggire da questo potente operatore. – GManNickG

+0

Buono per la ricerca lineare. Dopotutto, il primo posto che dovresti guardare è l'ultimo posto in cui metti qualcosa. –

4

L'operatore virgola, benché perfettamente documentato (K & R ecc.) Appare in un bel po 'di codice algoritmico ed è spesso una sorpresa per molti programmatori che non l'hanno mai incontrato prima. E 'spesso utilizzato per semplificare alcuni costrutti ciclo:

#define kITERATIONS_MAX 10 
int i=0,j=0,array[kITERATIONS_MAX],outArray[kITERATIONS_MAX],temp=0; 

for (i=0,j=kITERATIONS_MAX-1; i < kITERATIONS_MAX; i++,j--) 
{ 
temp = array[i]*array[j]; 
outArray[i]=temp; 
} 

Il codice sopra moltiplicherà elementi di matrice 0 thru 9 dove 9 thru 0 mentre evitando cicli annidati.

Quando si utilizza l'operatore virgola, vengono valutate sia la prima che la seconda espressione. Il risultato della prima espressione viene ignorato e viene restituito il risultato della seconda espressione.

+0

Io uso l'operatore virgola in 'while' condizioni che fanno due cose, di solito assegnazione seguito da un test:' while (c = getc(), c = EOF!) ... '. –

+0

@DavidRTribble Il 'c = getc()' restituisce essere uguale a 'C', il che significa che può solo (presumibilmente) usare' while ((c = getc())! = EOF) ...' –

+0

@RobbieMckennie, È vero, ma trovo più semplice leggere le due operazioni (assegnazione e confronto) come due espressioni separate all'interno dell'espressione' while' di controllo. –

5

Dal qualcuno parlare in ogni caso, potrebbe anche essere io: Duff's Device. È una bella illustrazione del modo in cui le etichette funzionano in C, e comprenderlo mi ha dato una "esperienza aha" la prima volta. Questo è il suo codice originale:

send(to, from, count) 
register short *to, *from; 
register count; 
{ 
    register n=(count+7)/8; 
    switch(count%8){ 
    case 0: do{ *to = *from++; 
    case 7:  *to = *from++; 
    case 6:  *to = *from++; 
    case 5:  *to = *from++; 
    case 4:  *to = *from++; 
    case 3:  *to = *from++; 
    case 2:  *to = *from++; 
    case 1:  *to = *from++; 
     }while(--n>0); 
    } 
} 

Oggi, non si sarebbe usare register, ed evitare di definizione di funzione vecchio stile.

+0

Inoltre, a quanto ho capito, non si vuole fare questo su un moderno compilatore di ottimizzazione --- ci si metterà sulla sua strada. – dubiousjim