Successivo: , Precedente: , Su: Tutti gli operatori   [Contenuti][Indice]


6.2.3 Espressioni di assegnamento

Un assegnamento è un’espressione che memorizza un valore (generalmente diverso da quello che la variabile aveva in precedenza) in una variabile. Per esempio, si assegni il valore uno alla variabile z:

z = 1

Dopo l’esecuzione di quest’espressione, la variabile z ha il valore uno. Qualsiasi precedente valore di z prima dell’assegnamento viene dimenticato.

Gli assegnamenti possono anche memorizzare valori di stringa. Il seguente esempio memorizza il valore "questo cibo è buono" nella variabile messaggio:

cosa = "cibo"
predicato = "buono"
messaggio = "questo " cosa " è " predicato

Quest’esempio illustra anche la concatenazione di stringhe. Il segno ‘=’ è un operatore di assegnamento. È il più semplice fra gli operatori di assegnamento perché il valore dell’operando di destra è memorizzato invariato. La maggior parte degli operatori (addizione, concatenazione e così via) non fanno altro che calcolare un valore. Se il valore non viene poi utilizzato non c’è alcun motivo per usare l’operatore. Un operatore di assegnamento è differente; produce un valore; anche se poi non lo si usa, l’assegnamento svolge ancora una funzione alterando la variabile. Chiamiamo questo un effetto collaterale.

L’operando di sinistra non dev’essere necessariamente una variabile (vedi la sezione Variabili); può essere anche un campo (vedi la sezione Cambiare il contenuto di un campo) o un elemento di un vettore (vedi la sezione Vettori in awk). Questi operandi sono chiamati lvalue, il che significa che possono apparire sul lato sinistro di un operatore di assegnamento. L’operando sul lato destro può essere qualsiasi espressione; produce un nuovo valore che l’assegnamento memorizza nella variabile, nel campo o nell’elemento di vettore specificati. Tali valori sono chiamati rvalue.

È importante notare che le variabili non hanno dei tipi permanenti. Il tipo di una variabile è semplicemente quello di qualsiasi valore le sia stato assegnato per ultimo. Nel seguente frammento di programma, la variabile pippo ha dapprima un valore numerico, e in seguito un valore di stringa:

pippo = 1
print pippo
pippo = "pluto"
print pippo

Quando il secondo assegnamento dà a pippo un valore di stringa, il fatto che avesse precedentemente un valore numerico viene dimenticato.

Ai valori di stringa che non iniziano con una cifra viene assegnato il valore numerico zero. Dopo l’esecuzione del seguente codice, il valore di pippo è cinque:

pippo = "una stringa"
pippo = pippo + 5

NOTA: Usare una variabile sia come numero che come stringa può originare confusione e denota uno stile di programmazione scadente. I due esempi precedenti illustrano come funziona awk, non come si dovrebbero scrivere i programmi!

Un assegnamento è un’espressione, per cui ha un valore: lo stesso valore che le è stato assegnato. Così, ‘z = 1’ è un’espressione col valore uno. Una conseguenza di ciò è che si possono scrivere più assegnamenti insieme, come:

x = y = z = 5

Quest’esempio memorizza il valore cinque in tutte e tre le variabili, (x, y e z). Questo perché il valore di ‘z = 5’, che è cinque, è memorizzato in y e poi il valore di ‘y = z = 5’, che è cinque, è memorizzato in x.

Gli assegnamenti possono essere usati ovunque sia prevista un’espressione. Per esempio, è valido scrivere ‘x != (y = 1)’ per impostare y a uno, e poi verificare se x è uguale a uno. Però questo stile rende i programmi difficili da leggere; una tale nidificazione di assegnamenti dovrebbe essere evitata, eccetto forse in un programma usa-e-getta.

Accanto a ‘=’, ci sono diversi altri operatori di assegnamento che eseguono calcoli col vecchio valore di una variabile. Per esempio, l’operatore ‘+=’ calcola un nuovo valore aggiungendo il valore sul lato destro al vecchio valore di una variabile. Così, il seguente assegnamento aggiunge cinque al valore di pippo:

pippo += 5

Questo equivale a:

pippo = pippo + 5

Si usi la notazione che rende più chiaro il significato del programma.

Ci sono situazioni in cui usare ‘+=’ (o qualunque operatore di assegnamento) non è la stessa cosa che ripetere semplicemente l’operando di sinistra nell’espressione di destra. Per esempio:

# Grazie a Pat Rankin per quest'esempio
BEGIN  {
    pippo[rand()] += 5
    for (x in pippo)
       print x, pippo[x]

    pluto[rand()] = pluto[rand()] + 5
    for (x in pluto)
       print x, pluto[x]
}

È praticamente certo che gli indici di pluto siano differenti, perché rand() restituisce valori differenti ogni volta che viene chiamata. (I vettori e la funzione rand() non sono ancora stati trattati. Vedi la sezione Vettori in awk, e vedi la sezione Funzioni numeriche per maggiori informazioni.) Quest’esempio illustra un fatto importante riguardo agli operatori di assegnamento: l’espressione di sinistra viene valutata una volta sola.

Dipende dall’implementazione stabilire quale espressione valutare per prima, se quella di sinistra o quella di destra. Si consideri quest’esempio:

i = 1
a[i += 2] = i + 1

Il valore di a[3] potrebbe essere sia due sia quattro.

La Tabella 6.2 elenca gli operatori di assegnamento aritmetici. In ogni caso, l’operando di destra è un’espressione il cui valore è convertito in un numero.

OperatoreEffetto
lvalue += incrementoAggiunge incremento al valore di lvalue.
lvalue -= decrementoSottrae decremento dal valore di lvalue.
lvalue *= coefficienteMoltiplica il valore di lvalue per coefficiente.
lvalue /= divisoreDivide il valore di lvalue per divisore.
lvalue %= moduloImposta lvalue al resto della sua divisione per modulo.
lvalue ^= esponenteEleva lvalue alla potenza esponente.
lvalue **= esponenteEleva lvalue alla potenza esponente. (e.c.)

Tabella 6.2: Operatori di assegnamento aritmetici

NOTA: Soltanto l’operatore ‘^=’ è definito da POSIX. Per avere la massima portabilità, non usare l’operatore ‘**=’.

Ambiguità sintattiche tra ‘/=’ e le espressioni regolari

C’è un’ambiguità sintattica tra l’operatore di assegnamento /= e le costanti regexp il cui primo carattere sia ‘=’. (a.b.) Questo è più evidente in alcune versioni commerciali di awk. Per esempio:

$ awk /==/ /dev/null
error→ awk: syntax error at source line 1
error→  context is
error→         >>> /= <<<
error→ awk: bailing out at source line 1

Un espediente è:

awk '/[=]=/' /dev/null

gawk non ha questo problema, e neppure lo hanno BWK awk e mawk.


Successivo: , Precedente: , Su: Tutti gli operatori   [Contenuti][Indice]