edutecnica

Vettori (array)

     

Un vettore è un insieme di elementi dello stesso tipo, distinti da un indice.

Esempi di sintassi:



tipo nomeVett[dim];
tipo nomeVett[] = {elementi};

dim è il numero di elementi del vettore.

Esempi



int k[10]; //vettore di 10 int
double x[] = {3.2, 9.4, 27.1}; //vettore di 3 double

Operazioni sui vettori

     

Sui vettori non sono possibili operazioni aritmetiche, né di confronto, né di assegnazione.
L’unica operazione consentita è l’accesso a un suo elemento mediante il corrispondente indice.

Esempi:



double x[] = {3.2, 9.4, 27.1};
double y = x[0];
x[0]=x[2]/2–x[1];

L’indice può essere costituito da una qualsiasi espressione intera e può variare tra 0 e dim -1, dove dim è la dimensione del vettore.

Esempio: minimo di un vettore



#include<iostream>
using namespace std;
int main(){
  int vettore[] = {7, 103, 12, 27, 5};
  int i, minimo;
  minimo = vettore[0];
  for(i = 1; i < 5; i++)
      if(vettore[i] < minimo) minimo = vettore[i];
  cout<<"Il minimo è "<<minimo<<endl;
}

Stringhe

     

Una stringa è un vettore di char, il cui ultimo elemento è il carattere NUL('\0').
L’inizializzazione di una variabile stringa si può effettuare utilizzando una costante stringa.

Esempio :

Char s[] = "Stringa";

La variabile s contiene 8 elementi:i 7 caratteri della costante stringa più il carattere NUL che viene inserito automaticamente.
Una variabile stringa è, a tutti gli effetti, un vettore. Pertanto, l’operazione di assegnazione è consentita solamente i fase di dichiarazione.

Input e output di stringhe

     

Le stringhe possono essere acquisite da tastiera mediante l'istruzione cin e visualizzate a schermo con l'istruzione cout.
cin
legge i caratteri dallo stream di ingresso e li memorizza in sequenza nella stringa finchè non incontra uno "spazio bianco" (che non viene letto).
Quest’ultimo causa la fine dell’operazione e la memorizzazione nella stringa stringa del carattere NUL dopo l’ultimo carattere valido.
cout
scrive in sequenza i caratteri della stringa (escluso quello terminatore) sull’uscita standard, normalmente il video.

Esempi di input e output di stringhe



char s[80];
cin >> s; //acquisisce s
cout << s; //visualizza s

Per acquisire anche gli "spazi bianchi" e terminare l’acquisizione con INVIO o al raggiungimento di un prefissato numero di caratteri, si deve usare il metodo getline():

cin.getline(s, 80);

Il numero massimo di caratteri acquisibili è quello indicato dopo il nome della stringa diminuito di 1, ovvero, nell’esempio, 79.
Nell’ottantesimo sarà automaticamente memorizzatoli carattere NUL.

Vettori multidimensionali (matrici)

     

Gli elementi di un vettore possono essere di tipo scalare o aggregato, vettori compresi. In questo secondo caso si parla di vettori multidimensionali o matrici.

Esempi di sintassi :



tipo vett[dim1][dim2]. . .[dimn];
tipo vett[]…[dimn] = {elementi};

dimi è il numero di elementi del vettore i-esimo. n è il numero di dimensioni: se vale 2 si parla di vettori bidimensionali, se vale 3 di vettori tridimensionali e così via.

Esempio :

int a[10][30];

In questo esempio la variabile a è stata dichiarata come un vettore di 10 elementi che a loro volta sono vettori, ciascuno costituito da 30 int.
In altre parole, a è una matrice costituita da 10 righe e 30 colonne i cui elementi sono int.

double x[][3] = {
{3.2, 9.4, 27.1},
{5.8, 20.9, 6.9}
};

In questo caso x rappresenta un vettore bidimensionale di double inizializzato con i valori dell’elenco.
La prima dimensione coincide con il numero di righe dell’elenco di inizializzazione, che qui sono 2.

Vettori di stringhe

     

Un vettore di stringhe è un caso particolare di vettore multidimensionale. La seguente dichiarazione, per esempio:

char nome[10][20];

dichiarazione un vettore, nome, che può contenere 10 stringhe, ciascuna lunga al massimo 20 caratteri (compreso quello terminatore).
In questo caso, invece:

char cognome[][30] = {
"Bianchi",
"Rossi",
"Verdi"
}

Si è dichiarato un vettore, cognome, inizializzato con 3 stringhe. Ognuna può essere lunga al massimo 30 caratteri (terminatore compreso). Per fare riferimento a una stringa di questi vettori si indica solo il primo indice. Per esempio, la stringa "Rossi" corrisponde a cognome[1].

Funzioni con vettori come parametri

     

Una funzione può avere, come parametro formale, un vettore. La sintassi di questo parametro è uguale a quella della dichiarazione del vettore corrispondente. Il seguente prototipo, per esempio, dichiara una funzione in cui il primo parametro è un vettore di int:

int somma(int v[], int n);

La dichiarazione della prima dimensione del vettore non è necessaria (ma le parentesi quadre si).
Nel caso di vettori di vettori multidimensionali o vettori di stringhe occorre dichiarare le successive dimensioni:

int tabella(char s[][50], int i);

Il parametro s è un vettore di stringhe.

Passaggio di vettori a funzioni

     

Quando si chiamano funzioni che hanno vettori come parametri, nella lista degli argomenti attuali si deve indicare solo il nome del vettore, senza dimensioni (qualunque esse siano). Nel caso delle due funzioni degli esempi precedenti:

tot = somma(dati, 30);
car = tabella(elenco, 50);

dove dati è un vettore di int ed elenco un vettore di stringhe. Alla funzione chiamata non vengono passati tutti gli elementi del vettore ma solamente l'indirizzo del primo elemento. Dato che questi sono memorizzati in locazioni di memoria consecutive, il compilatore ha tutte le informazioni necessarie a individuare ogni elemento.

Esempi di funzioni con stringhe



// Lunghezza di una stringa
int lunghezza(char s[]){
  unsigned i = 0;
  while (s[i] != '\0')
  i++;
  return i;
}
// Copia di stringhe: d = s
void copia(char d[], char s[]){
  unsigned i = 0;
  while (s[i++] != '\0') d[i] = s[i];
  d[i] = '\0';
}

Si noti che in questo caso l'argomento corrispondente al parametro formale d della funzione copia sarà modificato. Ciò è dovuto al particolare meccanismo di passaggio dei vettori (per riferimento anziché per valore). Per evitare modifiche accidentali di vettori passati a una funzione, occorre dichiarare il corrispondente parametro formale come const.

Funzioni standard con stringhe

     

Le seguenti chiamate impiegano funzioni della Libreria Standard che operano su stringhe. I loro prototipi sono contenuti nell'header file <cstring>.
Gli argomenti s (sorgente) e d (destinazione) sono stringhe.

// copia s in d (d = s)
strcpy(d, s);
//aggiunge s al termine di d
strcat(d, s);
// confronta s con d
strcmp(s, d)

Il valore restituito è:
negativo, se s è alfabeticamente minore di d;
zero, se s e d sono uguali;
positivo, se s è alfabeticamente maggiore di d:

// calcola la lunghezza di s
strlen(s);

Il valore restituito è il numero di caratteri che compongono s, escluso il carattere terminatore.

Tipi enumerativi

     

Un tipo enumerativo è un insieme di costanti intere, definite dal programmatore, ognuna delle quali è associata a un identificatore.

Sintassi


enum tag (enum1, enum2, ..., enum);

Se tag è presente, la dichiarazione è anche una definizione di tipo. In questo caso si possono dichiarare altre variabili di quel tipo mediante la seguente sintassi:

tag identificatore;

Ai nomi tra parentesi graffe sono automaticamente assegnati dei valori interi compresi tra 0 e n-1 in base al loro ordine: 0 al primo, n-1 all'ultimo. Questa successione naturale può essere modificata assegnando altri valori interi, ma solo all'interno della dichiarazione.

Esempi di enumerazioni

     

enum Giorno { LUN, MAR, MER, GIO, VEN, SAB, DOM };

Alle costanti da LUN a DOM sono automaticamente assegnati i valori interi da 0 a 6.

Giorno oggi = LUN;

Definizione di una variabile enumerata, oggi, inizializzata con il valore LUN:

oggi = 0; // ERRORE!

Non è possibile assegnare direttamente valori di altro tipo a variabili enumerate. Queste operazioni sono permesse solo mediante cast espliciti:

oggi = Giorno(0);
enum Colore { BIANCO, ROSSO, GIALLO = 10, BLU };

Le costanti BIANCO e ROSSO valgono, rispettivamente 0 e 1. GIALLO ha un valore definito dall'utente, 10, e BLU quello subito successivo, 11.

Strutture

     

Una struttura è un insieme di elementi che possono essere di tipo diverso e distinti da un nome. Ogni elemento è detto campo o membro della struttura.

Esempio di sintassi:

struct tag {
tipo1, campo1;
tipo2, campo2;
...
tipon campon;
} identificatore1;

identificatore1 è il nome di una "variabile struttura".
Se tag è presente, la dichiarazione è anche la definizione di un nuovo tipo, di nome tag.
In questo caso è possibile dichiarare altre variabili di quel tipo con la semplice sintassi:

tag identificatore2;

Esempi di strutture :

struct Data {
int giorno, mese, anno;
};
struct Persona {
char nome[20];
char cognome[30];
Data dataNascita;
char luogoNascita[30];
unsigned altezza;
} candidato;

Si noti che all'interno di una struttura ci possono essere campi di tipo aggregato, comprese altre strutture. Per accedere ai campi di una struttura si può usare l'operatore punto (.). Per esempio, per assegnare un valore al campo altezza della variabile struttura candidato si può scrivere:

candidato.altezza = 182;

Assegnazione di strutture

     

L'unica operazione possibile tra variabili struttura è l'assegnazione. Tutti i valori dei campi della struttura a destra dell'operatore = sono assegnati ai corrispondenti campi della struttura a sinistra.

Esempio :

struct Complesso {
double re, double im;
};
Complesso c1, c2;

c1.re = -3.2; c1.im = 9.4;
c2 = c1; // Assegnazione

Assegnazione di vettori tramite struct

     

Le strutture possono essere assegnate, i vettori no. Per copiare un vettore in un altro senza farlo elemento per elemento, lo si può incapsulare, come campo, all'interno di una struttura.

Esempio :

struct Temp {
double t[100];
};

Temp interno, esterno;
for(unsigned = 0; i < 100; i++)
interno.t[i] = i;

// copia indiretta del vettore t
esterno = interno;

Dopo la copia della struttura, i valori degli elementi del vettore t, membro della struttura esterno, coincideranno con quelli del vettore t di interno.

Unioni

     

Le unioni servono a memorizzare nella stessa variabile valori di tipo diverso. La dichiarazione di un'unione ha la stessa sintassi di quella di una struttura, con l'unica eccezione della keyword union al posto di struct.
Come per le strutture, l'accesso a un valore di una variabile di tipo union può avvenire mediante l'operatore punto.

Diversamente dalle strutture, un'unione occupa lo spazio necessario a memorizzare il suo campo più grande e può memorizzare solo un valore alla volta.

Esempio di union :

union Var {
char s[201:
int i;
double d;
};
// Due variabili union
Var v1, v2 = ("Giorgio"); // contiene 1 stringa
v1.i = 1:
cout << v1.i << '\t' << v2.s << endl;
v2.i = v1.i; // v2 ora contiene un int
v2.d = 9.81; // v2 ora contiene un double
cout << v2.d << endl; // Ok
cout << v2.i << endl;
/* Attenzione! v2 contiene un double ma viene interpretato come int */