Delucidazioni funzioni c++

Messaggioda michele1239 » 02/03/2017, 10:16

Buongiorno ragazzi, ho alcuni dubbi sull'uso delle funzioni in c++
1)qual è la differenza tra sostituzione per valore e sostituzione per riferimento?
2)perchè gli array non possono essere passati per riferimento?
3)perchè negli array bidimensionali bisogna specificare solo la grandezza della seconda dimensione?
4)perchè si usano i prototipi di funzioni?ho capito che bisogna dichiarare i prototipi per evitare un side effect, ciò che non mi è chiaro è il motivo per il quale senza i prototipisi avrebbe un funzionamento non corretto del nostro programma.
scusate per il disturbo.
michele1239
Starting Member
Starting Member
 
Messaggio: 12 di 32
Iscritto il: 11/12/2016, 15:05

Re: Delucidazioni funzioni c++

Messaggioda Luc@s » 02/03/2017, 11:21

Pensala a livello di business deal
Il prototipo e' un contratto.
Senza contratto come puoi dire cosa e' valido e cosa no?
----
Luca Francesca <[email protected]>
System Engineer Lead @ Salesforce

Info: https://www.linkedin.com/in/lucafrancesca/
Luc@s
Senior Member
Senior Member
 
Messaggio: 1481 di 1955
Iscritto il: 01/05/2006, 17:21
Località: Irlanda

Re: Delucidazioni funzioni c++

Messaggioda michele1239 » 02/03/2017, 11:45

si più o meno mi è chiaro
dobbiamo anticipare al compilatore quali funzioni andremo ad usare, giusto?
michele1239
Starting Member
Starting Member
 
Messaggio: 13 di 32
Iscritto il: 11/12/2016, 15:05

Re: Delucidazioni funzioni c++

Messaggioda Luc@s » 02/03/2017, 11:46

Nei file .h di solito.
----
Luca Francesca <[email protected]>
System Engineer Lead @ Salesforce

Info: https://www.linkedin.com/in/lucafrancesca/
Luc@s
Senior Member
Senior Member
 
Messaggio: 1482 di 1955
Iscritto il: 01/05/2006, 17:21
Località: Irlanda

Re: Delucidazioni funzioni c++

Messaggioda michele1239 » 02/03/2017, 11:49

per quanto riguarda la prima domanda un mio compagno di corse ha dato la seguente risposta:
quando "lavori" per valore "lavori" su una copia, mentre se "lavori" per riferimento alla fine della funzione il valore cambia.
E' corretta come risposta?(anche se un po' semplicistica)
michele1239
Starting Member
Starting Member
 
Messaggio: 14 di 32
Iscritto il: 11/12/2016, 15:05

Re: Delucidazioni funzioni c++

Messaggioda Luc@s » 02/03/2017, 11:51

A livello base si.
Il riferimento non copia e' abbastanza vero
----
Luca Francesca <[email protected]>
System Engineer Lead @ Salesforce

Info: https://www.linkedin.com/in/lucafrancesca/
Luc@s
Senior Member
Senior Member
 
Messaggio: 1483 di 1955
Iscritto il: 01/05/2006, 17:21
Località: Irlanda

Re: Delucidazioni funzioni c++

Messaggioda michele1239 » 02/03/2017, 11:54

Luc@s ha scritto:A livello base si.
Il riferimento non copia e' abbastanza vero

okok grazie mille
michele1239
Starting Member
Starting Member
 
Messaggio: 15 di 32
Iscritto il: 11/12/2016, 15:05

Re: Delucidazioni funzioni c++

Messaggioda Giux » 02/03/2017, 12:47

michele1239 ha scritto:1)qual è la differenza tra sostituzione per valore e sostituzione per riferimento?


Sarebbe più corretto dire passaggio per valore e passaggio per riferimento, in ogni caso
Quando passi un dato per valore ad una funzione(di solito è l'approccio standard del C++) in realtà
stai operando con una copia del dato stesso nel contesto di una funzione, quindi tutto cio che farai con il parametro
non avrà ripercussioni sul dato originale

Se invece passi un riferimento con l'aggiunta dell'operatore $&$ oppure (se usi lo stile C)
e passi dei puntatori espliciti con l'operatore * stai passando proprio l'indirizzo dell'area di memoria in cui è stata allocata la variabile, di conseguenza se agisci sulla variabile stai modificando (per aliasing) il dato originale

Esempio di passaggio per valore
in questo caso lo cambio avviene localmente nella funzione
quindi x ed y nel main rimangono tali
Codice:
int swap(int a, int b){
   int temp = a;
   a = b;
   b = temp;
}

int main(void)
{
   int x = 3, y = 4;
   swap(x, y); // sto passando una copia di x ed y
   return 0;
}



In questo caso il compilatore si aspetta dei puntatori
quindi la funzione opera direttamente con le variabili x ed y del main
che risultano scambiate correttamente
Codice:
int swap(int *a, int *b){
   int temp = *a;
   *a = *b;
   *b = temp;
}

int main(void)
{
   int x = 3, y = 4;
   swap(&x, &y); // sto passando un riferimento di x ed y
   return 0;
}


michele1239 ha scritto:2)perchè gli array non possono essere passati per riferimento?


Il discordo degli array è un po complicato per via di alcune sottigliezze che il C++ ha ereditato dal C
Come saprai il nome di un array in C ed anche in C++ corrisponde all'indirizzo della prima cella dell'array stesso
(questo perchè in memoria gli array vengono memorizzati in locazioni contigue, e quindi si puo far uso dell'aritmetica dei puntatori in modo naturale e semplice) tuttavia
Quando passi un array ad una funzione gli stai passando una copia dell'indirizzo della prima cella. Quindi qui bisogna fare attenzione: gli array vengono passati implicitamente per riferimento(inteso come copia del puntatore alla prima cella dell'array).

michele1239 ha scritto:3)perchè negli array bidimensionali bisogna specificare solo la grandezza della seconda dimensione?


Per come ti dicevo sopra gli array come le matrici(che sono sempre array, però multidimensionali) vengono
memorizzati in memoria in celle contigue( praticamente la matrice è come se venisse allocata una riga dopo l'altra a partire dalla riga $0$, e proseguendo fino alla riga $n-1$)
Ebbene, ora il compilatore necessita per allocare correttamente la memoria di almeno $n-1$ dimensioni del tuo array
e nel caso delle matrici gli serve il numero delle colonne(per poter determinare quanto è grande una riga)
Questo perchè dietro le quinte l'aritmetica dei puntatori fa uso solo della dimensione delle righe, cioè del numero di colonne
che corrisponde alla seconda dimensione dell'array

michele1239 ha scritto:4)perchè si usano i prototipi di funzioni?ho capito che bisogna dichiarare i prototipi per evitare un side effect, ciò che non mi è chiaro è il motivo per il quale senza i prototipi si avrebbe un funzionamento non corretto del nostro programma.
scusate per il disturbo


Il discorso dei prototipi è storico nel C quindi nel C++ . Sono stati introdotti principalmente per
ridurre gli errori nel passaggio degli argomenti e per gestire i programmi di grandi dimensioni ma anche per motivi di efficienza nella compilazione.

Se definisci una funzione prima del main il programma dovrebbe andar bene lo stesso( e questo dipende dalla versione del tuo compilatore), in ogni caso è buona prassi dichiarare le funzioni mediante i prototipi perchè questo aiuta il compilatore
ad effettuare il debug alla ricerca di eventuali incongruenze nel passaggio dei parametri, e soprattutto quando più funzioni si chiamano tra loro. Il fatto che va in errore probabilmente è dovuto alle nuove restrizioni dei compilatori per le nuove versioni del C++... Infine il prototipo viene impiegato anche per gestire per l'overloading(sovraccarico) delle funzioni (cioè quando hai delle funzioni con lo stesso nome, ma con parametri differenti) le cosiddette "signature"

P.S. Nessun disturbo se vuoi altri chiarimenti, scrivi pure :-D
La matematica è la regina delle scienze e la teoria dei numeri è la regina della matematica.
(Carl Friedrich Gauss)
Avatar utente
Giux
Average Member
Average Member
 
Messaggio: 162 di 517
Iscritto il: 01/10/2012, 09:49

Re: Delucidazioni funzioni c++

Messaggioda michele1239 » 02/03/2017, 13:27

Giux ha scritto:
michele1239 ha scritto:1)qual è la differenza tra sostituzione per valore e sostituzione per riferimento?


Sarebbe più corretto dire passaggio per valore e passaggio per riferimento, in ogni caso
Quando passi un dato per valore ad una funzione(di solito è l'approccio standard del C++) in realtà
stai operando con una copia del dato stesso nel contesto di una funzione, quindi tutto cio che farai con il parametro
non avrà ripercussioni sul dato originale

Se invece passi un riferimento con l'aggiunta dell'operatore $&$ oppure (se usi lo stile C)
e passi dei puntatori espliciti con l'operatore * stai passando proprio l'indirizzo dell'area di memoria in cui è stata allocata la variabile, di conseguenza se agisci sulla variabile stai modificando (per aliasing) il dato originale

Esempio di passaggio per valore
in questo caso lo cambio avviene localmente nella funzione
quindi x ed y nel main rimangono tali
Codice:
int swap(int a, int b){
   int temp = a;
   a = b;
   b = temp;
}

int main(void)
{
   int x = 3, y = 4;
   swap(x, y); // sto passando una copia di x ed y
   return 0;
}



In questo caso il compilatore si aspetta dei puntatori
quindi la funzione opera direttamente con le variabili x ed y del main
che risultano scambiate correttamente
Codice:
int swap(int *a, int *b){
   int temp = *a;
   *a = *b;
   *b = temp;
}

int main(void)
{
   int x = 3, y = 4;
   swap(&x, &y); // sto passando un riferimento di x ed y
   return 0;
}


michele1239 ha scritto:2)perchè gli array non possono essere passati per riferimento?


Il discordo degli array è un po complicato per via di alcune sottigliezze che il C++ ha ereditato dal C
Come saprai il nome di un array in C ed anche in C++ corrisponde all'indirizzo della prima cella dell'array stesso
(questo perchè in memoria gli array vengono memorizzati in locazioni contigue, e quindi si puo far uso dell'aritmetica dei puntatori in modo naturale e semplice) tuttavia
Quando passi un array ad una funzione gli stai passando una copia dell'indirizzo della prima cella. Quindi qui bisogna fare attenzione: gli array vengono passati implicitamente per riferimento(inteso come copia del puntatore alla prima cella dell'array).

michele1239 ha scritto:3)perchè negli array bidimensionali bisogna specificare solo la grandezza della seconda dimensione?


Per come ti dicevo sopra gli array come le matrici(che sono sempre array, però multidimensionali) vengono
memorizzati in memoria in celle contigue( praticamente la matrice è come se venisse allocata una riga dopo l'altra a partire dalla riga $0$, e proseguendo fino alla riga $n-1$)
Ebbene, ora il compilatore necessita per allocare correttamente la memoria di almeno $n-1$ dimensioni del tuo array
e nel caso delle matrici gli serve il numero delle colonne(per poter determinare quanto è grande una riga)
Questo perchè dietro le quinte l'aritmetica dei puntatori fa uso solo della dimensione delle righe, cioè del numero di colonne
che corrisponde alla seconda dimensione dell'array

michele1239 ha scritto:4)perchè si usano i prototipi di funzioni?ho capito che bisogna dichiarare i prototipi per evitare un side effect, ciò che non mi è chiaro è il motivo per il quale senza i prototipi si avrebbe un funzionamento non corretto del nostro programma.
scusate per il disturbo


Il discorso dei prototipi è storico nel C quindi nel C++ . Sono stati introdotti principalmente per
ridurre gli errori nel passaggio degli argomenti e per gestire i programmi di grandi dimensioni ma anche per motivi di efficienza nella compilazione.

Se definisci una funzione prima del main il programma dovrebbe andar bene lo stesso( e questo dipende dalla versione del tuo compilatore), in ogni caso è buona prassi dichiarare le funzioni mediante i prototipi perchè questo aiuta il compilatore
ad effettuare il debug alla ricerca di eventuali incongruenze nel passaggio dei parametri, e soprattutto quando più funzioni si chiamano tra loro. Il fatto che va in errore probabilmente è dovuto alle nuove restrizioni dei compilatori per le nuove versioni del C++... Infine il prototipo viene impiegato anche per gestire per l'overloading(sovraccarico) delle funzioni (cioè quando hai delle funzioni con lo stesso nome, ma con parametri differenti) le cosiddette "signature"

P.S. Nessun disturbo se vuoi altri chiarimenti, scrivi pure :-D


grazie mille, sei stato molto chiaro!
michele1239
Starting Member
Starting Member
 
Messaggio: 16 di 32
Iscritto il: 11/12/2016, 15:05

Re: Delucidazioni funzioni c++

Messaggioda axpgn » 02/03/2017, 14:48

Scusami, ma mi spieghi perché per ringraziare hai citato tutto il (lungo) post (per giunta) precedente?
axpgn
Cannot live without
Cannot live without
 
Messaggio: 7497 di 40654
Iscritto il: 20/11/2013, 22:03


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite