Indirizzo, byte occupati e valore di una variabile

  1. variabile = insieme di celle consecutive
  2. per sapere quali celle sono occupate da una variabile, ci basta sapere quante sono e l'indirizzo della prima
  3. ci sono casi in cui serve sapere queste cose
  4. operatori & e sizeof
  5. indirizzo e numero di byte si possono anche stampare
  6. differenza fra valore e indirizzo
  7. sizeof dipende solo dal tipo; per questa ragione, si può usare anche sul tipo

Le variabili C sono zone di memoria. In altre parole, ogni variabile è un insieme di locazioni all'interno della memoria. Il numero di byte occupati da una variabile dipende dal suo tipo: un intero occupa quattro posizioni, un carattere una posizione, un double otto, ecc.

Se vogliamo sapere quali byte una variabile occupa, ci servono due numeri: il primo è la posizione del primo byte occupato, il secondo è il numero di byte occupati. Il primo numero viene detto indirizzo della variabile. Se per esempio la variabile a occupa in memoria le posizioni dalla 1243 alla 1247, allora il suo indirizzo è il primo di questi numeri, cioè 1243; questa variabile occupa quattro locazioni, quindi il numero di byte occupati da a è 4.

Nei programmi fatti fino a questo momento, non era necessario sapere quali celle una variabile occupa. Esistono però delle situazioni in cui è invece necessario. Per questo, il C mette a disposizione delle primitive che permettono di trovare l'indirizzo e il numero di byte occupati dalle variabili. Queste nozioni sono necessarie per esempio nel caso in cui il programma deve gestire un numero di dati non noto a priori, come si vedrà a proposito degli array e delle liste.

indirizzo
per sapere l'indirizzo di una variabile si usa l'operatore unario &; in altre parole, se a è una variabile, allora &a è il suo indirizzo (la prima posizione di memoria occupata da essa);
numero di byte occupati
il numero di byte occupati da una variabile si trova con sizeof; quindi per esempio sizeof(a) è il numero di byte occupati dalla variabile a.

Il programma seguente dichiara tre variabili di diversi tipi, assegna dei valori, e poi stampa i loro indirizzi e il numero di byte che occupano. Da notare che l'indirizzo di una variabile, cosí come il numero di byte occupati, sono dei normali numeri, e si possono quindi stampare. Nel caso dell'indirizzo, si è scelto di stamparlo in esadecimale (usando %x) ma anche la stampa in decimale avrebbe funzionato (da notare che gli indirizzi sono numeri unsigned, e quindi è comunque più appropriato stamparli usando %u che %d).

/*
  Stampa indirizzo, occupazione di memoria e valore
  di alcune variabili.
*/

int main(void) {
  int a;
  char b;
  float c;

  a=12;
  b='a';
  c=0.1243;

  printf("L'indirizzo di a e' %x, occupa %d bytes, il suo valore e' %d\n",
         &a, sizeof(a), a);

  printf("L'indirizzo di b e' %x, occupa %d bytes, il suo valore e' %c\n",
         &b, sizeof(b), b);

  printf("L'indirizzo di c e' %x, occupa %d bytes, il suo valore e' %f\n",
         &c, sizeof(c), c);


  return 0;
}

È importante notare la differenza tra il valore di una variabile e il suo indirizzo. L'indirizzo di una variabile è l'inizio della zona di memoria occupata da una variabile, mentre il valore di una variabile è il contenuto di tale zona.

Altra osservazione: tutte la variabili di un certo tipo occupano esattamente lo stesso numero di byte. Quindi, se a e x sono interi, si può essere certi che sizeof(a) è uguale a sizeof(x). Per questa ragione, sizeof è stata definita in modo che possa avere come parametro sia il nome di una variabile che il nome di un tipo. È quindi possibile per esempio calcolare e stampare il valore di sizeof(int), che coincide necessariamente con i valori di sizeof di ogni variabile di tipo int.

Il programma dimensione.c stampa il numero di byte occupati dalle variabili di vari tipi di dato. Il numero di byte occupati da un tipo di dato può cambiare passando a calcolatori di tipo diverso. Per esempio, un intero può occupare due, oppure quattro, oppure otto byte a seconda del tipo di calcolatore/sistema operativo/compilatore usato.

/*
  Spazio occupato da variabili di un certo tipo.
*/

int main() {

  printf("Il tipo int occupa %d bytes\n", sizeof(int) );

  printf("Il tipo char occupa %d bytes\n", sizeof(char) );

  printf("Il tipo float occupa %d bytes\n", sizeof(float) );

  printf("Il tipo double occupa %d bytes\n", sizeof(double) );

  return 0;
}