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
La matematica è la regina delle scienze e la teoria dei numeri è la regina della matematica.
(Carl Friedrich Gauss)