Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
1
Vettori, stringhe e matrici
Lezione frontale #4
Argomenti:
-vettori e stringhe
-allocazione dinamica di memoria
-libreria di funzioni sulle stringhe
-Strutturazione di un progetto con librerie e CUnit
Lab di Informatica - Prof. F. Calefato
Tipi di dato in C
Lab di Informatica - Prof. F. Calefato
4/10/2013
2
VETTORI & STRINGHE
Parte 1
Lab di Informatica - Prof. F. Calefato
Vettori (Array)
I vettori (array) sono uno dei tipi di dato
strutturati:
Sequenza finita di elementi omogenei (tutti dello
stesso tipo)
Ogni elemento identificato allinterno dellarray da
un numero dordine detto indice dellelemento
Il numero di elementi del vettore detto lunghezza
(o dimensione fisica) del vettore
Lab di Informatica - Prof. F. Calefato
4/10/2013
3
Vettori (in teoria)
Esempio
Vettore di n elementi
n detto lunghezza o dimensione fisica del vettore
Ogni elemento identificato da un indice intero
compreso tra 1 e n
1 2 N
X Y Z
indici
elementi
Lab di Informatica - Prof. F. Calefato
Vettori in C
In C il vettore un tipo di dato primitivo e si usa il costruttore
di tipo [ ]
Sintassi
<id-tipo> <id-variabile>[ <dimensione> ];
dove:
<id-tipo>: identificatore di tipo degli elementi componenti
<dimensione>: costante intera che rappresenta il numero
degli elementi componenti
<id-variabile>: identificatore della variabile strutturata (il
vettore)
Es.
int studenti [35];
N.B. lindice in C compreso tra 0 e n-1
Lab di Informatica - Prof. F. Calefato
4/10/2013
4
Esempi di dichiarazioni
#define MAX 10
int vet[MAX];
Alloca un vettore di MAX elementi, ovvero 10 locazioni di memoria
consecutive, ciascuna contenente un intero
MAX la lunghezza del vettore.
In C lindice degli elementi va sempre da 0 a lunghezza 1
vet[i] denota lelemento del vettore vet di indice i
Ogni elemento del vettore una variabile di tipo intero
vet lindirizzo del primo elemento vet[0]
ATTENZIONE:
La lunghezza del vettore deve essere una espressione costante, cio nota
a tempo di compilazione
int N;
float vet[N];
Lab di Informatica - Prof. F. Calefato
ERRORE Non standard ANSI C
Il compilatore non sa quanta
memoria allocare per larray
Uso di typedef per dichiarare il tipo
non primitivo vettore
In C possibile utilizzare typedef [ ] per dichiarare tipi di dato
non primitivi rappresentati da vettori
Sintassi
typedef <tipo-componente> <tipo-vettore>[<dim>];
<tipo-componente>: identificatore di tipo di ogni singola
componente
<tipo-vettore>: identificatore che si attribuisce al nuovo tipo
<dim>: numero di elementi che costituiscono il vettore (deve
essere una costante)
Esempio:
typedef int persone[30];
persone v1, v2; /* v1 e v2 sono variabili di tipo vettore ed ognuna
rappresenta un vettore di 30 elementi interi */
Lab di Informatica - Prof. F. Calefato
4/10/2013
5
Inizializzazione di un vettore (1/2)
Possibilit 1: inizializzazione in fase di
definizione
Esempio:
int v[10] ={1,2,3,4,5,6,7,8,9,10};
/* v[0] =1; v[1] =2; ... v[9] =10; */
NB la dimensione determinata sulla base
dellinizializzazione
Lab di Informatica - Prof. F. Calefato
Inizializzazione di un vettore (2/2)
Possibilit 2: mediante un ciclo
Per attribuire un valore iniziale agli elementi di un
vettore si pu attuare una sequenza di assegnamenti
alle N componenti del vettore
Esempio:
#define N 30
int vettore[N];
int i;
...
for (i =0; i <N; i++)
vettore [i] =i;
Lab di Informatica - Prof. F. Calefato
4/10/2013
6
Esempi di inizializzazione di vettori
Elementi del vettore inizializzati con valori costanti contestualmente alla
dichiarazione del vettore
Esempio: int n[4] ={11, 22, 33, 44};
Linizializzazione deve essere contestuale alla dichiarazione
Esempio: int n[4];
n ={11, 22, 33, 44}; errore!
Se ci sono meno inizializzatori di elementi, quelli rimanenti vengono posti
a 0
Esempio: int n[10] ={3}; azzera i rimanenti 9 elementi del vettore
float af[5] ={0.0}pone i 5 elementi pari a 0,0
int x[5] ={}; errore!
Se ci sono pi inizializzatori di elementi, si ottiene un errore di sintassi
Esempio: int v[2] ={1, 2, 3}; errore!
Se si mette una lista di inizializzatori, si pu evitare di specificare la
lunghezza (viene presa la lunghezza della lista)
Esempio: int n[] ={1,2,3}; equivale a int n[3] ={1,2,3};
ERRORE
ERRORE
ERRORE
Lab di Informatica - Prof. F. Calefato
Dimensione fisica vs. dimensione logica
Un array una collezione finita di N celle dello stesso
tipo
Non significa che si debbano per forza usare sempre tutte.
La dimensione logica di un array pu essere inferiore
alla sua dimensione fisica
la porzione di array realmente utilizzata dipende dai dati
dingresso
Esempio
#define DIM 10
main() {
int v[DIM] ={273,340,467,10};
Dimesione
fisica 10
Dimesione
logica 4
Lab di Informatica - Prof. F. Calefato
4/10/2013
7
Operatori di vettori in C
Non esistono operatori specifici per i vettori
E necessario operare singolarmente sugli elementi componenti
Non possibile lassegnamento diretto tra vettori
int V[10], W[10];
0xA01 c
0xA02 i
0xA03 a
0xA04 o
0xA05 \0
4/10/2013
14
Aritmetica dei puntatori
Se p un puntatore a un dato con un certo tipo
allora:
Lespressione p+i rappresenta lindirizzo di memoria
corretto per memorizzare la successiva i-ma
variabile dello stesso tipo a partire da p
Sono corrette anche espressioni come:
p +=i; // equivale a p = p + i;
p++;
q =p +i;
Lab di Informatica - Prof. F. Calefato
Aritmetica dei puntatori
Sia a un array di interi e i un intero
int a[10];
int i;
Allora
a[i] *(a + i)
Perch?
Lab di Informatica - Prof. F. Calefato
4/10/2013
15
Array e puntatori: perch equivalenti
Lab di Informatica - Prof. F. Calefato
Esempio 1/2
Due funzioni:
input_array()
print_array ()
Input della dimensione
Allocazione:
cast a (int *)
dim interi
Chiamata di inputarray
scanf sul puntatore p
incremento di p
void input_array (int *, int);
void print_array (const int *,
int);
void main(void) {
int *a;
int dim;
printf (Che dimensione?);
scanf (%d,&dim);
a =(int *) calloc ( dim, sizeof(int) );
input_array (a, dim);
print_array (a, dim);
free (a);
}
void input_array(int *p, int size) {
int i;
for (i=0; i <size; i++) {
printf (a[%d]=, i);
scanf (%d, p +i);
}
}
Lab di Informatica - Prof. F. Calefato
Base +
spostamento con
il puntatore (p+i)
cast a int*
4/10/2013
16
Esempio 2/2
Chiamata di
print_array()
La stampa di ogni
elemento
stampa lintero puntato
da p e poi incrementa il
puntatore
La memoria allocata
liberata
free(a);
main() {
int *a;
int dim;
printf (Che dimensione?);
scanf (%d,&dim);
a =(int *) calloc (dim, sizeof(int));
input_array (a, dim);
print_array (a, dim);
free (a);
}
return s;
}
Lab di Informatica - Prof. F. Calefato
Esercizio 5
Completare lesempio precedente della
funzione
char* crea_stringa(char a, char b, char c)
Dimostrarne la correttezza attraverso un
opportuno caso di test CUnit
Lab di Informatica - Prof. F. Calefato
4/10/2013
18
Esercizio 6 per casa
Scrivere una funzione int conta_parole(const
char* str) che conta le parole separate dagli
spazi in una stringa
Come distinguere lo spazio dagli altri caratteri???
Suggerimento: cercate nelle librerie standard del C
Dimostrarne la correttezza con un opportuno
caso di test CUnit
Lab di Informatica - Prof. F. Calefato
string.h
Libreria di funzioni da includere per le
operazioni pi comuni tra stringhe
Contiene funzioni per:
Copiare una stringa
Concatenare due stringhe in una
Misurare la lunghezza di una stringa
etc.
Lab di Informatica - Prof. F. Calefato
4/10/2013
19
Alcune funzioni di string.h
char *strcat ( char *s1, const char*s2)
concatena s2 a s1 e restituisce s1.
Lo spazio in s1 deve essere sufficiente a contenere la stringa
concatenata
int strcmp (const char *s1, const char *s2)
confronta le stringhe e restituisce un intero =0 se sono uguali
<0 se s1 precede s2, >0 se s1 segue s2
char *strcpy (char *s1, const char *s2)
copia s2 in s1 e restituisce s1 (dopo la copia)
Lo spazio in s1 deve essere sufficiente
int strlen(const char *s1)
restituisce la lunghezza di s1
Lab di Informatica - Prof. F. Calefato
Esercizio 7
Create dei programmi a scelta che facciano
uso di
strcat
strcpy
strcmp
strlen
Dimostrarne la correttezza attraverso opportuni
casi di test CUnit
Lab di Informatica - Prof. F. Calefato
4/10/2013
20
Strutturazione di un progetto in CDT
In C un progetto non pu avere pi
di una definizione di funzione main ()
Occorre creare due progetti distinti,
uno con il main CUnit per il test, uno
con il main "classico"
Struttura corretta a 3 progetti
1. Progetto libreria (statica) di funzioni
2. Progetto main CUnit
3. Progetto main classico
Lab di Informatica - Prof. F. Calefato
1. Creazione progetto libreria
Lab di Informatica - Prof. F. Calefato
4/10/2013
21
2. Creazione progetto CUnit (1/3)
Creare normalmente
un progetto
Utilizzare il file
main_cunit_template.c
fornito con le dispense
Aggiungere il progetto
di libreria tra le
references del
progetto Cunit
(necessario per
Eclipse)
Lab di Informatica - Prof. F. Calefato
2. Creazione progetto CUnit (2/3)
Aggiungere il progetto di libreria tra le
references del progetto CUnit (GCC)
Lab di Informatica - Prof. F. Calefato
4/10/2013
22
2. Creazione progetto CUnit (3/3)
Lab di Informatica - Prof. F. Calefato
3. Creazione del progetto Main classico
Rieseguire i medesimi passi compiuti per
configurare il progetto CUnit
Lab di Informatica - Prof. F. Calefato
4/10/2013
23
Esercizio 8 per casa
Scrivere un insieme di funzioni su array
dinamici di interi che effettuino:
linput e loutput
la ricerca del minimo e del massimo
la somma degli elementi
Le funzioni devono essere modularizzate in un
modulo con rispettivi file .h e .c
Dimostrarne la correttezza attraverso opportuni
casi di test CUnit
Lab di Informatica - Prof. F. Calefato
puts & gets in <stdio.h>
scanf non adatta a leggere intere linee (che possono contenere
spazi bianchi, caratteri di tabulazione, etc.)
scanf (con formato %s) prevede come separatore anche il blank
(spazio bianco)
possibile soltanto leggere stringhe che non contengono spazi bianchi;
Per esempio
Nel mezzo del cammin di nostra vita, mi ritrovai per una selva oscura
Leggendo con:
char s1[80], s2[80];
scanf("%s", &s1); /* s1 vale "Nel" */
scanf("%s", &s2); /* s2 vale "mezzo" */
Esistono funzioni specifiche per fare I/O di linee:
gets (legge fino a '\n')
puts (scrive e aggiunge '\n')
Lab di Informatica - Prof. F. Calefato
4/10/2013
24
gets
E una funzione standard che legge una intera riga da input,
fino al primo carattere di fine linea ('\n', newline) e lassegna
a una stringa
gets(const char* str);
Assegna alla stringa str i caratteri letti.
Il carattere '\n sostituito (nella stringa di destinazione str) da '\0
Restituisce la stringa letta str o NULL in caso di fallimento
Esempio
dato linput:
Nel mezzo del cammin di nostra vita,
mi ritrovai per una selva oscura
char s[80];
gets(s);
s vale: "Nel mezzo del cammin di nostra vita,"
Lab di Informatica - Prof. F. Calefato
puts
E una funzione standard che scrive una stringa sull'output
aggiungendo un carattere di fine linea ('\n', newline)
puts(const char* str);
puts(s) equivalentea printf("%s\n", s);
Restituisce un intero non negativo in caso di successo, EOF in caso
contrario
Esempio:
char s1[80]="Dante Alighieri";
char s2[80]="La Divina Commedia";
puts(s1);
puts(s2);
stampa sullo standard output:
Dante Alighieri
La Divina Commedia
Lab di Informatica - Prof. F. Calefato
4/10/2013
25
MATRICI
Parte 2
Lab di Informatica - Prof. F. Calefato
Matrici (vettori multidimensionali)
Gli elementi di un vettore possono essere a loro
volta di tipo vettore:
Si parla di matrici
Ci limitiamo ai vettori bidimensionali e quindi a matrici
N x M (righe x colonne)
Sintassi matrice 2D
<tipo> <identificatore> [<costante>][<costante>] ;
Esempio
float mat[4][3];
Lab di Informatica - Prof. F. Calefato
4/10/2013
26
Matrici 2D
float M [20][30];
M un vettore di 20 elementi
ognuno dei 20 elementi a
sua volta un vettore di 30 float
Accesso alle componenti:
il primo indice denota la riga
il secondo la colonna
M [0][0] =7.1 ;
M [1][29] =0.5 ;
M [19][29] =-1.99 ;
M [0] rappresenta il primo
vettore di 30 float (la prima
riga)
Lab di Informatica - Prof. F. Calefato
7.1
0.5
-1.99
Inizializzazione di matrici
Anche nel caso di vettori multi-
dimensionali linizializzazione si
pu effettuare in fase di
definizione
Esempio:
int matrix[4][4] ={ {1,0,0,0},
{0,1,0,0},
{0,0,1,0},
{0,0,0,1} };
Si pu anche omettere il numero
di righe
int matrix[][4]={{1,0,0,0},
{0,1,0,0}, {0,0,1,0}, {0,0,0,1}};
Non sono ammessibili
dichiarazioni:
int matrix[4][]=
int matrix[][]=
La memorizzazione
avviene per righe
Lab di Informatica - Prof. F. Calefato
4/10/2013
27
Matrici e typdef
Come al solito, possiamo usare typedef per
definire lalias del nuovo tipo di dati matrice
bidimensionale
Es
typedef int matrice [MAX_RIGHE] [MAX_COL]
matrice m1, m2;
Lab di Informatica - Prof. F. Calefato
Esercizio 9
Creare un tipo matrice di interi 2 x 3
Avvalorare la matrice da tastiera
Stampare la matrice
Stampare la somma totale dei numeri inseriti
nella matrice
Lab di Informatica - Prof. F. Calefato
4/10/2013
28
Riferimenti
Vittorio Scarano, Puntatori e stringhe
www.dia.unisa.it/~vitsca/LAB/lezione07l.pdf
La sezione sulle matrici contiene materiale
proveniente dalle lezioni del corso di
Programmazione di Michele Colajanni
Lab di Informatica - Prof. F. Calefato