Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 27
  1. #1

    [C/C++]Passaggio di variabili per riferimento e per valore

    Salve, volevo sapere come si fa a differenziare (in C/C++) il passaggio di parametri ad una funzione per valore e per riferimento.

    In Pascal io facevo così:
    Per riferimento
    codice:
    procedure nome_procedura(var x: integer);
    begin
         ...
         ...
    end;
    Per valore
    codice:
    procedure nome_procedura(x: integer);
    begin
         ...
         ...
    end;
    Ovviamente nel primo caso rende definitive le modifiche alla variabile anche globalmente, nel secondo caso invece, una volta usciti dalla funzione, la variabile torna al valore che aveva prima del passaggio.

    Come si fa questo in C++?
    SELECT neuroni FROM cervello
    WHERE status = 'funzionante';

    La query ha restituito: 0 risultati.

  2. #2
    Per valore:
    codice:
    tipo_restituito nome_procedura(tipo_argomento nome_argomento)
    {
       // Corpo
    }

    Per riferimento:

    codice:
    tipo_restituito nome_procedura(tipo_argomento &nome_argomento)
    {
       // Corpo
    }
    (L'operatore & restituisce l'indirizzo dell'argomento passato).

    Per ottimizzare il codice, invece di utilizzare una chiamata per valore, puoi utilizzare la chiamata:
    codice:
    tipo_restituito nome_procedura(const tipo_argomento &nome_argomento)
    {
       // Corpo
    }
    (Passi per riferimento, e quindi eviti il tempo di copia, ma non permetti di modificare l'argomento con const).

  3. #3
    Originariamente inviato da RooccoXXI
    (L'operatore & restituisce l'indirizzo dell'argomento passato).
    Occhio però a non confondere l'operatore & (che appunto restituisce l'indirizzo di un lvalue) con il token & usato per specificare che un parametro o una variabile sono di tipo reference.
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    Cos'è un lvalue?
    SELECT neuroni FROM cervello
    WHERE status = 'funzionante';

    La query ha restituito: 0 risultati.

  5. #5
    Originariamente inviato da Hirakeydos
    Cos'è un lvalue?
    Un qualcosa che può stare sul lato sinistro di un'espressione di assegnamento, in genere un valore dotato di un indirizzo di memoria. Una variabile o un reference ad essa, ad esempio, sono lvalue, mentre il valore temporaneo restituito da un'espressione (ad esempio 5+4) non lo è. Ovviamente l'operatore & si può applicare solo a lvalue, dato che non ha senso cercare di ottenere l'indirizzo di qualcosa che non ha un indirizzo ( &(5+4) non ha senso).
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Originariamente inviato da MItaly
    Un qualcosa che può stare sul lato sinistro di un'espressione di assegnamento, in genere un valore dotato di un indirizzo di memoria. Una variabile o un reference ad essa, ad esempio, sono lvalue, mentre il valore temporaneo restituito da un'espressione (ad esempio 5+4) non lo è. Ovviamente l'operatore & si può applicare solo a lvalue, dato che non ha senso cercare di ottenere l'indirizzo di qualcosa che non ha un indirizzo ( &(5+4) non ha senso).
    Ho capito grazie
    E grazie anche a RooccoXXI.

    Riepilogando, se non voglio che il valore della variabile passata alla funzione venga modificato, uso l'operatore '&' (che, se ho capito bene, equivale nel pascal al non mettere la parola var); altrimenti passo semplicemente il nome della variabile in facondi in modo che le eventuali modifiche ad essa restino permanenti a livello globale (la parola var nel pascal).

    La storia del const non è proprio chiarissima invece. Credevo che per dichiarare le costanti in C/C++ si usasse #define (es. #define N 5); const che fa di preciso?
    SELECT neuroni FROM cervello
    WHERE status = 'funzionante';

    La query ha restituito: 0 risultati.

  7. #7
    Originariamente inviato da Hirakeydos
    Riepilogando, se non voglio che il valore della variabile passata alla funzione venga modificato, uso l'operatore '&' (che, se ho capito bene, equivale nel pascal al non mettere la parola var); altrimenti passo semplicemente il nome della variabile in facondi in modo che le eventuali modifiche ad essa restino permanenti a livello globale (la parola var nel pascal).
    No, è il contrario di quello che hai appena scritto. L'operatore & serve a passare la variabile per riferimento (modifiche permanenti!), mentre se lo lasci via la variabile viene passata per valore (quindi copiata prima di essere passata alla funzione e le modifiche rimangono solo all'interno della funzione).

    La storia del const non è proprio chiarissima invece. Credevo che per dichiarare le costanti in C/C++ si usasse #define (es. #define N 5); const che fa di preciso?
    La storia del const è legata all'efficienza e alla sicurezza.
    Passando una variabile per valore hai il vantaggio che il valore originale della variabile non viene modificato, però questo richiede una copia; nel caso di tipi fondamentali questa copia è veloce, ma nel caso di oggetti di grosse dimensioni può compromettere seriamente l'efficienza del programma.
    Passando per valore hai il vantaggio che la variabile non viene copiata (quindi niente tempo di copia!) ma però potrebbe essere modificata accidentalmente.
    L'utilizzo di const con la chiamata per riferimento mette assieme i due vantaggi, eliminando gli svantaggi: la variabile non viene copiata (quindi efficenza!) ma la parola chiave const non ti permette di fare modifiche alla variabile (così da non modificare accidentalmente il valore originale). Questo sempre se NON devi/vuoi modificare il valore della variabile. Se ti serve che la funzione cambi il valore della variabile allora questa va passata per riferimento normale (solo con l'operatore &, senza const).

    Comunque la direttiva #define, se non ricordo male, viene sconsigliata nel libro Effective C++: 50 Specific Ways to Improve Your Programs and Design (di Scott Meyers). Consigliava di utilizzare comunque const (come variabile globale, quindi fuori dal corpo di qualsiasi funzione) per definire delle costanti globali (non mi ricordo i motivi però!).

  8. #8
    Originariamente inviato da RooccoXXI
    Comunque la direttiva #define, se non ricordo male, viene sconsigliata nel libro Effective C++: 50 Specific Ways to Improve Your Programs and Design (di Scott Meyers). Consigliava di utilizzare comunque const (come variabile globale, quindi fuori dal corpo di qualsiasi funzione) per definire delle costanti globali (non mi ricordo i motivi però!).
    Il #define è una sostituzione di testo "forza bruta" attuata dal precompilatore; le "variabili" const invece sono direttive del linguaggio comprese dal compilatore ed integrate nel linguaggio, il che significa ad esempio che le costanti hanno uno scope, possono essere inizializzate in base a parametri di template, e così via.
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    se però chiami una funzione che fa uso di un parametro costituito da array, allora questo ti verrà passato in automatico per riferimento, e non sarà in alcun modo possibile farlo passare per valore!

  10. #10
    Originariamente inviato da RooccoXXI
    No, è il contrario di quello che hai appena scritto. L'operatore & serve a passare la variabile per riferimento (modifiche permanenti!), mentre se lo lasci via la variabile viene passata per valore (quindi copiata prima di essere passata alla funzione e le modifiche rimangono solo all'interno della funzione).
    Hai ragione :P
    Originariamente inviato da RooccoXXI
    La storia del const è legata all'efficienza e alla sicurezza.
    Passando una variabile per valore hai il vantaggio che il valore originale della variabile non viene modificato, però questo richiede una copia; nel caso di tipi fondamentali questa copia è veloce, ma nel caso di oggetti di grosse dimensioni può compromettere seriamente l'efficienza del programma.
    Passando per valore hai il vantaggio che la variabile non viene copiata (quindi niente tempo di copia!) ma però potrebbe essere modificata accidentalmente.
    L'utilizzo di const con la chiamata per riferimento mette assieme i due vantaggi, eliminando gli svantaggi: la variabile non viene copiata (quindi efficenza!) ma la parola chiave const non ti permette di fare modifiche alla variabile (così da non modificare accidentalmente il valore originale). Questo sempre se NON devi/vuoi modificare il valore della variabile. Se ti serve che la funzione cambi il valore della variabile allora questa va passata per riferimento normale (solo con l'operatore &, senza const).
    Ora è chiaro, è una questione di ottimizzazione.
    Originariamente inviato da MItaly
    Il #define è una sostituzione di testo "forza bruta" attuata dal precompilatore; le "variabili" const invece sono direttive del linguaggio comprese dal compilatore ed integrate nel linguaggio, il che significa ad esempio che le costanti hanno uno scope, possono essere inizializzate in base a parametri di template, e così via.
    Questo perché, usando #define (ad esempio così: #define N 5) il precompilatore non fa altro che trovare tutte le occorrenze di N e sostituirle col valore 5, giusto? In pratica una const può essere "manipolata" un #define no.

    P.S. Ho fatto un programmino per provare un po di cose (tra cui sopratutto questa cosa del passaggio di argomenti a funzioni), va bene com'è o sbaglio qualcosa? (viene compilato senza né errori né warnings, e eseguito senza problemi)
    http://pastebin.com/hbWLKG7R
    SELECT neuroni FROM cervello
    WHERE status = 'funzionante';

    La query ha restituito: 0 risultati.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.