Sei sulla pagina 1di 8

Array TEORIA

DIPARTIMENTO DI ELETTRONICA /* gli array (detti anche vettori) rappresentano una sequenza
INFORMAZIONE E BIOINGEGNERIA di variabili di ugual tipo, memorizzate in celle di memoria consecutive,
accessibili attraverso un indice numerico */
Fabio Marfia
// ----- definizione -----
fabio.marfia@polimi.it
float array_di_float[7]; // array di sette variabili di tipo float
/* Attenzione: la definizione non può usare variabili per indicare
la dimensione dell’array */

C - Array e stringhe char array_di_caratteri[3]; // array di tre variabili di tipo char

int array_di_interi_inizializzati[] = {1, 4, 2}; // array inizializzato


// contestualmente alla definizione

// ----- accesso a una delle variabili dell’array -----


Esercitazione int n;
n = array_di_interi[2]; // a n è assegnato il valore dell’elemento
// in posizione 2 dell’array

array_di_interi[4] = 5; // all’elemento in posizione 4 viene assegnato


// il valore 5

/* Attenzione: */
/* l’indice dell’array va da 0 (primo elemento)
a N-1 (ultimo elemento), dove N è la dimensione dell’array */

26 ottobre 2018 /* il nome di un array indica l’indirizzo di memoria del primo elemento */
Informatica A, Ingegneria Gestionale, Anno Accademico 2018-2019
1 2

Matrici TEORIA Stringhe TEORIA

/* le matrici sono array a più dimensioni */ /* le stringhe sono array di caratteri ‘speciali’ */

// definizione // definizione
float matrice2D[5][4]; // matrice a 5 righe e 4 colonne di float char parola[] = “hello”; // stringa inizializzata con valore “hello”
char matrice3D[2][3][7]; // ‘cubo’ di 2 × 3 × 7 char /* le stringhe terminano con carattere speciale ‘\0’; quindi la variabile
parola ha 6 elementi: ‘h’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\0’ */

/* il carattere speciale da usare nel formato di printf e scanf per le


// l’accesso alle singole ‘celle’ avviene come con gli array stringhe è %s */
float f; printf(“parola è %s”, parola);
f = matrice2D[1][3]; // a n è assegnato il valore dell’elemento
// in riga 1 (seconda riga) /* il nome di una variabile stringa è di per sé l’indirizzo del primo
// e colonna 3 (quarta colonna) carattere; per questo motivo, la scanf che acquisisce una stringa
non ha bisogno dell’operatore & prima del nome di variabile */
scanf(“%s”, parola);
matrice3D[0][2][3] = ‘z’; // all’elemento con ‘coordinate’ (0,2,3)
// viene assegnato il carattere z

3 4
Stringhe (continua) TEORIA Conversione in binario con array

/* grazie alla libreria string.h sono disponibili alcune funzioni Realizzare un programma in C che, acquisito un numero intero
di manipolazione delle stringhe */
positivo o nullo, costruisca un array di bit che ne rappresentino
char a[] = “hello”; la conversione in binario naturale.
char b[64]; // b può avere al più 64 caratteri
int x;
Nota: è la generalizzazione del problema già visto in precedenza.
// lunghezza di una stringa
x = strlen(a); // x assume il valore 5 (numero di caratteri
// ‘validi’ prima del terminatore \0)

// copiatura
strcpy(b, a); // in b viene copiata la stringa contenuta in a

// confronto
x = strcmp(a, b); // x è 0 se a e b uguali,
// x < 0 se a precede b,
// x > 0 se a segue b

5 6

Conversione in binario con array (continua) Conversione in binario con array (continua)

I passi da fare sono: #include <stdio.h>

#define MAX_BIT 5
a. leggere il numero intero da convertire, controllando
int main() {
che sia non negativo;
b. applicare il metodo dei resti, memorizzando i bit in un array; int value_dec; /* dichiarazione della variabile per la lettura del numero da convertire */
c. stampare i bit dell’array. // dichiarazioni delle variabili per la memorizzazione dei bit della conversione
int bit_array[MAX_BIT] = {0};
Nel passo c, bisognerà prestare attenzione all’ordine dei bit: int bit_index = 0; // dichiarazione della variabile indice dei bit
il metodo dei resti li calcola dall’ultimo al primo, rispetto all’ordine
in cui vanno mostrati a video. int bit_valid = 0; /* intero usato come variabile di controllo: si è già raggiunto un primo bit valido? 0 = no, 1 = sì */

int j; // indice di iterazione

printf("Inserire un numero intero positivo da convertire: ");


scanf("%d", &value_dec);

// finché il valore letto non è positivo, richiedere


while(value_dec < 0 ){
printf("Il numero inserito è negativo. \nInserire un numero intero positivo: ");
scanf("%d", &value_dec);
}

7 8
Conversione in binario con array (continua) Conversione in binario con array (continua)

// applicazione del metodo dei resti // caso limite: il numero immesso dall'utente è 0, e non ci sono bit 1
while(value_dec > 0 && bit_index < MAX_BIT){ if(bit_valid == 0){ // bit_valid non è mai stato settato a 1
// calcolo del resto per bit in corso // => i bit dell'array sono tutti 0
bit_array[bit_index] = value_dec%2; printf("0");
// prossimo passaggio }
bit_index++; }
value_dec = value_dec/2; // divisione di interi, in value_dec va la parte intera
} return 0;
}
// controllo: non è stata terminata la conversione (quindi MAX_BIT non sufficienti)?
if(value_dec > 0) {
printf("Il numero eccede il max rappresentabile con %d bit.\n", MAX_BIT);
} else {
printf("Il numero binario è: ");
// stampa dei bit, dall'ultimo non 0 al primo
for(j = bit_index-1; j >= 0; j--){
// il bit corrente è diverso da 0?
if(bit_array[j] != 0){
// se sì, stampare e segnalare che da qui in poi vanno stampati anche gli 0
printf("%d", bit_array[j]);
bit_valid = 1; // fosse già stato settato a 1, nessun cambiamento

} else {
// se bit è uguale a 0, stampare solo se si è già incontrato in passato un 1
if(bit_valid == 1){
printf("%d", bit_array[j]);
}
}
}
9 10

Sopra la soglia Sopra la soglia (continua)

Realizzare un programma in C che realizzi questo comportamento: I passaggi necessari sono:

1. acquisire dall’utente una sequenza di numeri interi positivi terminanti a. acquisizione e memorizzazione dei numeri nell’array;
con 0, memorizzandoli in un array; b. acquisire il valore di soglia;
2. acquisire dall’utente un numero positivo num; c. per ogni numero memorizzato nell’array, verificare se è superiore
3. mostrare a video tutti i valori nell’array superiori a num. alla soglia, e in questo caso stamparlo a video.

11 12
Sopra la soglia (continua) Sopra la soglia (continua)

#include <stdio.h> // acquisizione del valore soglia


#define MAX_NUMBERS 100 printf("Inserire un numero positivo 'soglia': \n ");
do {
int main() { scanf("%d", &num);
// dichiarazione di variabili
int numbers[MAX_NUMBERS]; // array dei numeri immessi dall'utente, if(num <= 0){
// al più c'è posto per MAX_NUMBERS numeri
int numbers_index = 0; // indice per inserire i numeri nell'array printf("Valore non valido \n ");
int i; // indice di iterazione
int cur_value; // valore corrente }
int num; // valore soglia
} while (num <= 0);
// acquisizione dei numeri
printf("Inserire una sequenza di al più %d numeri positivi (inserire 0 // verifica dei valori sopra la soglia
per terminare): \n ", MAX_NUMBERS); printf("I numeri superiori alla soglia %d sono: ", num);
do {
scanf("%d", &cur_value); // per tutti i numeri validi nell'array
for(i = 0; i < numbers_index; i++){
if(cur_value > 0){ // nell'array, i numeri saranno quelli da posizione 0
numbers[numbers_index] = cur_value; // a posizione numbers_index - 1
numbers_index++; if(numbers[i] > num){ // se sopra soglia
printf("%d ", numbers[i]);
} else if(cur_value < 0){ }
}
printf("Valore non valido \n ");

} return 0;
} while (cur_value != 0 && numbers_index < MAX_NUMBERS); // al termine del ciclo, }
// numbers_index sarà pari al numero
13
// di numeri utili inseriti 14

Concatenazione di stringhe Concatenazione di stringhe (continua)

Realizzare un programma in C che, date due stringhe, calcoli una terza I passaggi sono:
stringa data dalla concatenazione delle prime due.
a. acquisire le due stringhe da concatenare;
Esempio: b. costruire la stringa concatenata:
stringa1 = “abcdefg” 1. ricopiare tutti i caratteri utili della prima stringa;
stringa2 = “hilmnopq” 2. aggiungere in coda i caratteri utili della seconda stringa.
stringa_concat = “abcdefghilmnopq”

15 16
Concatenazione di stringhe (continua) Concatenazione di stringhe (continua)

#include <stdio.h> // a fine del ciclo, i avrà come valore il numero di caratteri copiati
#define MAX_LENGTH 100 // da str1 a strTot

int main() { for (j = 0; str2[j] != '\0'; j++) { // copiare i caratteri della seconda stringa
strTot[i+j] = str2[j];
// definizione di variabili // il primo carattere della seconda stringa va ricopiato in posizione i
char str1[MAX_LENGTH], str2[MAX_LENGTH], strTot[2*MAX_LENGTH]; }
// le due stringhe e la stringa concatenata (di lunghezza possibile doppia)
strTot[i+j] = '\0'; // completare nuova stringa con carattere di fine stringa \0
int i, j; // indici di iterazione
printf("\nLa stringa concatenata è %s", strTot);
// acquisizione delle due stringhe
printf("Inserisci la prima stringa:\n");
scanf("%s",str1); return 0;
printf("Inserisci la seconda stringa:\n"); }
scanf("%s",str2);

// copia dei caratteri 'validi' della prima stringa


// scandire la prima stringa fino a trovare il carattere di fine stringa \0 Osservazione: il programma è costruito per ricevere stringhe non contenenti lo spazio.
for (i = 0; str1[i] != '\0'; i++){ La funzione scanf, infatti, in presenza di uno spazio valuta l’input dell’utente, e in caso
strTot[i] = str1[i];
} di %s non considera ciò che è inserito dopo lo spazio stesso.

17 18

Controllo dei caratteri Controllo dei caratteri (continua)

Realizzare un programma in C che permetta di verificare se una stringa I passi sono:


è palindroma (ossia, tale per cui se letta in senso inverso rimane identica).
Per semplificare, si fa distinzione tra maiuscole e minuscole (‘a’ != ‘A’). a. acquisire la stringa da terminale;
b. verificare se la stringa è palindroma:
Esempi: 1. per ogni carattere in posizione i controllare se uguale
• anna a quello in posizione ‘specchiata’ (lunghezza_stringa - i);
• AnnA 2. se tutti i caratteri verificano questa condizione,
• ailatiditalia la stringa è palindroma.
• abCdEdCba
Nel caso i caratteri della stringa siano dispari, il carattere centrale
non modifica la situazione.

19 20
Controllo dei caratteri (continua) Controllo dei caratteri (continua)

#include <stdio.h> // finché i caratteri della stringa sono 'a specchio' (o finché non si sono
// controllati tutti i caratteri), aumentare il contatore i
#define MAX_LENGTH 100 while(word[i] == word[count-i] && i < count-i){
i++;
int main() { }

// definizione di variabili if(i >= count-i){ // il conteggio è finito quando si è esaurita la stringa
char word[MAX_LENGTH]; // stringa acquisita da terminale
int count = 0, i; // variabile di conteggio e indice di iterazione printf("Stringa palindroma");

// acquisizione della stringa } else { // il conteggio è finito prima


printf("Inserire la stringa da controllare: \n");
scanf("%s", word); printf("Stringa non palindroma");

// conteggio dei caratteri nella stringa (si potrebbe fare usando la funzione }
// strlen di string.h)
for (i = 0; word[i] != '\0'; i++){
count++; return 0;
} }
count--; // count è ora l'indice dell'ultimo carattere nella stringa

i = 0; // reset dell'indice i per essere riutilizzato come contatore

21 22

Anagrammi Anagrammi (continua)

Realizzare un programma in C che date due stringhe controlli I passi da fare sono:
se sono una l’anagramma dell’altra.
a. acquisire le due stringhe da controllare;
b. verificare se l’una è anagramma dell’altra, ossia:
1. le due stringhe hanno stessa lunghezza;
2. le lettere usate nella prima stringa sono usate lo stesso numero
di volte nella seconda stringa

23 24
Anagrammi (continua) Anagrammi (continua)

#include <stdio.h> // controllo anagrammi: le due stringhe sono anagrammi se i caratteri della prima
#include <string.h> // stringa appaiono lo stesso numero di volte anche nella seconda
for (i = 0; i < len && is_anagram == 1; i++) {
#define MAX_LENGTH 100 // per ogni carattere in a (escluso ‘\0’) e finché is_anagram è 1
contA = 0; // reset del contatore di occorrenze nella prima stringa
int main() { contB = 0; // reset del contatore di occorrenze nella seconda stringa

// dichiarazione di variabili for (j = 0; j < len; j++) {


char a[MAX_LENGTH], b[MAX_LENGTH]; // stringhe da comparare if (a[j] == a[i]){
int len; // lunghezza della prima stringa contA++; // il carattere corrente è in a, aumenta contatore
int contA, contB; // contatori per le occorrenze dei caratteri }
int i, j; // indici di iterazione if ( b[j] == a[i] ){
int is_anagram = 1; // variabile 'di verità': è anagramma (1) o no (0) contB++; // il carattere corrente è in b, aumenta contatore
}
// acquisizione delle stringhe }
printf("Inserire la prima stringa: "); if ( contA != contB ) {
scanf("%s", a); is_anagram = 0; // se il conteggio è diverso, le due stringhe
// non sono anagrammi (e ciclo for termina)
printf("\n\nInserire la seconda stringa: "); }
scanf("%s", b); }
}
// verifica della lunghezza delle stringhe
len = strlen(a); if(is_anagram != 0){ // equivale a if(is_anagram)
if(len != strlen(b)){ printf("Le due stringhe sono anagrammi\n");
is_anagram = 0; // se le stringhe non hanno pari lunghezza, } else {
// sicuramente non sono anagrammi printf("Le due stringhe non sono anagrammi\n");
} else { }
return 0;
}
25 26

Matrice di dispari Matrice di dispari (continua)

Realizzare un programma in C che acquisisca una matrice di valori interi I passaggi necessari sono:
di dimensione 5 × 5, la stampi a video, e poi ricopi i soli elementi dispari
in una seconda matrice 5 × 5, lasciando eventuali ‘buchi’ in fondo. a. acquisire la matrice iniziale, leggendo da terminale i valori numerici;
Quindi, ad esempio: b. percorrere la matrice, analizzando ogni suo elemento, e ricopiare gli
elementi dispari nella seconda matrice.

1 2 1 98 -27 1 1 -27 7 -77


Nel passo b, si dovrà tenere conto che la seconda matrice dovrà ‘compattare’
gli elementi dispari, perciò a ogni iterazione si dovrà tenere traccia della prima
42 7 -77 0 13 13 35 87 19 -5 cella libera.
2 35 12 87 19 77 -1 -3 -53

-5 77 4 42 0

-1 -3 32 -53 12

27 28
Matrice di dispari (continua) Matrice di dispari (continua)

#include <stdio.h> // ricopiatura degli elementi dispari


#define ROWS 5 for(i = 0; i < ROWS; i++) {
#define COLUMNS 5 for(j = 0; j < COLUMNS; j++) {
if(mat1[i][j]%2 != 0) { // l'elemento è dispari => va ricopiato
int main() { // nella seconda matrice nel primo posto utile
int i, j, k = 0, r = 0; // indici di iterazione nelle matrici mat2[r][k] = mat1[i][j];
int mat1[ROWS][COLUMNS], mat2[ROWS][COLUMNS] = {0}; k++; // k tiene conto della colonna corrente nella seconda matrice
// matrice immessa da utente e matrice dei dispari if(k == COLUMNS) {
// se si arriva a fine riga (ossia, k ha raggiunto il numero di colonne)
// acquisizione della matrice // si va 'a capo': si riparte dalla colonna 0 e si va alla riga successiva
printf("Inserire i valori (numeri interi) della matrice %dx%d (i valori k = 0;
saranno inseriti riga per riga):\n", ROWS, COLUMNS); r++;
for(i = 0; i < ROWS; i++){ }
for(j = 0; j < COLUMNS; j++){ }
scanf("%d", &mat1[i][j]); }
} } // al termine di questo ciclo, (r,k) saranno le 'coordinate' del primo valore
} // vuoto nella seconda matrice

// stampa a video della prima matrice // stampa a video della seconda matrice (i valori validi sono nelle prime r righe)
printf("Matrice originaria: \n"); printf("\n\nMatrice 'dispari': \n");
for(i = 0; i < ROWS; i++){ for(i = 0; i < ROWS; i++){
for(j = 0; j < COLUMNS; j++){ for(j = 0; j < COLUMNS; j++){
printf("%4d ", mat1[i][j]); if(i < r || (i == r && j < k)){ // per escludere i valori non validi (oltre r,k)
// %4d istruisce printf a usare almeno 4 caratteri per la stampa del valore printf("%4d ", mat2[i][j]);
} }
// fine riga }
printf("\n"); printf(“\n"); // fine riga
} }
return 0;
29 } 30