Scaricare la presentazione
1
Vettori (a una dimensione)
Dichiarazione. Prima di essere usato, un vettore deve essere dichiarato. Per dichiarare che voti è un vettore di interi con 5 componenti si usa l’istruzione di dichiarazione int voti[5]; Essa fornisce il tipo dati delle componenti (o elementi) del vettore, il suo nome e il numero delle sue componenti. Altri esempi di dichiarazioni sono:
2
A ogni vettore il compilatore riserva memoria sufficiente per contenere il numero di valori indicati nell’istruzione di dichiarazione. Quindi, nella ipotesi che ciascun carattere sia memorizzato usando 1 byte e che ciascun numero intero ne usi 2, il vettore codici ha memoria riservata per 4 caratteri, il vettore voti ha memoria per 5 numeri in doppia precisione
3
e prezzi ha memoria per 6 numeri in virgola mobile.
Le singole componenti dei due vettori precedenti sono memorizzate in modo sequenziale, con la prima componente memorizzata nella prima locazione riservata, la seconda nella seconda e così via. Per accedere a una singola componente di un vettore a una dimensione si indica il nome del vettore e la posizione in esso della componente. La posizione della componente è detta subscritto o (valore dell’)indice. La prima componente ha indice 0, la seconda 1 e la i-esima ha indice i-1. In C il nome del vettore e l’indice sono combinati scrivendo l’indice in parentesi quadre dopo il nome del vettore.
4
Così: Ogni singola componente è detta variabile indicizzata o con subscritto, dato che per individuarla servono sia il nome della variabile sia un valore di indice o subscritto. Sebbene possa sembrare insolito riferirsi alla prima componente con un indice zero, ciò aumenta la velocità con cui il computer accede alle componenti del vettore.
5
Come mostra la figura seguente,
l’indice dice al computer quanti elementi vanno saltati, a partire dall’inizio del vettore, per raggiungere la componente desiderata. Le variabili con indice si possono usare in tutti i casi in cui siano valide le variabili scalari. Esempi di istruzioni che usano gli elementi del vettore voti sono: voti[0] = 98; voti[1] = voti[0] - 1; voti[2] = 2 * (voti[0] - 6);
6
totale = voti[0]+voti[1]+voti[2]+voti[3]+voti[4]
L’indice in parentesi non deve essere necessariamente un intero, ma può essere una qualsiasi espressione che venga valutata a un intero. Ad es., se i e j sono variabili intere, sono valide le seguenti variabili con indici: voti[i]; voti[2*i]; voti[j-i]; Un vantaggio di usare come indici espressioni intere è che ciò consente di muoversi sequenzialmente attraverso un vettore con un ciclo for. Quindi, non è necessario scrivere un’espressione del tipo: totale = voti[0]+voti[1]+voti[2]+voti[3]+voti[4] ma si può sostituirla con il ciclo:
7
totale = 0; for (i = 0; i <= 4; ++i); totale += voti[i]; In esso la variabile i è usata sia come contatore del ciclo, sia come indice del vettore. Vediamo come assegnare i valori alle componenti di un vettore a una dimensione.
8
Ingresso dei valori. I valori dei singoli elementi di un vettore si possono assegnare:
in modo interattivo, tramite la funzione scanf(), oppure tramite istruzioni di inizializzazione in un programma. Esempi di istruzioni d’ingresso interattivo sono: scanf(“%c”, &codice[0]); scanf(“%d %lf”, &voti[0], &prezzo[2]); for (i = 0; i <= 4; i++) { printf(“Scrivi un voto: “); scanf(“%d”, &voti[i]); } Il precedente ciclo for richiede all’utente di scrivere 5 voti, e memorizza il primo in voti[0], il secondo in voti[1] e così via.
9
Dato che il C non controlla il valore dell’indice usato, se un vettore è stato dichiarato costituito da 10 elementi e si usa l’indice 12, C non segnala l’errore in fase di compilazione. Il programma tenta di accedere all’elemento 12 procedendo oltre il giusto numero di byte a partire dall’inizio del vettore. Di solito, ma non sempre, ciò determina un crash del programma. Se infatti la locazione a cui si fa riferimento contiene come valore un dato, il programma accederà a esso, dando luogo a errori particolarmente difficili da trovare quando si userà in un altro punto del programma la variabile legittimamente assegnata alla locazione di memoria.
10
i valori di inizializzazione vanno racchiusi
Inizializzazione. Gli elementi di un vettore possono essere inizializzati all’interno delle loro istruzioni di dichiarazione, come le variabili scalari, con la differenza che: i valori di inizializzazione vanno racchiusi tra parentesi graffe e separati con virgole Esempi di inizializzazioni di vettori di numeri sono: int voti[5] = {24, 29, 30, 30, 27}; double larg[6]={10.96, 6.43, 2.58, .86, 5.89, 7.56}; float temp[4] = {98.6, , 101.5}; Un vettore di caratteri, può essere inizializzato o indicando i singoli caratteri, racchiusi tra apici semplici, char codici[4] = {‘r’, ‘o’, ‘m’, ‘a’}; oppure, in modo equivalente, con una stringa racchiusa tra apici doppi: char codici[4] = {“roma”};
11
Una caratteristica utile degli inizializzatori è che:
Se il numero di inizializzatori è minore del numero di elementi dichiarato nelle parentesi quadre, gli inizializzatori sono applicati a partire dall’elemento 0 del vettore, e gli altri elementi sono inizializzati a 0. Non c’è un modo per indicare la ripetizione di un valore di inizializzazione, o per inizializzare alcuni elementi di un vettore senza prima avere inizializzato quelli precedenti. Se nell’istruzione di dichiarazione non sono forniti inizializzatori specifici, tutti gli elementi del vettore sono posti uguali a 0. Una caratteristica utile degli inizializzatori è che: la dimensione di un vettore può essere omessa quando i valori di inizializzazione sono inseriti nell’istruzione di dichiarazione. Ad es., la dichiarazione int litri[] = {16, 12, 10, 14, 11} riserva spazio sufficiente per 5 elementi.
12
Uscita dei valori. Per quanto riguarda l’uscita, si possono visualizzare:
singoli elementi del vettore, con una chiamata alla funzione printf(), oppure intere sezioni del vettore inserendo una chiamata alla funzione printf() all’interno di un ciclo for. Esempi: printf(“%lf”, prezzo[6]); visualizza il valore della variabile con indici in doppia precisione prezzo[6] for (n = 5; n <= 20; ++n) printf(“%d %lf”, n, prezzo[n]); inserisce printf() all’interno di un ciclo for, e visualizza i valori degli indici e degli elementi dal 5 al 20.
13
Il programma seguente illustra queste tecniche d’ingresso e uscita usando un vettore di nome voti, definito per memorizzare 5 numeri interi. #include <stdio.h> void main(void) { int i, voti[5]; for (i = 0; i <=4; ++i) printf(“Scrivi un voto: “); scanf(“%d”, &voti[i]); } for (i = 0; i <= 4; ++i) printf(“\nIl voto n° %d è %d”, i, voti[i]);
14
Nel programma vi sono due cicli for:
il primo percorre l’intero vettore e consente di immettere i suoi singoli valori; il secondo visualizza i valori memorizzati. Ecco l’uscita prodotta: Scrivi un voto: 28 Scrivi un voto: 30 Scrivi un voto: 29 Scrivi un voto: 27 Il voto n° 0 è 28 Il voto n° 1 è 30 Il voto n° 2 è 29 Il voto n° 3 è 27 Il voto n° 4 è 29
15
Componente massima. Come altro esempio di uso di un ciclo for per la scansione di un vettore, troviamo il massimo di numeri, che assegniamo alle componenti di un vettore prezzo. 1. Supponiamo inizialmente che il massimo sia la prima componente del vettore: massimo = prezzo[0]; 2. Quindi, muovendoci sequenzialmente attraverso il vettore, confrontiamo tale massimo con ciascuna componente, e se ne troviamo una con valore maggiore la poniamo come nuovo massimo: for (i = 1; i <= 999; ++i) if prezzo[i] > massimo massimo = prezzo[i]; In questo codice il ciclo for consiste in una sola istruzione if. La ricerca di un nuovo valore massimo comincia con la componente 1 del vettore e continua fino all’ultima (che nel caso nostro ha indice 999).
16
Esercizio: somma degli elementi
Esercizio: somma degli elementi. I valori memorizzati negli elementi di un vettore possono subire diverse elaborazioni, la più semplice delle quali è la somma. Scrivere un programma che: assegni ciascun voto a un elemento di un vettore, lo accumuli in un totale, quindi visualizzi i singoli elementi del vettore e il totale. #include <stdio.h> #define DIM 5 void main(void) { int i, voti[DIM], totale = 0; for (i = 0; i <= 4; ++i) printf("Scrivi un voto: "); scanf("%d", &voti[i]); } printf("\nIl totale dei voti "); for (i = 0; i < DIM; ++i) printf("%d ", voti[i]); totale += voti[i]; printf("è %d",totale);
17
Esercizio: somma e media
Esercizio: somma e media. Modificare il programma precedente in modo che fornisca anche la media dei voti. #include <stdio.h> #define DIM 5 void main(void) { int i; float voti[DIM], totale = 0.; for (i = 0; i <= 4; ++i) printf("Scrivi un voto: "); scanf("%f", &voti[i]); } printf("\nIl totale dei voti "); for (i = 0; i < DIM; ++i) printf("%3.0f ", voti[i]); totale += voti[i]; printf(“è %4.0f\n",totale); printf("La media dei voti è %f", totale/DIM);
18
Da vettore a istogramma
Da vettore a istogramma. Spesso può essere utile rappresentare i valori delle componenti di un vettore nel formato di un grafico a barre o istogramma, facendo visualizzare a fianco di ogni valore una barra composta da altrettanti caratteri ▓ (di codice ASCII 178). Ad es., si potrebbe volere una rappresentazione di questo tipo:
19
Le barre possono essere disegnate con un ciclo for nidificato, all’uscita del quale un carattere \n fa avvenire la stampa del prossimo valore a riga nuova, come indica il programma seguente. #include <stdio.h> #define DIM 10 int main() { int n[DIM] = {19, 3, 15, 7, 11, 9, 13, 5, 17, 1}; int i, j; printf("%s", "Elemento Valore Istogramma\n"); for (i = 0; i < DIM; i++) printf("%5d %10d ", i, n[i]); for (j = 1; j <= n[i]; j++) printf("%c", '▓'); /* alt+178 */ } printf("\n");
20
int val[3][4]; double prezzi[10][5];
Vettori a due dimensioni (matrici) Un vettore a due dimensioni rappresenta una tabella o matrice, nella quale i valori sono organizzati in righe e colonne. Le righe di una matrice sono sostanzialmente dei vettori a una dimensione. Dichiarazione. Per dichiarare che val è un vettore di interi a due dimensioni, corrispondente alla tabella scriveremo un’istruzione quale: int val[3][4]; Analogamente, l’istruzione double prezzi[10][5]; dichiara che la matrice prezzi consiste in 10 righe e 5 colonne di numeri in doppia precisione, mentre
21
char codici[6][26]; dichiara che la matrice codici consiste in 6 righe e 26 colonne di caratteri. Per individuare ciascun elemento di una matrice, lo si identifica con la sua posizione in essa. Come mostra la figura, la scrittura val[1][3] identifica in modo univoco l’elemento nella riga 1, colonna 3.
22
Come i vettori a una dimensione, anche le matrci si possono usare in qualsiasi punto in cui siano valide le variabili scalari. Esempi di istruzioni che usano gli elementi della matrice val sono: num = val[2][3]; val[0][0] = 62; nuovo_num = 4 * (val[1][0] - 5);
23
le parentesi interne possono essere omesse
Inizializzazione. Come i vettori a una dimensione, anche le matrici possono essere inizializzate all’interno delle loro istruzioni di dichiarazione, elencando i valori iniziali entro parentesi {} separate da virgole. Ad es., la dichiarazione int val[3][4] = { {8, 16, 9, 52}, {3, 15, 27, 6}, {14, 25, 2, 10} }; dichiara val come una matrice di interi con 3 righe e 4 colonne, con i valori iniziali dati nella dichiarazione. Il primo gruppo di parentesi interne contiene i valori della riga 0 della matrice, il secondo quelli della riga 1, ecc. Sebbene le virgole nelle parentsi d’inizializzazione siano necessarie, le parentesi interne possono essere omesse dato che l’inizializzazione avviene comunque riga per riga. Quindi la precedente dichiarazione può essere sostituita da: int val[3][4] = {8,16,9,52,3,15,27,6,14,25,2,10};
24
Visualizzazione. Come i vettori a una dimensione, anche le matrici possono essere visualizzate
con istruzioni relative ai singoli elementi, oppure con dei cicli, sia for sia while. Il programma seguente visualizza gli elementi di una matrice 3 * 4 con due cicli for nidificati, controllati quello esterno dalla variabile ri (che stampa le righe), quello interno dalla variabile co (che stampa le colonne). #include <stdio.h> void main(void) { int ri, co, val[3][4]={8,16,9,52,3,15,27,6,14,25,2,10}; printf("Visualizza vettore con ciclo for nidificato"); for (ri = 0; ri < 3; ++ri) printf("\n"); /* stampa ciascuna riga a linea nuova */ for (co = 0; co < 4; ++co) printf("%2d ", val[ri][co]); }
25
Ecco l’uscita prodotta:
Visualizza vettore con ciclo for nidficato
26
#include <stdio.h> void main(void) {
Moltiplicazione per uno scalare. Come primo esempio di operazioni con le matrici, scriviamo un programma che moltiplichi per 10 ciascuna componente della matrice precedente, quindi visualizzi i valori calcolati. #include <stdio.h> void main(void) { int ri, co, val[3][4]={8,16,9,52,3,15,27,6,14,25,2,10}; printf("\nVisualizza gli elementi moltiplicati\n"); for (ri = 0; ri < 3; ++ri) printf("\n"); for (co = 0; co < 4; ++co) printf("%3d ", val[ri][co]*10); } Ecco l’uscita prodotta: Visualizza gli elementi moltiplicati
27
Esercizio. Sommare tra loro gli elementi della precedente matrice a 3 righe e 4 colonne.
#include <stdio.h> void main(void) { int ri, co, totale=0; int val[3][4]={8,16,9,52,3,15,27,6,14,25,2,10}; printf("La somma degli elementi della matrice"); for (ri = 0; ri < 3; ++ri) printf("\n"); for (co = 0; co < 4; ++co) totale = totale + val[ri][co]; printf("%2d ", val[ri][co]); } printf("\nè %d", totale);
28
Tavola pitagorica. Abbiamo già visto il diagramma di flusso per stampare la tavola pitagorica.
29
Possiamo adesso tradurlo nel seguente programma C:
#include <stdio.h> main() { int ri, co, n; printf("Scrivi l'ordine della tavola pitagorica: "); scanf("%d", &n); for (ri = 1; ri <= n; ri++) for (co = 1; co <= n; co++) printf("%4d", ri*co); printf("\n"); }
30
Ecco l’uscita prodotta:
31
Triangolo di Tartaglia
Triangolo di Tartaglia. Come è noto, se consideriamo le potenze successive del binomio (a + b), ossia: (a + b)0 = 1 (a + b)1 = a + b (a + b)2 = a2 + 2*a*b + b2 (a + b)3 = a3 + 3*a2*b + 3*a*b2 + b3 (a + b)4 = a4 + 4*a3*b + 6*a2*b2 + 4*a*b3 + b4 e scriviamo i soli coefficienti dei vari monomi
32
otteniamo una tabella nota come “triangolo di Tartaglia”
otteniamo una tabella nota come “triangolo di Tartaglia”. In essa gli elementi di ciascuna riga si possono ottenere con il seguente algoritmo: il primo elemento è sempre uguale a “1”; ciascun altro elemento si ottiene sommando i due che gli “stanno sopra” nella riga precedente (ossia: il k-mo elemento di una riga si ottiene sommando il k-1-mo e il k-mo elemento della riga precedente). Per calcolare il triangolo useremo una matrice di ordine N, quindi calcoleremo dapprima la prima riga, poi le righe successive, quindi stamperemo l’intera tabella al solito modo. Il programma completo è il seguente:
34
Esercizio. Modificare il programma precedente in modo che stampi il triangolo di Tartaglia nella sua forma più usuale: A tale scopo è sufficiente modificare la parte del programma che stampa il triangolo (evidenziata in grigio), facendo stampare un numero adeguato di spazi vuoti all’inizio di ogni riga e tra un numero e l’altro. Ricordiamo che: ciascun intero è giustificato a destra nel proprio campo; tra un campo numerico e il successivo il C stampa uno spazio vuoto.
35
Dato che ciascun elemento del triangolo viene stampato in un campo di 4 caratteri, per ottenere l’allineamento voluto sarà necessario stampare: N-r-1 gruppi di 3 spazi vuoti all’inizio della r-esima riga: uno spazio vuoto dopo ciascun campo numerico. Il programma modificato è pertanto il seguente:
36
#include <stdio.h>
#define N 10 main() { int r, c, TT[N][N], k; TT[0][0] = 1; for (c = 1; c < N; c++) TT[0][c] = 0; for (r = 1; r < N; r++) TT[r][0] = 1; TT[r][c] = TT[r-1][c-1] + TT[r-1][c]; } for (r = 0; r < N; r++) for (k = 0; k < 3*(N-r-1); k++) printf ("%c", '*'); for (c = 0; c <= r; c++) printf("%4d %c", TT[r][c], ' '); printf("\n");
37
Esercizio. Modificare il programma precedente in modo che stampi il triangolo di Trataglia nella forma seguente: È sufficiente apportare due semplici modifiche alla sezione di stampa del programma precedente: invertire l’ordine con cui varia l’indice di riga del ciclo for esterno, facendolo partire da N-1 e arrivare a 0; spostare il ciclo for interno che stampa gli spazi vuoti dopo il ciclo for interno che stampa gli elementi della riga generica (con una leggera modifica del valore finale del suo contatore)
38
printf("%4d %c", TT[r][c], ' '); printf("\n");
#include <stdio.h> #define N 10 main() { int r, c, TT[N][N], k; TT[0][0] = 1; for (c = 1; c < N; c++) TT[0][c] = 0; for (r = 1; r < N; r++) TT[r][0] = 1; TT[r][c] = TT[r-1][c-1] + TT[r-1][c]; } for (r = N-1; r >= 0; r--) for (c = 0; c <= r; c++) printf("%4d %c", TT[r][c], ' '); printf("\n"); for (k = 0; k <= 3*(N-r); k++) printf ("%c", ' ');
39
Vettori a più di due dimensioni
Vettori a più di due dimensioni. Sebbene i vettori a più di due dimensioni non siano usati molto di frequente, il C consente di dichiarare un numero qualsiasi di dimensioni, semplicemente elencando il valore massimo di ciascuna dimensione. Ad es., la dichiarazione int risposta[4][10][6]; dichiara un vettore a tre dimensioni. Il primo elemento del vettore si indica risposta[0][0][0] e l’ultimo risposta[3][9][5].
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.