Dubbio semplice procedura in C

ELWOOD1
Ciao a tutti,
riguardo a questa semplice procedura in C non mi capacito del fatto che mi restituisce i valori che chiedo.

Si tratta semplicemente dello scambio di 2 variabili intere:

#include<stdio.h>
#include<stdlib.h>

void scambia(int x, int y);


main() {
int a,b;

printf("Inserire il valore di a:");
scanf("%d",&a);       
printf("Inserire il valore di b:");
scanf("%d",&b);       

scambia(a,b);

printf("I nuovi valori sono a=%d e b=%d\n\n",a,b);
       

system("PAUSE");
}


void scambia(int x, int y) {
int temp;
temp=x;
x=y;
y=temp;
}




Mentre se al posto delle variabili intere utilizzo i puntatori allora la procedura mi da il risultato corretto:


#include<stdio.h>
#include<stdlib.h>

void scambia(int *x, int *y);


main() {
int a,b;

printf("Inserire il valore di a:");
scanf("%d",&a);       
printf("Inserire il valore di b:");
scanf("%d",&b);       

scambia(&a,&b);

printf("I nuovi valori sono a=%d e b=%d",a,b);
       

system("PAUSE");
}


void scambia(int *x, int *y) {
int temp;
temp=*x;
*x=*y;
*y=temp;
}


Come mai??

Risposte
claudio862
Perché in C i parametri delle funzioni sono passati sempre per copia.

...
int a = 2;
f(a); // Una *copia* di 'a' viene passata alla funzione 'f'.
int * pa = & a;
g(pa); // Una *copia* di 'pa' viene passata alla funzione 'g'.
...

void f(int b)
{
// 'b' è una variabile locale a 'f', non è legata ad 'a'.
// È uguale ad 'a' ma non è la stessa variabile.
// Modifiche a 'b' non si ripercuotono su 'a'.
}

void g(int * pb)
{
// 'pb' è una variabile locale a 'g', non è legata ad 'pa'.
// È uguale ad 'pa' ma non è la stessa variabile.
// Modifiche a 'pb' non si ripercuotono su 'pa'.
}


Però dato che 'pa' e 'pb' sono puntatori e sono identici, puntano alla stessa memoria. Quindi se dentro g() modifichi la memoria puntata da 'pb' automaticamente si modifica anche la memoria puntata da 'pa' (perché si tratta della stessa memoria).

ELWOOD1
Cioè, se ho capito bene il fatto di effettuare la procedura al di fuori del main con le variabili intere non ne modifico il loro contenuto.

Mentre se utilizzo i puntatori vado a modificarne la posizione di memoria e quindi anche il contenuto...

ci sono?

claudio862
Quando tu chiami una funzione:

void fun(ABC nome)
{
...
}

...

// Chiama la funzione
ABC a;
fun(a);

viene creata una nuova variabile di tipo 'ABC' interna alla funzione fun() e ci viene copiato dentro il valore specificato. Quindi le modifiche fatte a 'nome' dentro la funzione fun() non influenzano il valore di 'a'. Qualsiasi tipo sia ABC. Se ABC è un puntatore a int (cioè ABC == int*) il discorso è lo stesso. Ma un puntatore contiene un indirizzo di memoria, e la memoria è comune a tutto il programma. Quindi fun() non può modificare l'indirizzo di memoria che le è stato passato, ma può modificare la memoria a quell'indirizzo.

Per farti un esempio concreto abbastanza stupido: i parametri sono dei fogli. Quando chiami una funzione tu fai una fotocopia del tuo foglio e glie la passi. La funzione può fare quello che vuole della sua copia, ma la tua non può modificarla. Se però il contenuto dei due fogli è un numero di schedario (~ un indirizzo di memoria) allora la funzione può andare allo schedario e modificare la cartella specificata, e la modifica è visibile anche a te. Perché lo schedario (~ la memoria) è comune a tutto il programma.

ELWOOD1
Ottima definizione, semplice ed intuitiva.
Per cui qualsiasi modifica effettuata all'interno della funzione col parametro puntatore, al momento dell'esecuzione della funzione/procedura verrà modificata anche qualsiasi variabile associata a quel tipo di puntatore?

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.