allora supponiamo di avere questo main
codice:
int main()
{
  int a = 10, b = 20;
  moltiplica(a, b);

  return 0;
}
i parametri che si passano alla funzione ("a" e "b") vengono detti parametri attuali

invece i parametri che compaiono nella definizione della funzione
codice:
int moltiplica(int a, int b)
{
  return a*b;
}
sono detti parametri formali

nel passaggio per valore, i parametri formali sono memorizzati in locazioni di memoria diverse da quelle dei paramtri attuali
cioè nel momento in cui entro nel corpo della funzione, vengono "allocati" i parametri formali, (di fatto sono nuove variabili)

questa funzione
codice:
int moltiplica(int x, int y)
{
  return x*y;
}
è identica a quella precedente perchè anche in questo caso vengono allocate 2 variabili nuove (come prima)
il cui contenuto è la copia dei paramtri attuali


di solito per capire questo concetto si parla dei record di attivazione (stack)

la funzione moltiplica la modifico per farti capire come funziona il passaggio per valore

codice:
la freccia <-- indica il punto in cui si trova l'esecuzione del processo (programma)

int main()
{
  int a = 10, b = 20, c;
  c = moltiplica(a, b);<-- 

  return 0;
}

lo stack è questo
----------
|  main  |
----------
| a | 10 |
| b | 20 |
| c | ?? |
----------

successivamente viene richiamata la funzione

int moltiplica(int x, int y) 
{<--
  x = x * 10;
  return x*y;
}

e questo è lo stack, in cui le variabili locali sono x e y
le variabili a e b non sono accessibili alla funzione moltiplica (perchè non sono variabili globali)
--------------
| moltiplica | 
|------------|
|  x  |  10  |
|  y  |  20  |
--------------
|    main    |
--------------
|  a  |  10  |
|  b  |  20  |
|  c  |  ??  |
--------------


int moltiplica(int x, int y) 
{
  x = x * 10; 
  return x*y; <--
}

lo stack (N.B. "a" non è stata modificata)
--------------
| moltiplica | 
|------------|
|  x  | 100  |
|  y  |  20  |
--------------
|    main    |
--------------
|  a  |  10  |
|  b  |  20  |
|  c  |  ??  |
--------------


int main()
{
  int a = 10, b = 20, c;
  c = moltiplica(a, b);

  return 0; <-- 
}

lo stack è ora questo
--------------
|    main    |
--------------
|  a  |   10 |
|  b  |   20 |
|  c  | 2000 |
--------------
ora se al posto di quella moltiplica metti
codice:
int moltiplica(int a, int b)
{<--
  a = a * 10;
  return a*b;
}

lo stack è
--------------
| moltiplica | 
|------------|
|  a  |  10  |
|  b  |  20  |
--------------
|    main    |
--------------
|  a  |  10  |
|  b  |  20  |
|  c  |  ??  |
--------------

int moltiplica(int a, int b) 
{
  a = a * 10; 
  return a*b; <--
}

lo stack (N.B. "a" del main non è stata modificata)
--------------
| moltiplica | 
|------------|
|  a  | 100  |
|  b  |  20  |
--------------
|    main    |
--------------
|  a  |  10  |
|  b  |  20  |
|  c  |  ??  |
--------------


int main()
{
  int a = 10, b = 20, c;
  c = moltiplica(a, b);

  return 0; <-- 
}

lo stack è ora questo
--------------
|    main    |
--------------
|  a  |   10 |
|  b  |   20 |
|  c  | 2000 |
--------------
ecco perchè le funzioni sono "identiche"