====== Tipi di dato strutturato ====== Il tipo //int// è detto //tipo semplice//, così come lo sono anche //float// oppure //char//, in quanto possono contenere un solo valore. Il tipo //array// e altri ancora sono detti "//tipo strutturati//", perché composti da più elementi. Se il problema chiede di calcolare la media dei 15 voti di uno studente, non conviene dichiarare 15 variabili di tipo semplice per memorizzare i 15 voti, ma conviene usare una sola variabile di tipo strutturato, composta da 15 elementi. Il tipo array è un'eredità del linguaggio C. In C++ esistono tanti altri tipi di dato che possono essere usati al posto del tipo array. Qui verrà solo accennato per motivi storici. ===== Esempio ===== È utile riprendere l'[[appunti3s:programmazione_strutturata#struttura_iterativa_precondizionale|esempio 36 ]]: >> Scrivere un programma che chieda cinque numeri e ne visualizzi la somma Rispondere alle seguenti domande: - Nella soluzione //quante variabili// sono state utilizzate per memorizzare i cinque numeri? - Ci sarebbero state più istruzioni da aggiungere se invece di cinque numeri fossero stati cinquanta? Provare a rispondere alle stesse domande, nel caso in cui il problema venisse modificato nel seguente modo: >> Scrivere un programma che chieda cinque numeri e li visualizzi in modo ordinato Questa volta è necessario mantenere in memoria in modo distinto tutti i numeri per poterli ordinare e visualizzare dopo l'ordinamento. Sarebbe necessario avere cinque variabili, oppure anche cinquanta! È intuibile che la soluzione di un problema che deve gestire cinquanta variabili è troppo complessa e che sarebbe utile avere una variabile strutturata che le contenesse tutte insieme e da cui sia più facile richiamarle. Se si usassero cinque variabili come a, b, c, d, e, sarebbe impossibile automatizzare la ripetizione all'interno di una struttura iterativa. Viceversa se le variabili fossero qualcosa come a1, a2, a3, a4, a5, perché potrebbero essere richiamate dentro la struttura iterativa usando un generico ai. =====Array===== In italiano vengono chiamati anche vettori, ma questo termine andrebbe evitato per non fare confusione con il tipo //std%%::%%vector// introdotto dalla libreria standard del C++. Le variabili strutturate di tipo //array// derivano dal linguaggio C e sono scomode da usare perché, ad esempio, non c'è nessun controllo del superamento della posizione dell'ultimo elemento. Quindi, nel C++, al loro posto, in generale, è consigliabile usare degli //oggetti// chiamati //std%%::%%[[appunti3s:tipi di dato strutturato array#vector]]//, Qui array verrà solo accennato per motivi storici. * Un array è una struttura che raggruppa tanti elementi, tutti di uno stesso tipo. * Per indicare la posizione di un elemento dell'array si può usare un indice int o char. * Se un vettore è di 9 elementi, l'indice va da 0 a 8 Quando si definisce un array, il compilatore deve riservare la quantità di memoria necessaria. Per fare questo il compilatore deve conoscere il numero dei suoi elementi: int a[40]; // corretto int a[]; // errore ==== array di char ==== Un vettore di tipo char viene anche chiamato “stringa in stile C” (da non confondere con le std%%::%%string del C++) e viene fatta terminare sempre con un valore nullo che in ottale si indica con \0 (equivale in binario a 00000000). Non confonderlo con il carattere '0' o con l'intero 0. char w[] = "miao"; // corretto char w[] = {'m','i','a','o','\0'} ; // corretto w è un vettore di 5 elementi!!! ^ posizione ^ 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ | valore | m | i | a | o | \0 | | | // questo programma è stato scritto da Fabio // crea un array, lo inizializza e lo visualizza #include int main() { int a1[9]={70,71,72,79,44,-1,58,30}; for (int indice=0; indice<9; indice++) std::cout << a1[indice] << ' ' ; //notare la sintassi delle parentesi quadrate std::cout << std::endl; return 0; } Gli array sono utili per gestire grandi quantità di dati dello stesso tipo. Si può accedere, leggere e modificare un singolo elemento del vettore usando l'indice, dentro le parentesi quadrate. Grazie alla presenza dell'indice le operazioni sugli array possono essere automatizzate, ad esempio, percorrendo l'array usando un'istruzione di iterazione come //for//. // questo programma è stato scritto da Fabio // crea un array, lo inizializza e ne visualizza la somma di tutti gli elementi #include int main() { int totale=0; int a1[9]={70,71,72,79,44,-1,58,30}; for (int indice=0; indice<9; indice++) // l'indice si può dichiarare dentro il for (solo quando serve) totale = totale + a1[indice] ; //notare la sintassi delle parentesi quadrate std::cout << totale << std::endl; return 0; } Rivedere il precedente esempio, immaginando di dover visualizzare e sommare 90 valori interi invece di 9. Come potrebbe essere risolto un problema del genere senza l'uso degli array? * Il numero degli elementi deve essere stabilito al momento della compilazione. * solo per le variabili globali si può stabilire anche run time. * Il linguaggio **non** effettua controlli sul superamento dei limiti di un array ==== Array e puntatori a....==== Da un certo punto di vista array e puntatori hanno delle somiglianze e delle differenze. Si vedrà presto il legame tra questi due argomenti nel capitolo [[appunti3s:gestione della memoria#pointers|gestione della memoria]]. ====Array come stringhe di parole==== Come è ben noto, in C++ per memorizzare una parola si usa il tipo //std%%::%%string//, ma tale tipo di dato non era presente nel linguaggio C. In C gli array erano utilizzati anche per contenere una sequenza di caratteri, ma la sequenza doveva terminare con il valore //\0// (Zero, da non confondere con il carattere ASCII '0'). Esiste una funzione che converte le variabili C++ std%%::%%string in array in stile C. std::string variabileString = "ciao"; char a1[50] = c_str(variabileString); Esempio in cui viene usata proprio questa funzione: [[appunti3s:stream#file]] ==== Array di array ==== int v[3][2]; È un array di 3 elementi ognuno dei quali è a sua volta un array di 2 elementi. Alcuni rappresentano gli array bidimensionali come una matrice, ma, in memoria, gli elementi sono disposti in modo adiacente facendo scorrere l'indice più esterno a partire da sinistra. ==== Argomenti della linea di comando ==== La forma con cui si dichiara la funzione main() può contenere i seguenti argomenti int main(int argc, char[][] argv) Questa forma permette di passare dei parametri al main() dalla linea di comando: programma.exe opzione1 opzione2 * //argc// è una variabile che contiene il numero delle opzioni passate dall'utente * //argv// contiene tutte le opzioni passate (è l'indirizzo di un array di array di char), per comprendere il quale sarebbe meglio studiare i puntatori.([[appunti3s:gestione della memoria#pointers]]) esempio... ===== Vector ===== //std:vector// è uno dei tipi di dato strutturato tra i più utili che, rispetto agli array, lavora a livello più alto con più controlli sugli errori di programmazione. Come gli array permette di memorizzare un insieme di valori dello stesso tipo, ma rispetto agli array possiede enormi vantaggi. Ad esempio, trattandosi di una struttura della libreria standard , vi si possono applicare tutti gli algoritmi presenti nella [[appunti3s:STL|standard template library]]. I vector sono degli oggetti e per poter utilizzare tutte le utili funzioni fornite dalla libreria standard è necessario conoscere la [[appunti3s:programmazione orientata agli oggetti]]... Alcuni esempi d'uso dei vector sono nel capitolo [[appunti3s:STL#vector|standard template library]]. A voler essere precisi, bisogna dire che vector non è un "vero" tipo di dato, ma un container...