2011-08-30 15 views
14

Qualcuno potrebbe spiegare cosa fa e come è legale il codice C? Ho trovato questa linea in questo codice: http://code.google.com/p/compression-code/downloads/list, che è un'implementazione C dell'algoritmo Vitter per Adaptive Huffman CodingDue segni uguali in una riga?

ArcChar = ArcBit = 0; 

Dalla funzione:

void arc_put1 (unsigned bit) 
{ 
    ArcChar <<= 1; 

    if(bit) 
     ArcChar |= 1; 

    if(++ArcBit < 8) 
     return; 

    putc (ArcChar, Out); 
    ArcChar = ArcBit = 0; 
} 

ArcChar è un int e ArcBit è un unsigned char

risposta

18

Il valore dell'espressione (a = b) è il valore di , quindi è possibile concatenarli in questo modo. Hanno anche ragione associativa, quindi tutto funziona.

Essenzialmente

ArcChar = ArcBit = 0; 

è (circa 1 ) uguale

ArcBit = 0; 
ArcChar = 0; 

poiché il valore del primo assigment è il valore assegnato, così 0.

Per quanto riguarda i tipi, anche se è un ArcBitunsigned char il risultato della cessione otterrà allargato a int.


Non esattamente lo stesso, anche se, come R .. sottolinea in un commento qui sotto.

+0

Grazie per spiegare la questione del tipo di dati. – user807566

+6

Non è esattamente la stessa cosa della versione a due istruzioni, che ha un punto di sequenza tra i due compiti. Questo può fare la differenza se i due lvalue sono '* ptr1' e' * ptr2' e capita di puntare allo stesso posto (in cui la versione a una istruzione avrebbe UB) o se sono entrambi 'volatili' e ti interessa l'ordine in cui si svolgono gli incarichi. –

+0

Ah, dannazione. E ora non posso cancellare: -/ – Joey

3

Assegna ArcBit a 0, quindi assegna ArcChar al valore dell'espressione ArcBit = 0 (ad esempio 0)

3

Un'operazione di assegnazione (a = b) stessa restituisce un valore, che può essere ulteriormente assegnato a un altro valore; c = (a = b). Alla fine, sia a che c avranno il valore di b.

+0

Interessante. Non mi rendevo conto che restituiva un valore. Grazie. – user807566

4

Imposta entrambe le variabili su zero.

int i, j; 
i = j = 0; 

lo stesso che scrivere

int i, j; 
j = 0; 
i = j; 

o scrivendo

int i, j; 
i = 0; 
j = 0; 
1

In alcune lingue, le assegnazioni sono dichiarazioni: essi causano qualche azione abbia luogo, ma non lo fanno avere un valore loro stessi Ad esempio, in Python è vietato scrivere

x = (y = 10) + 5 

poiché la cessione y = 10 non può essere utilizzato quando è previsto un valore.

Tuttavia, C è una delle molte lingue in cui le assegnazioni sono espressioni: producono un valore, così come qualsiasi altro effetto che potrebbero avere. Il loro valore è il valore che viene assegnato. La riga di codice precedente sarebbe legale in C.

L'uso di due segni uguale su una linea viene interpretato in questo modo:

ArcChar = (ArcBit = 0); 

Cioè: ArcChar è beging assegnato il valore di ArcBit = 0, che è 0, quindi entrambe le variabili diventano 0.


x = y = 0 è in realtà legale in Python, ma è considerato uno speciale-caso l'istruzione di assegnazione, e cercando di fare qualcosa di più complicato con le assegnazioni fallirà.

+0

Buona spiegazione. Grazie. – user807566

5
ArcChar = ArcBit = 0; 

L'assegnazione è lasciato associativa, quindi è equivalente a:

ArcChar = (ArcBit = 0); 

Il risultato ArcBit = 0 è il valore appena assined, che è - 0, quindi ha senso per assegnare tale 0-ArcChar

1

Assegnazione in C è un'espressione, non comunicato. Inoltre è possibile assegnare liberamente valori di dimensioni diverse (char senza segno a int e viceversa). Benvenuti in linguaggio di programmazione C :)

5

Questo è solo il concatenamento dell'operatore di assegnazione. Lo standard dice in 6.5.16 Assignment operators:

Un operatore di assegnazione deve disporre di un lvalue modificabile come il suo operando di sinistra. Un operatore di assegnazione memorizza un valore nell'oggetto designato dall'operando di sinistra. Un'espressione di assegnazione ha il valore dell'operando di sinistra dopo l'assegnazione, ma non è un lvalue . Il tipo di un'espressione di assegnazione è il tipo dell'operando di sinistra a meno che l'operando di sinistra abbia il tipo qualificato, nel qual caso si tratta della versione non qualificata del tipo di operando di sinistra . L'effetto collaterale dell'aggiornamento del valore memorizzato dell'operando di sinistra è tra il punto di sequenza precedente e quello successivo.

Così si può fare qualcosa di simile:

a=b=2; // ok 

Ma non questa:

a=2=b; // error 
Problemi correlati