Consideriamo questa dualità su un esempio
int X[10]; int *PX;la situazione della memoria dopo queste dichiarazioni è come segue:
dove le celle di memoria (variabili/scatole) X[0], ..., X[9]
hanno indirizzi consecutivi, ed X è inteso come un modo per riferirsi a
X[0].
PX
è una variabile che può contenere un indirizzo di variabile
intera.
Si ha che valgono le seguenti identità
x == &x[0] &x[1] == (&x[0])+1 &x[2] == (&x[1])+1 ... &x[9] == (&x[8])+1Assumiamo di eseguire PX = &X[0];
e si ha che valgono
*(PX+1) == X[1] ... *(PX+9) == X[9]Ma poichè X non è una variabile, abbiamo che X = ...; è errato;
ESEMPIO
#include <stdio.h> main(){ int x[10] = {0,1,2,3,4,5,6,7,8,9}; int * px = NULL, z; px = &x[0]; px = px+1; if(x[1] == *px) printf("va bene \n"); else printf("va male\n"); if(x == &x[0]) printf("torna tutto \n"); else printf("qualcosa non va\n"); px = px +2; printf("il valore del contenuto di px e\' %d\n",*px); px = &x[0]; /*x = x+1; errore*/ z = px[3]; printf("il valore di px[3] e\' %d\n",z); /*z = (*px)[3]; errore*/ z = *(px+3); printf("il valore di *(px+3) e\' %d\n",z); }produrrà come output
va bene torna tutto il valore del contenuto di px e' 3 il valore di px[3] e' 3 il valore di *(px+3) e' 3
Una conseguenza di questa peculiarità del C riguarda i parametri delle funzioni di tipo array: come al solito sono parametri valori, ma i parametri di tipo array sono dei puntatori al primo elemento, quindi effettivamente essi sono dei parametri variabili.
Pertanto se volete un parametro valore di tipo array dovete controllare voi
di non modificarlo all'interno della funzione; se invece volete un
parametro variabile di tipo array, non dovete fare nulla (diversamente dal
caso di un parametro variabile di altri tipi, vedere qui).
Si consiglia di indicare con dei commenti quando un parametro di tipo
array è un valore e quando è una variabile.
ESEMPIO
#include <stdio.h> #define DIM 5 int VSum(int v[] /*valore*/, int dim) { int sum = 0, i; for(i=0; i < dim; i++) sum += v[i]; return sum; } int VSumP(int * pv, int dim) { int sum = 0, i; for(i=0; i < dim; i++) sum += *(pv+i); return sum; } void VPrint(int v[ ] /*valore*/, int dim) { int i; for(i=0; i < dim; i++) printf("%5d ",v[i]); printf("\n"); } void VPrintP(int * pv, int dim) { int i; for(i=0; i < dim; i++){ printf("%5d ",*pv); pv = pv+1; }; printf("\n"); } void VRead(int v[ ] /*variabile*/, int dim) { int i; for(i=0; i < dim; i++) scanf("%d",&v[i]); } void VReadP(int * pv, int dim) { int i; for(i=0; i < dim; i++) scanf("%d",pv+i); } main(){ int a[DIM] = {3,3,3,3,3}, b[DIM]; VPrint(a,DIM); VPrintP(a,DIM); VRead(b,DIM); VPrint(b,DIM); VReadP(b,DIM); VPrint(b,DIM); printf("La somma di a e\' %d.\n",VSum(a,DIM)); printf("La somma P di a e\' %d.\n",VSumP(&a[0],DIM)); printf("La somma di un postfisso di a (ultimi 2 elementi) e\' %d.\n",VSum(a+2,2)); printf("La somma P di un postfisso di a (ultimi 2 elementi) e\' %d.\n",VSumP(a+2,2)); }
ESERCIZIO