Array

Un array è un gruppo adiacente di locazioni di memoria, tutte dello stesso tipo. Per accedere ad un elemento si deve specificare il nome assegnato all'array e la posizione occupata dall'elemento all'interno dell'array. Il numero degli elementi che costituiscono l'array è un valore deciso al momento della dichiarazione.

Quindi un array è individuato da

La sintassi per dichiarare un array in C++ è la seguente:

 

tipo nome[dimensione];

 

Ad esempio un array, denominato elenco in grado di memorizzare 10 interi viene riservato con la seguente dicharazione:

int elenco[10];

che si legge: "elenco è un array di 10 interi".

La posizione occupata dagli elementi dell'array viene numerata assegnando al primo elemento la posizione numero 0. Quindi nell'esempio precedente i 10 elementi dell'array elenco occupano le posizioni da 0 a 9. Ad esempio al quinto elemento si accede con l'espressione elenco[4]

Come con tutte le variabili, anche per un array bisogna assegnare un valore iniziale a ciascun elemento. Un primo modo consiste nell'assegnare, subito dopo la dichiarazione, il valore a ogni elemento:

int elenco[4];

elenco[0] = 6;

elenco[1] = 0;

elenco[2] = 9;

elenco[9] = 6;

Un'altra tecnica consiste nell'inizializzare i valori dell'array durante la dichiarazione:

 

int elenco[10] = { 6, 0, 9, 42, 35, 12, 21, 18, 72, 6 };

 

Il compilatore, nell'interpretare la dichiarazione, è in grado di contare gli elementi e quindi di determinare anche la dimensione, per questo motivo, la terza tecnica consente di omettere a dimensione:

 

int elenco[] = { 6, 0, 9, 42, 35, 12, 21, 18, 72, 6 };

 

In questa dichiarazione il compilatore si fa carico di contare il numero di locazioni da riservare in memoria

Infine gli elementi dell'array possono essere inizializzati assegnando il valore da input:

#include <iostream>

  using namespace std;

 

int main() {

 

  int elenco[4];

  cout << "Scrivi 4 numeri (dopo ciascuno premi invio)" << endl;

 

  for(int i = 0; i < 4; i++)

    cin >> elenco[i];

 

    cout << "I valori presenti nell'array sono:";

 

  for(int i = 0; i < 4; i++)

    cout << " " << elenco[i];

 

  cout << endl;

 

  system("PAUSE");

  return 0;

}

L'indice dell'elemento a cui si vuole accedere deve essere un numero compreso tra 0 e N-1, dove N è la dimensione dell'array. L'indice deve essere fornito esplicitamente (es: elenco[5];), preso da una variabile (es: elenco[k];) o calcolato da una espressione (es: elenco[k+3];)

Gli array possono essere passati come parametri ad una funzione. In questo caso, nella dichiarazione della funzione si specifica il nome dell'array come parametro, senza specificare la dimensione. All'interno della funzione l'accesso agli elementi dell'array avviene con la consueta sintassi. Per esempio:

<iostream>

using namespace std;

 

int somma(const int eln[], const int qta) {

  long som = 0;

  for(int i = 0; i < qta; som += eln[i++]);

  return som;

}

 

int main() {

  int elenco[] = {1, 2, 3, 4, 5, 6, 7};

  cout << "Somma: " << somma(elenco, 7) << endl;

return 0;

}

La funzione somma riceve, come parametri, un array di interi e un numero intero che rappresenta la quantità degli elementi, esegue l'addizione di tutti gli elementi e ne restituisce il risultato alla funzione chiamante.

Si noti la flessibilità del ciclo for in C++: la terza espressione, rappresenta l'operazione da eseguire prima di ripetere un altro ciclo, che in sostanza è tutto ciò che si deve fare, rendendo superfluo scrivere il corpo del ciclo.

Inoltre si noti che l'array viene passato per riferimento, cioè la funzione riceve l'indirizzo dell'array, quindi ogni modifica all'array viene vista anche dal programma chiamante. Per evitare che il programmatore usi espressioni che modifichino accidentalmente l'array, la dichiarazione del parametro contiene la clausola const.

Un array viene anche denominato vettore. Per dichiarare un array bidimensionale (o matrice) si aggiunge una ulteriore coppia di parentesi quadre nella dichiarazione. Ad esempio:

 

int matrice[N][M];

 

L'array conterrà NxM elementi dello stesso tipo. Può essere immaginato come una scacchiera in cui una posizione viene individuata specificando due coordinate oppure, secondo il modello di memorizzazione, come un array di M array di N elementi. Il primo indice specifica uno tra gli M array e il secondo indice specifica l'elemento all'interno di tale array.

Un array multi dimensione è un'astrazione che serve al programmatore per modellare l'elaborazione degli elementi. Ad esempio la dichiarazione anno[12][31] può anche essere sostituita dalla dichiarazione anno[365]. La differenza tra le due dichiarazioni dipende dalla convenienza che ne ha il programmatore ad elaborare i dati: in un caso è immediato riferirsi ad un certo giorno del mese, nel secondo caso è più semplice calcolare il numero di giorni tra due date.

Attenzione: quando si passa un array multi dimensione ad una funzione, nella dichiarazione, si deve omettere solo la prima dimensione. Es:
int Funzione(int matrice[][4]) { … }

Algoritmo di Ricerca del Massimo

problema

Dati N elementi: X[0], X[1], ..., X[N-1], trovare il massimo valore e la sua posizione. In caso di valori uguali si vuole conoscere la posizione di quello più vicino all'estremo superiore.

Algoritmo:

  1. Assegnare i valori iniziali alle variabili:

    posMax ← N-1,

    si suppone che il massimo si trovi in posizione N-1.
    nella variabile posMax viene memorizzata la sua posizione.

    Max ← X[N-1],
    nella variabile Max viene memorizzato il suo valore.

    k ← N-2,
    la variabile k contiene la posizione del prossimo elemento da confrontare con quello che si è assunto che sia il massimo

  2. SE (k è negativo) il procedimento di ricerca termina,

    non ci sono altri elementi

  3. SE (X[k] > Max)
    1. Max ← X[k]

      è stato trovato un nuovo massimo, si aggiorna il valore nella variabile Max

    2. posMax ← k

      Si memorizza la sua posizione nella variabile posMax

  4. k ← k - 1

    si passa a prendere in esame un altro elemento

  5. ripetere il procedimento continuando dal passo Nr. 2

fig. 1: Diagramma di flusso

fig. 2: ciclo for,

Con riferimento al diagramma di flusso in figura 1, le operazioni:

  1. di assegnazione di un valore iniziale ad una variabile (k ← N-2)

  2. di controllo se il valore della variabile si mantiene entro limiti prefissati, (k<0?)

  3. di decremento della variabile (k ← k-1);

  4. e di rinvio al test sul valore della variabile,

costituiscono un ciclo e vengono incorporate in un'unica espressione.

Nella programmazione i cicli rappresentano un'istruzione che esprime la ripetizione di un gruppo di operazioni.
Pertanto, più sinteticamente, le operazioni da eseguire in ciclo vengono precedute da un'istruzione for che specifica tre espressioni:

Il diagramma di flusso di figura 1 si trasforma nel diagramma di flusso di figura 2.

In questo diagramma di flusso il punto di entrata nel ciclo è stato espresso in termini molto dettagliati, ma nella pratica, ci si limita ad esprimere le tre espressioni sopra la linea di ritorno nel ciclo, cioè: k=N-2; k≥0; k++;

Stringhe

Per Stringa si intende una sequenza di caratteri, come "Hello, world!". Le stringhe vengono memorizzate carattere per carattere in sequenza. Di conseguenza in C++ una striga è un array di caratteri. Si consideri il seguente programma:

#include <iostream>

using namespace std;

 

int main() {

  char helloworld[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\0' };

  cout << helloworld << endl;

 

return 0;

}

Questo programma stampa "Hello, world!". Le osservazioni più importanti sono:

L'array di caratteri helloworld può essere inizializzato anche direttamente con una stringa. In questo caso non è necessario usare il carattere di fine stringa perchè lo inserisce automaticamente il compilatore:

char helloworld[] = "Hello, world!";

Il C++ fornisce delle librerie per la manipolazione delle stringhe Il seguente esempio illustra l'utilizzo della libreria cctype.h:

#include <cstdlib>

#include <iostream>

#include <cctype>

 

using namespace std;

 

int main(int argc, char *argv[]) {

  char msgCifrato[] = "9U9N909.m6E0S9s6a2gg6IO.CIFRATO";

 

  char lettera = msgCifrato[0];

  for(int i = 0; lettera != '\0'; lettera = msgCifrato[++i]) {

    if(isalpha(lettera))

      cout << (char)(isupper(lettera) ? tolower(lettera) : lettera);

    else if(ispunct(lettera))

      cout << ' ';

  }

 

  cout << endl;

  system("PAUSE");

  return 0;

}

Questo esempio usa le funzioni di libreria:

Le funzioni is restituiscono un risultato booleano (vero o falso).

Il ciclo for preleva un carattere alla volta dalla stringa e, se non si tratta del carattere di fine stringa, trasforma un carattere alfametico maiuscolo in minuscolo e lo mostra, se è già minuscolo lo stampa direttamente. Se si tratta di un caratere di punteggiatura stampa uno spazio, tutti gli altri caratteri vengono ignorati.

Ecco un esempio di utilizzo della libreria cstring:

#include <iostream>

#include <cstring>

 

using namespace std;

 

int main() {

  char fram1[] = "sono un";

  char fram2[] = "a stringa!";

  char fram3[20];

  char Stringa[20] = "";

 

  strcpy(fram3, fram1);

  strcat(Stringa, fram3);

  strcat(Stringa, fram2);

 

  cout << Stringa;

 

  return 0;

}

Questo programma crea e inizializza due stringhe (fram1 e fram2). La stringa fram3 viene dichiarata ma non viene inizializzata. La Stringa è inizializzata con il carattere null.

fram1 è copiato in fram3 usando la funzione strcpy,

strcat è usata per concatenare due stringhe.