Quizzettino del week-end

Dato che agosto è finito, e anche l’estate sta finendo, per allietare il fine settimana vi propongo un quiz facile facile, la cui soluzione sarà un post lungo e noiosissimo (scherzo! o forse no, boh). Insomma, la soluzione sarà data prossimamente, intanto beccatevi il quiz.

Qual’è il comportamento del seguente programmino C?

#include <stdio.h>

int d = 5;

int set(int x)
{
    return d = x;
}

int main()
{
    int r = set(0) + 7 / d;
    printf("risultato = %d\n", r);
    return 1; 
}

Cercate di essere precisi nella risposta, mi raccomando. Alla prossima!

Posta un commento o usa questo indirizzo per il trackback.

Commenti

  • AlessandroPischedda  Il 31 agosto 2012 alle 22:43

    Questo codice restituisce l’eccezione floating exception “division-by zero”. Questo avviene perché nel calcolo dell’espressione per la variabile r ha maggior precedenza la chiamata a funzione ( set(int x) ) rispetto gli altri operatori.
    Quindi abbiamo prima l’esecuzione della funzione set(), questa assegna alla variabile d il valore di x ( cioè 0 ) e restituisce il valore di d (sempre zero). Ora continua con il calcolo dell’espressione che secondo le precedenze degli operatori può essere riscritta come :
    0 + ( 7 / d )
    d ha valore uguale a 0 e quindi restituisce a run-time il floating exception.

    Spero di esser stato preciso ma ancora di più di non aver detto fesserie :).

  • juhan  Il 1 settembre 2012 alle 08:42

    Ha ragione Alessandro. Io che sono un vecchio pasticcione metto sempre dei printf() strategici e in questo caso uno nella set() viene eseguito prima dell’errore.
    Quest’abitudine mi deriva, forse, dai SO prima di Unix, molto meno amichevoli verso il programmatore (davvero).

  • AlessandroPischedda  Il 1 settembre 2012 alle 12:47

    Se posso vorrei porvi un problema, di cui non so la risposta, che riguarda l’esercizio di sopra. Ho provato a modificare l’espressione del calcolo della r (per essere leggermente più ingannevole) come segue:

    r = 7 / d + set(0);

    Visto che la chiamata di funzione ha precedenza massima mi aspetterei lo stesso risultato, ovvero floating exception… invece restituisce 1. Se invece uso

    r = d + set(0);

    Ottengo r = 0, mentre se uso 7 / (d + set(0)) ottendo l’eccezione.
    Ora tutto questo mi fa pensare che l’operazione di divisione abbia precedenza superiore alla chiamata di funzione però non dovrebbe essere così, o sbaglio ?

    • glipari  Il 1 settembre 2012 alle 20:13

      Direi che ti stai avvicinando … 🙂 (domani scrivo il post di risposta)

  • AlessandroPischedda  Il 1 settembre 2012 alle 22:32

    Ho indagato un po in giro per la rete ed ho trovato la seguente cosa :
    ” C, like most languages, does not specify the order in which the operands of an operator are evaluated. (The exceptions are &&, ||, ?:, and `,’.).
    For example, in a statement like

    x = f() + g();
    f may be evaluated before g or vice versa; thus if either f or g alters a variable on which the other depends, x can depend on the order of evaluation…. Function calls, nested assignment statements, and increment and decrement operators cause “side effects” “.

    Quindi la precedenza degli operatori mi dice come dovrebbe essere “scritta” una espressione senza parentesi che contiene operatori diversi cioè nel nostro caso r = set(0) + 7 / d sarebbe vista come r = set(0) + ( 7 / d). Però a quanto pare in C/C++ non è specificato l’ordine con cui devono essere valutati gli operatori ma questo è lasciato al compilatore e deciderà lui l’ordine. Tant’è che il codice potrebbe non essere portabile.

    Spero di essermi avvicinato alla soluzione.

Trackback

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: