Vettori parzialmente utilizzati

Nel precedente esercizio si è visto come sia possibile usare le strutture per memorizzare puù dati riguardanti lo stesso oggetto. In particolare, usiamo una struttura per memorizzare un vettore dinamico e la sua dimensione. È però facile rendersi conto che questi due dati non sono sufficienti nel caso in cui solo una parte del vettore contiene dei valori significativi. In questo caso, serve un terzo campo che indica il numero di elementi significativi del vettore.

Il programma parziale.c è una modifica del precedente, in cui la struttura contiene un terzo campo di tipo intero, di nome n, che contiene il numero di elementi significativi del vettore.

Anche in questo caso (come del resto nel precedente) è compito del programmatore garantire che il valore memorizzato in a.n sia effettivamente il numero di elementi significativi del vettore. Questo si puù realizzare mettendo inizialmente a 0 questa variabile; ogni volta che viene immesso un nuovo valore in a.punt[i], si va a vedere se sto creando un nuovo valore significativo oppure no. Questo non è difficile da controllare: infatti, se il vettore ha a.n elementi significativi, allora questi hanno indici 0, 1, ... , a.n-1. Quindi, se i è maggiore di a.n-1, allora sto mettendo un valore in una posizione che precedentemente non era significativa del vettore. Le nuove posizioni significative del vettore sono ora quelle di indici 0, 1, ... , i. Da questo segue che il nuovo valore di a.n deve essere tale che a.n-1 è uguale a a.i, per cui occorre assegnare a.n=i+1. Questo si può riassumere come segue:

elementi significativi prima: 0 1 2 3 ... a.n-1
elementi significativi dopo:  0 1 2 3 ... a.n-1 ... i

Questo significa che dopo l'assegnamento ho i+1 elementi significativi, e questo deve essere il nuovo valore di a.n.

Il programma completo è riportato qui sotto. È una versione modificata del precedente, in cui oltre a tenere il valore di a.dim pari al numero di elementi allocati per il vettore, metto in a.n il numero di elementi significativi.

/*
  Array dinamico definito come una struttura.
*/

#include<stdlib.h>

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

void StampaVettore(struct ArrayDinamico x) {
  int i;

  for(i=0; i<=x.n-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));
  a.n=0;

  for(i=0; i<=5; i++) {
    a.punt[i]=i*i;
    if(a.n<i+1)
      a.n=i+1;
  }

  StampaVettore(a);

  return 0;
}


Si noti che la dichiarazione di variabile, e la intestazione della procedura, sono rimaste inalterate. Uno dei vantaggi di usare una struttura al posto delle variabili separate è che in questo modo l'aggiunta di nuovi campi comporta del codice solo nei punti in cui questi nuovi campi vengono usati.