Array e Matrici

Problema

Si vuole un programma che chieda 10 numeri all'utente e li visualizzi in ordine inverso.

Si vuole un programma che chieda 10 numeri all'utente e li ordini dal piu' piccolo al piu' grande, per poi stamparli a video.

E' molto scomodo e poco pratico fare uso di 10 variabili separate. E' necessario un contenitore diverso, in grado di contenere N variabili dello stesso tipo.

Introduzione

Variabili vettoriali: contengono più valori dello stesso tipo, detti elementi.

Tutti gli elementi hanno lo stesso nome, ma sono contraddistinti da un numero, detto indice indicato tra parentesi quadre:

a[1]    a[2]     a[3]     a[4]

in termini matematici questo si scrive:

\begin{equation} a_{1} \qquad a_{2} \qquad a_{3} \qquad a_{4} \end{equation}

Se il tipo è di base (come char, int, long, double, etc.), tutti gli elementi del vettore sono variabili scalari di quel tipo

Definizione

Definizione (alloca tutta la memoria per tutti gli elementi):

tipo nome[num_elementi];

La dimensione del vettore deve essere una costante intera positiva

Esempio

int vett[10];

vett1.png

Il numero di elementi deve essere una costante intera positiva (non una const) nota a compile-time

Di norma la costante viene gestita con una #define

Accesso agli elementi

Si accede ai singoli elementi indicando il nome del vettore seguito dall'indice (posizione) dell'elemento tra parentesi quadre.

La posizione puo' essere espressa con una costante, una variabile o con una espressione

vett[2]      vett[i]       vett[i+2]

Il primo elemento ha indice 0

L'ultimo elemento di un vettore di N elementi ha indice N-1, quindi nel nostro esempio sara' vett[9]

Uso degli elementi

Dato che gli elementi di un vettore sono equivalenti ad una variabile del tipo indicato nella definizione (nel nostro esempio il tipo e' int) un elemento può essere utlizzato in tutti i contesti in cui si può usare un valore di quel tipo

1: int vett[10];
2: int x;
3: 
4: scanf ("%d", &vett[0]);
5: 
6: x = vett[0] * 5;

Layout in memoria

Gli elementi del vettore sono allocati in locazioni di memoria successivi e contigui

vett2.png

Il nome di un vettore, per il compilatore, in realtà equivale all'indirizzo in memoria del primo elemento del vettore.

Non è quindi una variabile, quindi non gli si può assegnare un valore.

Non possiamo quindi copiare un vettore con un assegnamento.

Attraversare un vettore

E' possibile attraversare tutto un vettore con un ciclo for

1: #define N 10
2: 
3: int vett[N];
4: int i;
5: 
6: /* riempie il vettore con valori inseriti dall'utente */
7: for(i = 0; i < N; i++) {
8:     scanf("%d", &vett[i]);
9: }

Si sfora il vettore quando si cerca di accedere ad elementi la cui posizione non è valida, ovvero se la posizione è oltre i limiti del vettore.

Questo errore viene chiamato buffer overflow ed è una vulnerabilità di sicurezza.

1: int vett[4];
2: int i;
3: 
4: for (i = 0; i <= N; i++) {
5:     printf("%d", vett[i]);
6: }

Inizializzazione di vettore

Si inizializza un vettore con una lista di valori racchiuse tra parentesi graffe

int vett[4] = {12, 42, 3, 100};

Non e' possibile inserire un numero di valori maggiore della lunghezza del vettore.

Il compilatore ce lo segnalerà con un warning.

Se non inizializziamo il contenuto di un vettore i valori in esso contenuti non sono noti (può esserci qualsiasi valore, non è detto che siano zero).

Se la lista invece contiene meno valori della dimensione del vettore verranno inizializzati solo quelli indicati, mentre i restanti verranno inizializzati a zero.

int v[4] = {6, 2};

Il vettore conterra' 6, 2, 0, 0

Se invece indichiamo

int v[100] = {0};

Il vettore conterra' solo zeri

Passaggio vettori a funzione

Per passare un vettore come argomento, si indica il suo nome senza parentesi

x = media(vettore);

Il parametro formale corrispondente definirà un vettore dello stesso tipo (in genere senza dimensione in quanto ininfluente)

float media(float v[]);

La funzione deve conoscere in qualche modo la dimensione del vettore. Abbiamo piu' possibilita':

  • viene passato come argomento
float media(int v[], int lung);
  • è noto a priori (es. una #define) questa soluzione rende meno flessibile il codice da noi scritto

Il codice all'interno della funzione, al contrario di quanto avviene con le "normali" variabili, modifica in modo permanente il contenuto dell'array.

Se quindi inseriamo dei valori all'interno dell'array durante l'esecuzione di una funzione, il resto del programma potra' accedere ed utilizzare tali valori.

void carica_array(int valori[], int dim)
{
    for (i = 0; i < dim; i++) {
        printf("inserisci il valore %d: ", i + 1);
        scanf("%d", &valori[i]);
    }
}

int main()
{
    int v[10];

    carica_array(v, 10);

    printf("%d %d\n", v[0], v[1]);
    /* la printf stampera' i primi due valori inseriti dall'utente nella funzione */
    return 0;
}

Esercizi

Es1

Scrivere una funzione C che riceve come parametro un array di double e la sua dimensione e restituisce la media degli elementi presenti nell'array.

Es2

Scrivere una funzione C che riceve come parametro un array di interi, la sua dimensione e due indici h e k e restituisce la somma degli elementi dell’array memorizzati nelle posizioni da h a k

Es3

Scrivere una funzione C che riceve come parametro un array di interi e la sua dimensione e restituisce 1 se tutti gli elementi dell'array sono diversi tra loro

Es4

Scrivi una funzione trova_divisori(int n) che riceva un numero n intero minore di 10000 ed inserisca in un vettore tutti i divisori del numero inserito dall'utente. La funzione chiama a sua volta la funzione stampa_vettore() per visualizzare l'elenco dei divisori trovati.

Es5

Scrivere un programma che riempia un array con N numeri interi e sia in grado di determinare se in tutte le posizioni pari dell’array è memorizzato un numero pari.

Es6

Scrivere un programma che riempia un array da 10 elementi di valori casuali compresi tra 1 e 10. Il programma deve poi stampare su di un'unica riga tutti gli elementi dell'array, Se la somma dei numeri supera 50 il programma dovrà anche contare quanti numeri dell'array sono maggiori di 6 e stamparlo a video. Se la somma dei numeri invece è minore di 50 il programma dovrà contare quanti numeri dell'array sono minori di 4 e stamparlo a video.

Esempio: 1 10 5 8 4 9 7 5 2 3 Numeri maggiori di 6: 4

1 2 5 8 4 9 7 5 2 4

Numeri minori di 4: 3

Es7

Scrivere un programma C che legga dall'utente un array di numeri interi e stampi VERO se il primo valore dell'array e' duplicato

[10, 20, 30, 60, 42, 1200, 10] stampa VERO

Es8

Scrivere una funzione C che legga N numeri, li memorizzi in un vettore, e costruisca poi un secondo vettore contenente i valori del primo in ordine inverso Per esempio:

– valori dell’array: 15, 23, 35, 46, 51, 68, 12, 72;

– valori secondo array: 72, 12, 68, 51, 46, 35, 23, 15

Matrici

Altri esercizi

Es1

Scrivere un programma composto da due funzioni:

  • la funzione leggi_array() che riempia un array di 8 numeri interi con valori inseriti dall'utente,
  • scrivere una funzione somma() che calcoli la somma di quelli negativi ed inserisca zero al loro posto.

Es2

Creare un array di interi con 10 posti, inserire zeri in tutte le celle; leggere in che posizione inserire un 1 e inserirlo nella corretta posizione dell’array; scandire l’array una cella alla volta fermandosi quando si trova l’uno, dire in che cella è stato trovato.

Es3

Scrivere una funzione che, dato un array di 8 interi, e due numeri inf e pos calcoli e stampi a video quanti valori nell’array sono compresi tra questi.

Es array: 1 3 4 5 6 7 10 100 se inf = 2 sup = 8

il numero calcolato e' 5 in quanto i valori 3, 4, 5, 6, 7 sono compresi nell'intervallo

Es4

Scrivere una funzione che, dato un array di 10 interi, sia in grado di determinare se i valori memorizzati nell’array sono memorizzati in ordine crescente. 1, 2, 3, 4, 10, 50, 70, 100 e' in ordine crescente

1, 2, 4, 5, 3, 10, 20, 30, 4 non e' memorizzato in ordine crescente

Es5

Scrivere una funzione che, dato un array di 10 interi e stampi a video solo i numeri che appaiono nell’array una volta soltanto. Ad esempio se l’array contiene 1, 2, 3, 1, 2, 4 il programma stamperà 3, 4

Validate