Strutture per rappresentare array dinamici

Gli array dinamici presentano una tipica situazione in cui servono più variabili per rappresentare lo stesso oggetto. Infatti, un array dinamico viene rappresentato come un puntatore che indica la zona di memoria in cui i dati sono memorizzati, e un numero che dice la grandezza dell'array, ossia il numero di elementi allocati.

Dal punto di vista della comodità di scrittura del codice, può risultare comodo utilizzare una sola variabile che contenga questi due dati. Usiamo quindi una struttura a due campi (i campi di una struttura sono la parti componenti delle variabili di tipo struttura). Il primo campo è il vettore stesso, ossia un puntatore al tipo che costituisce il vettore (per esempio, un intero); il secondo campo è un numero intero, che rappresenta il numero di elementi che sono stati allocati per il vettore. La dichiarazione della struttura è quindi la seguente:

struct ArrayDinamico {
  int *punt;
  int dim;
};

In questo modo, ogni volta che si dichiara una variabile struttura, questa è automaticamente composta da un puntatore a interi (quindi un vettore di interi) e da un intero.

Per dichiarare una variabile struttura, si usa una dichiarazione di tipo come segue:

  struct ArrayDinamico a;

Come si è detto prima, questa dichiarazione crea una variabile a.punt di tipo puntatore a intero, e una variabile a.dim di tipo intero.

Si noti che il valore di queste due variabili è completamente indipendente: possiamo anche per esempio allocare 100 elementi per il vettore e scrivere il numero 200 nella variabile intera. Questo è ammesso dal linguaggio, ma è un errore di programmazione, dal momento che la variabile viene usata per rappresentare appunto il numero di interi allocati per il vettore. Tutto questo vuole dire che è il programmatore che deve fare in modo che il campo dim contenga sempre il numero di elementi allocati per il vettore, e non è il calcolatore che automaticamente aggiorna questo valore.

Questo significa che, quando si alloca (malloc) oppure si rialloca (realloc) il vettore, occorre aggiornare anche il valore di a.dim che rappresenta il numero di elementi contenuti nel vettore.

Il seguente programma arraystruct.c definisce una variabile struttura a. Il vettore viene allocato, e vengono scritti alcuni valori al suo interno. Viene anche definita una funzione che stampa tutti gli elementi del vettore. Si noti che questa funzione usa sia il puntatore che la dimensione, ma viene chiamata passando semplicemente la variabile struttura.

/*
  Array dinamico definito come una struttura.
*/

#include<stdlib.h>

struct ArrayDinamico {
  int *punt;
  int dim;
};

void StampaVettore(struct ArrayDinamico x) {
  int i;

  for(i=0; i<=x.dim-1; i++)
    printf("%d ", x.punt[i]);

  printf("\n");
}

int main() {
  struct ArrayDinamico a;
  int i;

  a.dim=10;
  a.punt=malloc(10*sizeof(int));

  for(i=0; i<=5; i++)
    a.punt[i]=i*i;

  StampaVettore(a);

  return 0;
}