Basi Programmazione c++

Embed Size (px)

Citation preview

  • 7/29/2019 Basi Programmazione c++

    1/55

    Le Basi della Programmazione 1

    Linguaggio C++Le basi

  • 7/29/2019 Basi Programmazione c++

    2/55

    Le Basi della Programmazione 2

    1. Linguaggio C++, la storia

    Nel 1972 Dennis Ritchie progettava e realizzava, presso i Bell Laboratories, la prima versione dellinguaggio C. Ritchie aveva ripreso e sviluppato molti dei costrutti sintattici utilizzati nella costruzionedel sistema operativo UNIX da Ken Thompson.

    Successivamente gli stessi Thompson e Ritchie riscrissero in C il codice di UNIX. Da allora il C hasubito pochissime trasformazioni, mantenendosi un linguaggio di alto livello che possiede un ristretto

    insieme di costrutti e di parole chiave, ma con una straordinaria forza espressiva. Il C consente diprogrammare in maniera modulare, utilizzando macro e funzioni, di interagire direttamente confunzioni tipiche del basso livello come ad esempio lindirizzamento assoluto di memoria. Perleleganza della sua sintassi e la compattezza dei costrutti, il C una sfida permanente alle capacitintellettuali del programmatore.

    Quando nella prima met degli anni Ottanta, nella teoria della programmazione si sviluppano le basiper la OOP (Object Oriented Programming, programmazione orientata agli oggetti) si capisce prestoche quella sar la chiave di volta per lo sviluppo di applicazioni general-purpose. Ecco allora che ildanese Bjarne Stroustrup propone nel 1983 un nuovo linguaggio denominato C con classi e

    successivamente C++. Mantenendo una compatibilit quasi assoluta con il C, il C++ un linguaggioObject Oriented che diventer lo standard de facto per la programmazione di applicativi nel ventennio aseguire.

    Il C++ rappresenta un linguaggio completamente autonomo rispetto al C, pur utilizzandonesostanzialmente la sintassi. In particolare, lintroduzione di costrutti quali i template e le classi rende ilC++ un linguaggio multi paradigma, principalmente quello a oggetti. Ci che ha sempre differenziato ilC e il C++ da altri linguaggi artificiali il fatto di essere stati creati da dei programmatori chedovevano fronteggiare particolari esigenze quali la codifica dei programmi e lorganizzazione delcodice e non da un gruppo di ricerca appositamente creato allo scopo.

    Questo ha portato un sacco di programmatori a inviare commenti, suggerimenti e migliorie a Ritchie e

    Stroustrup nei primi anni dello sviluppo dei due linguaggi ottenendo un prodotto sicuramente pimalleabile e adatto alle necessit.

  • 7/29/2019 Basi Programmazione c++

    3/55

    Le Basi della Programmazione 3

    I paradigmi di programmazione

    Quando si utilizzavano sistemi operativi a linea di comando, come UNIX e il DOS, lunica

    programmazione possibile era basata sul paradigma imperativo. Il paradigma imperativo (da imperio,comando) fondato sullesplicita richiesta di eseguire un comando.

    In tale contesto il programmatore dovr privilegiare lesame del processo di calcolo in quanto precisasequenza di azioni da svolgere. Le strutture di controllo assumono la forma di istruzioni di flusso(GOTO, FOR, IF/THEN/ELSE, ecc.) e il calcolo procede per iterazione piuttosto che per ricorsione. Ivalori delle variabili sono spesso assegnati a partire da costanti o da altre variabili (assegnamento) eraramente per passaggio di parametri (istanziazione).

    La programmazione strutturata una tecnica il cui scopo di limitare la complessit della struttura delcontrollo dei programmi. Il programmatore vincolato ad usare solo le strutture di controllo canoniche

    definite dal Teorema di Bohm-Jacopini, ovvero la sequenza, la selezione e il ciclo, evitando leistruzioni di salto incondizionato.

    La programmazione orientata agli oggetti (OOP) si dimostrata la pi adeguata nello sviluppo disistemi software complessi. In questo paradigma il concetto principale quello di oggetto in quantometafora di un concetto del mondo reale. In tale contesto il programmatore interpreta lo svolgersi delleazioni come una sequenza di interazioni fra oggetti, quindi come un flusso (pi) semplice dainterpretare e sviluppare.

    La programmazione guidata dagli eventi (EDP, event driven programming) perde la sequenza logicaprecisa descritta dai precedenti paradigmi, ma il flusso delle azioni viene guidato dagli eventi che ilprogramma intercetta. Evento linterazione del mondo esterno con il programma, quindi la pressionedi un tasto sullinterfaccia grafica da parte dellutente, come la stampante che segnala di aver finito lacarta o linchiostro.

    Linguaggi compilati e linguaggi interpretati

    In informatica, un linguaggio di programmazione un linguaggio formale, dotato di una sintassi e diuna semantica ben definite, utilizzabile per il controllo del comportamento di una macchina formale.Lutilit dei linguaggi di programmazione sta nel fatto che le macchine formali sono descrizioniteoriche di strumenti implementati tipicamente come microcontrollori o microprocessori.Sostanzialmente quindi, un linguaggio di programmazione lo strumento che ci permette di creare ilsoftware adatto a controllare strumenti governati da processori. Se si considera infine che si stima cheogni strumento elettronico attualmente in commercio dal valore superiore alle 50 euro contenga un

  • 7/29/2019 Basi Programmazione c++

    4/55

    Le Basi della Programmazione 4

    processore, si capisce subito limportanza dei linguaggi di programmazione nella definizione dellatecnologia moderna.

    Programmare in un dato linguaggio di programmazione significa generalmente scrivere uno o pisemplici file di testo chiamato codice sorgente, seguendo sintassi e semantica del linguaggio scelto. I

    linguaggi di programmazione si dividono dunque in due grandi classi di linguaggi:

    1. linguaggi compilati

    2. linguaggi interpretati.

    I linguaggi compilati sono quelli che sottopongono il codice sorgente a compilazione. Questa loperazione di traduzione del codice sorgente dal linguaggio comprensibile alluomo, quello stabilitodalla sintassi del linguaggio scelto, al linguaggio comprensibile dal processore, definito linguaggiomacchina. Il risultato della compilazione viene solitamente definito codice oggetto. Per fare questo

    ogni linguaggio compilato ha bisogno di un suo proprio compilatore: questo genericamente unprogramma che si occupa della traduzione descritta.

    La compilazione crea dunque un legame fra il codice oggetto prodotto e il processore che dovreseguirlo. Questo crea importanti vantaggi, come la velocit di esecuzione del codice e lefficienzanella gestione della memoria, ma anche svantaggi come una difficile portabilit (su altre architetture)del codice oggetto e a volte anche del codice sorgente.

    Esempi di linguaggi compilati sono il C, C++, Pascal e Fortran.

    I linguaggi interpretati si propongono di eliminare il problema della portabilit. Il codice sorgente in

    questi casi non viene pi compilato per la creazione del codice oggetto, ma coincide esattamente conesso! Viene infatti interpretato in fase di esecuzione riga per riga e tradotto ogni volta nellacorrispondente operazione da eseguire. In questo caso, i linguaggi interpretati necessitano dunque di uninterprete che interpreti e faccia eseguire il codice.

    Linterpretazione in teoria libera dalla dipendenza dalla piattaforma: sar sufficiente avere un interpreteadatto ad ogni piattaforma per poter eseguire il codice ovunque. Daltro canto per si assiste ad ungrosso decadimento delle prestazioni in fase di esecuzione, per il doppio lavoro di dover interpretare edeseguire in real-time.

    Alcuni linguaggi (java, C#) cercano di mitigare questo aspetto negativo dellinterpretazionemantenendo i suoi aspetti positivi, fornendo una sorta di semi-compilazione preventiva che fornisce un

    linguaggio intermedio (bytecode) facilmente interpretabile.Esempi di linguaggi interpretati sono il Basic, il Perl, il Python e in generale tutti i linguaggi discripting.

  • 7/29/2019 Basi Programmazione c++

    5/55

    Le Basi della Programmazione 5

    Valutare un linguaggio di programmazione

    Non ha senso, in generale, parlare di linguaggi migliori o peggiori, o di linguaggi migliori in assoluto:

    ogni linguaggio nasce per affrontare una classe di problemi pi o meno ampia, in un certo modo e in uncerto ambito. Per, dovendo dire se un dato linguaggio sia adatto o no per un certo uso, necessariovalutare le caratteristiche dei vari linguaggi:

    Caratteristiche intrinseche

    Sono le qualit del linguaggio in s, determinate dalla sua sintassi e dalla sua architettura interna.

    Influenzano direttamente il lavoro del programmatore, condizionandolo. Non dipendono n daglistrumenti usati (compilatore/interprete, IDE, linker) n dal sistema operativo o dal tipo di macchina.

    Espressivit: la facilit e la semplicit con cui si pu scrivere un dato algoritmo in un datolinguaggio.

    Didattica: la semplicit del linguaggio e la rapidit con cui lo si pu imparare.

    Leggibilit: la facilit con cui, leggendo un codice sorgente, si pu capire cosa fa e comefunziona. La leggibilit dipende non solo dal linguaggio ma anche dallo stile diprogrammazione di chi ha creato il programma.

    Robustezza: la capacit del linguaggio di prevenire, nei limiti del possibile, gli errori diprogrammazione.

    Modularit: quando un linguaggio facilita la scrittura di parti di programma indipendenti(moduli) viene definito modulare. In genere la modularit si ottiene con luso disottoprogrammi (subroutine, procedure, funzioni) e con la programmazione ad oggetti.

    Flessibilit: la possibilit di adattare il linguaggio, estendendolo con la definizione di nuovicomandi e nuovi operatori.

    Generalit: la facilit con cui il linguaggio si presta a codificare algoritmi e soluzioni diproblemi in campi diversi.

    Efficienza: la velocit di esecuzione e luso oculato delle risorse del sistema su cui ilprogramma finito gira.

    Coerenza: lapplicazione dei principi base di un linguaggio in modo uniforme in tutte le sueparti.

  • 7/29/2019 Basi Programmazione c++

    6/55

    Le Basi della Programmazione 6

    Caratteristiche esterne

    Oltre alle accennate qualit dei linguaggi, possono essere esaminate quelle degli ambienti in cui

    operano. Un programmatore lavora con strumenti software, la cui qualit e produttivit dipende da uninsieme di fattori che vanno pesati anchessi in funzione del tipo di programmi che si intende scrivere.

    Diffusione: il numero di programmatori nel mondo che usa il tale linguaggio.

    Standardizzazione: Lesistenza di alcuni dialetti del linguaggio frammenta la comunit diprogrammatori, limitandone lutilit e la diffusione generale.

    Integrabilit: dovendo scrivere programmi di una certa dimensione, molto facile trovarsi adover integrare parti di codice precedente scritte in altri linguaggi: se un dato linguaggio diprogrammazione consente di farlo facilmente, magari attraverso delle procedure standard,

    questo decisamente un punto a suo favore. Portabilit: la possibilit che portando il codice scritto su una certa piattaforma su unaltra,

    questo funzioni subito, senza doverlo modificare.

  • 7/29/2019 Basi Programmazione c++

    7/55

    Le Basi della Programmazione 7

    2. Tecniche di programmazione

    Un programmatore, inteso come creatore di software, deve essere in grado di occuparsi di un po' tuttele fasi del ciclo di vita del software.Questa ultima espressione si riferisce al modo in cui si scompone l'attivit di progettazione, creazione,test e manutenzione di un software in sotto attivit coordinate fra loro.Questo concetto fondamentale in programmazione e segna la sua comparsa del mondo informaticosegna la definitiva trasformazione della programmazione da attivit artigianale, affidata allacreativit dei singoli individui, ad attivit scientifica, con un forte accento sul processo di creazione

    come strumento di controllo del software.Esistono numerosi modelli su cui basare il ciclo di vita di un software, che prevedono comunque lascomposizione del processo di sviluppo in attivit analoghe. Le distinzioni fra questi si basanosoprattutto su:

    l'enfasi relativa che si attribuisce a ciascuna attivit;

    l'individuazione degli attori specifici incaricati di ciascuna attivit;

    l'ordine in cui le attivit si svolgono.

    Le principali attivit costituenti il processo di sviluppo sono:

    Analisi, ovvero l'indagine preliminare sul contesto in cui il prodotto software deve inserirsi,sulle caratteristiche che deve esibire, ed eventualmente su costi e aspetti logistici della suarealizzazione.

    Al termine della fase verr creato un documento che descrive le caratteristiche del sistema, taledocumento viene definito "documento di Specifica".

    Progettazione, in cui si definiscono le linee essenziali della struttura del sistema da realizzare,

    in funzione dei requisiti evidenziati dall'analisi e dal documento finale da essa creato.In questa fase sar sviluppato un documento che permetter di avere una definizione dellastruttura di massima (architettura di alto livello) e una definizione delle caratteristiche deisingoli componenti (moduli).

    Implementazione, ovvero la sua realizzazione concreta; questa tipicamente consiste nellarealizzazione di uno o pi programmi in un determinato linguaggio di programmazione.

  • 7/29/2019 Basi Programmazione c++

    8/55

    Le Basi della Programmazione 8

    Collaudo, volta a misurare in che modo il sistema realizzato soddisfa i requisiti stabiliti nellafase di analisi, ovvero a valutarne la correttezza rispetto alle specifiche.

    Le tipologie specifiche di test (prove) si possono inoltre distinguere in funzione dei particolariaspetti dei moduli o del sistema che vengono valutati; si parla per esempio di test funzionali,test di performance, test di accettazione, test d'installazione.

    Manutenzione, che comprende tutte le attivit di modifica del software successive al suorilascio presso il cliente o la sua immissione sul mercato.

    Queste attivit possono essere volte a correggere errori del software, adattarlo a nuovi ambientioperativi, o estenderne le funzionalit. La manutenzione incide sui costi tanto che si stima che il60% di questo dipenda dalla manutenzione.

    Ogni modifica al software comporta necessariamente la necessit di nuovi test, sia relativi alle

    nuove funzionalit eventualmente introdotte, sia mirati a verificare che le modifiche apportatenon abbiano compromesso funzionalit preesistenti (test di regressione).

    Vediamo con un migliore dettaglio come sviluppare queste fasi in modo da ottenere un'organizzazioneil pi possibile precisa del lavoro da svolgere, lasciando comunque ad ognuno la possibilit dipersonalizzare il lavoro, mettendo l'accento su uno degli aspetti, a seconda delle inclinazioni propriee delle difficolt del progetto.

  • 7/29/2019 Basi Programmazione c++

    9/55

    Le Basi della Programmazione 9

    La fase di Analisi

    Prevede l'analisi dei requisiti, uno studio del problema il cui obiettivo stabilire se vale la pena (da unpunto di vista tecnico ed economico) realizzare il sistema del quale si vanno definendo i requisiti.Ovviamente in un progetto scolastico o in un progetto personale questa fase autoreferenziale.

    I requisiti del problema vanno individuati mettendo in evidenza l'obiettivo finale del processo stesso: inquesta fase vanno individuate le variabili di input e di output, il linguaggio di programmazione piadatto a risolvere il problema e l'obiettivo finale del progetto software.

    La fase di Progettazione

    In questa fase si scompone il problema in tutti i suoi sotto-problemi (moduli) secondo uno sviluppotop-down, si definisce la gerarchia e la interdipendenza fra questi e se ne discute la soluzione,supportandola con esempi, modelli matematici, diagrammi di flusso.

    Obiettivo della fase definire l'algoritmo risolutivo del problema.

    Strategie Risolutive

    Elaborare un algoritmo non una operazione semplice ed sempre diversa per ognuno dei problemiche ci si trova ad affrontare. Spesso per le tecniche di risoluzione, come i modi di ragionare dellepersone, tendono a seguire determinati schemi, consolidati con il tempo. Eccone alcuni:

    Sfruttare L'esperienzaGioco dello Scarabeo numericoLo scarabeo numerico si gioca con 9 carte numerate da 1 a 9, poste sul tavolo scoperte. I due giocatoridevono prendere, alternativamente, una carta dal tavolo. Vince chi per primo riesce a totalizzare 15 contre carte.Cercate di definire una strategia di gioco che vi consenta di vincere, o quanto meno di non perdere.(saper giocare a tris potrebbe essere utile!)

  • 7/29/2019 Basi Programmazione c++

    10/55

    Le Basi della Programmazione 10

    Procedere a ritrosoGioco dei 24 dadiSi hanno a disposizione 24 dadi di cui uno, ma non si sa quale, leggermente pi pesante di tutti glialtri.

    Utilizzando una bilancia a due piatti identificare il dado pi pesante in non pi di 3 pesateGioco del 100Si gioca in due, uno per volta, partendo da zero e aggiungendo almeno 1 al totale e al massimo 10.Vince chi dice 100.

    AlgebraZio e nipoteAugusto ha il triplo degli anni che aveva sua nipote Clarabella 10 anni fa, e Clarabella, ora, ha la metdegli anni che suo zio Augusto avr fra 5 anni.Che differenza di et c' tra zio e nipote?

    La fase di Implementazione

    In questa fase si passa alla realizzazione pratica dell'algoritmo progettato, implementandolo nellinguaggio di programmazione scelto nella fase di analisi.

    Per ogni difficolt implementativa incontrata in questo livello necessario interrompere la fase etornare alla precedente fase di progettazione, risolvere l'ostacolo, rielaborare l'algoritmo risolutivo eprocedere di nuovo alla sua implementazione.

    La fase termina con la realizzazione di un software funzionante che risolve il problema individuatonella fase di analisi.

  • 7/29/2019 Basi Programmazione c++

    11/55

    Le Basi della Programmazione 11

    3. C++, primi elementi

    La struttura generale del codice e lorganizzazione dei programmi nel linguaggio C++, perfettamentecompatibile con quella del C ed descrivibile tramite un semplice schema:

    DIRETTIVE AL PREPROCESSORE

    DICHIARAZIONE VARIABILI GLOBALI

    PROGRAMMA PRINCIPALE (main)

    FUNZIONE 1

    FUNZIONE 2

    ...

    FUNZIONE n

    Di tutte le sezioni componenti la struttura di un programma, comunque doveroso notare che solo una obbligatoria e cio la dichiarazione di un programma principale. Tutte le altre possono essere omesse.

    Le direttive al preprocessore C sono istruzioni di pre-elaborazione del codice sorgente, chepermettono unorganizzazione dinamica del codice. Sono semplicemente distinguibili da ogni altraistruzione perch ogni direttiva inizia sempre con un #.

    Le direttive pi comuni sono la #include che serve a dichiarare lutilizzo di una determinata libreriae la direttiva #define che serve a dichiarare una sostituzione di testo.

    Ogni programma scritto in C++ strutturato come una serie di chiamate a funzione. Non c codiceesecutivo fuori da una delle funzioni, che sono lambiente predefinito per le operazioni. La funzionemain semplicemente la funzione che viene chiamata per prima.

    A questa viene dunque affidato il compito di contenere tutte le chiamate alle altre funzioni disponibili.La sintassi generale di una funzione della forma:

  • 7/29/2019 Basi Programmazione c++

    12/55

    Le Basi della Programmazione 12

    ( )

    {

    ;

    ;... ;

    }

    dove:

    tipo restituito indica il tipo del valore di uscita della funzione,

    elenco parametri rappresenta linsieme dei parametri che la funzione accetta in ingresso.

    Il linguaggio C++ prevede un insieme di categorie lessicali chiaramente distinguibili fra loro:

    commenti

    identificatori

    parole chiave

    costanti letterali

    punteggiatura e operatori

    I commenti sono una parte fondamentali di ogni buon programma in qualsiasi linguaggio diprogrammazione!! Infatti i commenti sono parti inserite direttamente nel codice, ma ignorate dalcompilatore. Questo permette dunque di commentare il codice nella nostra lingua, descrivendo leoperazioni effettuate. Sono importanti anche nellottica di permettere ad altri di leggere il nostro codiceo di ricordarne a noi stessi la funzionalit.

    In C++ sono possibili due tipi di commenti:

    il commento di riga

    // questo commento termina quando si va a capo

    il commento lungo

    /* questo commento inizia qui

    e termina quando qui */

  • 7/29/2019 Basi Programmazione c++

    13/55

    Le Basi della Programmazione 13

    Identificatore un nome generico utilizzato per descrivere assieme variabili, costanti, tipi, funzioni emacro. Ognuna di queste categorie rappresenta una caratteristica del linguaggio.

    Ogni identificatore deve iniziare con una lettera o con un underscore (_) e non pu contenere spazi.Tutti gli identificatori presenti in un programma devono essere diversi, indipendentemente dalla

    categoria cui appartengono.

    Tipi di dato fondamentali

    Ogni identificatore che un programma intende utilizzare deve essere prima dichiarato. Per le variabili

    abbiamo la seguente sintassi:

    ;

    dove:

    qualificatore un parametro opzionale che descrive il tipo e pu assumere i valori: signed,unsigned, short, long.

    tipo rappresenta (appunto) il tipo di dato memorizzato.

    In C++ i tipi fondamentali si dividono in due categorie: semplici e strutturati. I tipi semplici, gli uniciche ci interessano per adesso, sono:

    Nome Descrizione

    int Comprende i numeri interi relativi compresi in un certo intervallo, che dipendedalle caratteristiche fisiche della macchina ospite.

    (a 32 bit, circa 8 miliardi fra positivi e negativi)

    char Comprende i numeri interi da 0 a 255. Tipicamente questo numero vienerappresentato per` come un carattere in base allutilizzo del codice ASCII.

    float Comprende i numeri reali, rappresentati in virgola mobile con precisione singola(a 32 bit, 7 cifre).

  • 7/29/2019 Basi Programmazione c++

    14/55

    Le Basi della Programmazione 14

    Nome Descrizione

    double Comprende i numeri reali, rappresentati in virgola mobile con precisione doppia(a 32 bit, 16 cifre).

    bool Rappresenta i valori logici true (1) e false (0).

    enum Rappresenta una sequenza di interi come una sequenza di identificatori costanti.

    I tipi strutturati si dicono cos perch non sono tipi definiti autonomamente come i tipi semplici, masono piuttosto strutture di dati creati a partire da altre gi esistenti. I tipi strutturati saranno comunqueapprofonditi pi avanti nel corso degli studi. Le categorie di tipi strutturati comprendono:

    Nome Descrizione

    array Sono variabili in grado di ospitare un numero predefinito di valori omogenei. Adesempio la variabile array nomeMesi potrebbe essere un array contenente 12stringhe ognuna corrispondente al nome di un mese.

    struct Sono variabili in grado di ospitare un numero predefinito di valori NON omogeneifra loro, ma solitamente unite da caratteristiche comuni. Ad esempio la variabilestruct persona potrebbe contenere nome, cognome, data di nascita, peso, altezza.

    union Sono variabili in grado di memorizzare nella stessa variabile tipi differenti inistanti differenti. Ad esempio la variabile temperatura potrebbe essere una unioncontenente un valore float che indica la temperatura oppure il valore NULL adindicare una temperatura non misurata.

    Stringhe e Caratteri

    La gestione di caratteri e stringhe (sequenze di caratteri, cio parole) uno degli argomenti peculiaridel linguaggio C++ e una delle cose in cui si discosta maggiormente dal genitore C.

  • 7/29/2019 Basi Programmazione c++

    15/55

    Le Basi della Programmazione 15

    Sostanzialmente per, rimane anche la possibilit di gestire le stringhe come in C, eliminando di fattoogni eventuale problema di compatibilit fra i due approcci.

    Essendo per le stringhe solo un insieme di caratteri, sar utile introdurle successivamente a questi. Icaratteri in C++ sono gestiti tramite una variabile di tipo char che abbiamo detto contenere un numero

    intero fra 0 e 255. La corrispondenza numero - carattere viene affidata alla cosiddetta tabella dei codiciASCII (American Standard Code for Information Interchange), che vediamo qui rappresentata:

    Come visto allinterno di questa troviamo una serie di caratteri speciali, visualizzabili, ma non

    descrivibili direttamente. Per esempio, sappiamo che per andare a capo in un testo digitato, bastapremere il tasto INVIO, ma come possibile indicare questo carattere? Per tutti i caratteri specialicome questo esiste un insieme di shorcut (scorciatoie, combinazioni di tasti) speciali, definite sequenzedi escape:

  • 7/29/2019 Basi Programmazione c++

    16/55

    Le Basi della Programmazione 16

    Sequenza di escape Descrizione

    \n New line

    \t tab

    \a beep\f Form feed

    \r Carriage return

    \v Vertical tab

    \b backspace

    \\ backslash

    \' apex

    \'' Double apex

    \? Question mark\0 End string

    Una qualsiasi sequenza di caratteri, lettere, numeri, spazi e sequenze di escape, pu essere inclusa fradoppi apici ( ) a formare una stringa costante. Ad esempio, la stringa

    "ciao, Mondo!\n"

    indica la scritta ciao, Mondo! con alla fine un carattere newline, lo stesso effetto che si otterrebbepremendo INVIO su un testo digitato.

  • 7/29/2019 Basi Programmazione c++

    17/55

    Le Basi della Programmazione 17

    Operatori

    Un operatore un simbolo che opera su una o pi espressioni, producendo un valore che pu essereassegnato ad una variabile. In C++ sono disponibili nativamente i seguenti insiemi di operatori:

    Operatori Aritmetici

    Operatore Descrizione Esempio Risultato

    + Addizione x=2x+2

    4

    - Sottrazione x=2

    5-x

    3

    * Moltiplicazione x=4x*5

    20

    / Divisione 15/55/2

    32.5

    % Modulo(resto divisione intera)

    5%210%810%2

    120

    ++ Incremento x=5x++

    x=6

    -- Decremento x=5x--

    x=4

    Bisogna notare che la divisione funziona diversamente a seconda del tipo. Cio se a=5 e b=2 sonovariabili intere, il risultato di a/b sar lintero 2 (troncamento della parte decimale), mentre se sonovariabili reali (float), il risultato sar il reale 2.5.

    Nel caso di una operazione fra un reale e un intero il risultato sempre un reale.

  • 7/29/2019 Basi Programmazione c++

    18/55

    Le Basi della Programmazione 18

    Operatori di Assegnazione

    Operatore Esempio come fare

    = x=y x=y

    += x+=y x=x+y-= x-=y x=x-y

    *= x*=y x=x*y

    /= x/=y x=x/y

    .= x.=y x=x.y

    %= x%=y x=x%y

    Operatori di confronto

    Operatore Descrizione Esempio

    == uguale a 5==8 restituisce false

    != diverso da 5!=8 restituisce true

    > maggiore di 5>8 restituisce false

    < minore di 5= maggiore o uguale a 5>=8 restituisce false

  • 7/29/2019 Basi Programmazione c++

    19/55

    Le Basi della Programmazione 19

    Operatore Descrizione

    && AND logico bit a bit

    || XOR bit a bit

    ^ Complemento a uno>> Shift destro

    ? < Espr1 >:che valuta Espr1 se EsprLogica vera, Espr2 altrimenti.

    a = (b > 0?1 : 2)assegner ad a il valore 1 se b maggiore di zero, 2altrimenti.

    Esercizi

  • 7/29/2019 Basi Programmazione c++

    20/55

    Le Basi della Programmazione 20

    1. Ciao, Mondo!

    2. Programma per calcolare larea e il perimetro di un rettangolo di base = 4 e altezza = 6.

    3. Programma che permette l'inserimento, da parte dell'utente, di un numero intero e che lovisualizza.

    4. Programma che permette l'inserimento, da parte dell'utente, di un numero reale e che lovisualizza.

    5. Programma che permette l'inserimento, da parte dell'utente, di un carattere e che lo visualizza.

    6. Programma che permette l'inserimento, da parte dell'utente, di una stringa e che la visualizza.

    7. Programma che visualizza il numero intero int n = 5 e va a capo, il carattere char c = 'b' e va acapo, il numero reale float r = 3.14 e va a capo.

    8. Programma per calcolare larea e il perimetro di un rettangolo con i valori di base e altezzainseriti dall'utente.

    9. Lavorare coi parametri della funzione main().10. Calcolo dello spazio occupato da ognuno dei tipi fondamentali semplici, tramite loperatore

    sizeof.

    11. La libreria climits e i limiti superiore e inferiore dei tipi interi.

    12. Dati tre numeri interi, considerarli come hh:mm:ss di un orario determinato. Calcolare i seconditrascorsi dalla mezzanotte del giorno prima.

    13. Sapendo che in un parcheggio la prima ora costa 1.5 mentre tutte lo successive costano 1 e,scrivere un programma che richieda il numero complessivo delle ore e visualizzi il totale dapagare.

  • 7/29/2019 Basi Programmazione c++

    21/55

    Le Basi della Programmazione 21

    4. Le strutture di controllo

    Il lavoro di creazione e organizzazione dellalgoritmo risolutivo di un certo problema si pu descrivere,in buona approssimazione, con la stesura di una serie di operazioni da compiere per ottenere il risultatoprefissato. Durante questo lavoro, vanno tenute in considerazioni anche variabili come il linguaggioimplementativo scelto, il sistema che ospiter il programma finale e ogni variabile contingente. ovviodunque che la stesura dellalgoritmo unoperazione preliminare alla stesura del codice e andrebbero

    sempre ben distinte.La schematizzazione sistematica delle operazioni da svolgere per le risoluzione del problema ilprocedimento che viene definito programmazione strutturata. Obiettivo di questa tecnica diprogrammazione quello di organizzare in strutture pi semplici ogni algoritmo risolutivo. In unalgoritmo le istruzioni possono essere organizzate in:

    1. sequenza, in cui le istruzioni sono eseguite una dopo laltra

    2. alternanza, in cui alcune istruzioni sono eseguite alternativamente (o un gruppo o un altro)

    3. ripetizione, in cui alcune istruzioni sono ripetute un numero finito di volte.

    Accanto a queste semplici strutture possono esserne inserite altre pi generali o pi particolari, perschematizzare ogni algoritmo secondo i criteri che pi si adattano ai propri gusti. Queste tre sono statescelte perch vale il seguente teorema (Jacopini-Bohm, 1966)

    Qualsiasi algoritmo pu essere riscritto in maniera equivalente

    utilizzando solo le strutture di sequenza, alternanza, ripetizione.

    Questo algoritmo cio sostanzialmente afferma che le tre strutture indicate sono i mattoni fondamentaliper riprodurre qualsiasi algoritmo formulabile dalluomo. In altre parole, tutti i problemi che sonorisolvibile, hanno anche una soluzione costruita semplicemente con istruzioni in sequenza, alternanza eripetizione.

  • 7/29/2019 Basi Programmazione c++

    22/55

    Le Basi della Programmazione 22

    Struttura alternativa

    La struttura alternativa viene rappresentata in C++ tramite lo schema:

    if CONDIZIONE

    ISTRUZIONI cond VERA

    [else

    ISTRUZIONI cond FALSA]

    ove ovviamente il primo gruppo di istruzioni viene eseguito solo se la condizione vera, mentre ilsecondo solo se la condizione falsa. Le istruzioni rappresentano sempre un blocco e vanno quindiracchiuse fra parentesi graffe { e }. La condizione una espressione booleana di cui viene valutata la

    veridicit.Le parentesi quadre nello schema stanno invecead indicare che la seconda parte dellistruzione `opzionale, cio si potrebbe creare semplicementeuna struttura del tipo

    if CONDIZIONE

    ISTRUZIONI

    in modo da eseguire un blocco di istruzioni solonel caso che una condizione si verifichi.

  • 7/29/2019 Basi Programmazione c++

    23/55

    Le Basi della Programmazione 23

    Proviamo con un esempio a prendere pratica con le strutture illustrate. Immaginiamo di dover risolvereil seguente problema: dati due numeri dallutente, disporli in ordine crescente; Il seguente codice lorisolve.

    int primo, secondo, min, max;

    cout > primo;

    cout > secondo;

    if (primo < secondo)

    {

    min = primo;

    max = secondo;

    }

    else

    {

    min = secondo;

    max = primo;

    }cout

  • 7/29/2019 Basi Programmazione c++

    24/55

    Le Basi della Programmazione 24

    Va notato anche che listruzione IF.. ELSE puessere ripetuta dentro ad unaltra, producendo unanidificazione e in questo caso si potrebbe perdere illegame fra IF e lELSE correlato. In questo caso

    vale la regola che ogni ELSE si riferisce sempre alpi vicino IF sovrastante.

    Nellesempio seguente lindentazione chiarifica ilegami fra i vari IF.. ELSE.

    if CONDIZIONE

    if CONDIZIONE

    ISTRUZIONI

    else

    ISTRUZIONI

    else

    ISTRUZIONI

  • 7/29/2019 Basi Programmazione c++

    25/55

    Le Basi della Programmazione 25

    Struttura alternativa multipla

    Capita a volte di dover tener testa non a due semplici possibilit alternative, ma ad una serie dicomportamenti in risposta agli eventi. E questo il caso in cui possibile utilizzare una struttura

    alternativa multipla, la cui sintassi viene qui mostrata:

    switch (VARIABILE)

    {

    case VALORE-1:

    ISTRUZIONI-1;

    break;

    case VALORE-2:

    ISTRUZIONI-2;

    break;

    ...

    default:

    ISTRUZIONI;

    }

    Importante notare che la struttura switch funziona solo con variabili intere ed assolutamente analoga

    ad una serie di IF nidificati che hanno nella condizione il controllo sulla stessa variabile.

    Anche qui vediamo di illustrare un esempio: dato un numero intero da 1 a 12, visualizzare il mesecorrispondente. Vediamo il codice:

    int mese;

    cout > mese;

    switch(mese)

    {

    case 1:

    cout

  • 7/29/2019 Basi Programmazione c++

    26/55

    Le Basi della Programmazione 26

    break;

    ...

    case 12:

    cout

  • 7/29/2019 Basi Programmazione c++

    27/55

    Le Basi della Programmazione 27

    Struttura iterativa

    In questa parte ci occuperemo di tutte le istruzioni del linguaggio C++ che permettono di ripetere un

    numero finito di volte un blocco di istruzioni. Il numero delle ripetizioni solitamente controllatotramite una condizione booleana.

    Una caratteristica comune delle istruzioni seguenti che tutte ripetono le istruzioni finch lacondizione risulta vera, mentre escono dal ciclo esecutivo quando questa diventa falsa.

    Iterazioni PREcondizionali

    Le iterazioni PREcondizionali sono semplicemente

    quelle che prima di iniziare a eseguire le istruzionida ripetere controllano la verit della condizioneimposta. In questo caso se la condizione falsa, ilciclo non viene eseguito neanche una volta

    while CONDIZIONE

    ISTRUZIONI

    Vediamo con un esempio di chiarire il concetto:

    calcolare il prodotto di due numeri interi A, Bsommando A per B volte.

    int A = 5, B = 7, prodotto = 0;

    while ( B!=0){

    prodotto += A; // prodotto = prodotto + A;

    B--; // B = B - 1

    };

  • 7/29/2019 Basi Programmazione c++

    28/55

    Le Basi della Programmazione 28

    Iterazioni POSTcondizionali

    Le iterazioni POSTcondizionali sono quelle

    iterazioni che prima eseguono una volta il blocco diistruzioni da ripetere e poi controllano unacondizione per capire se bisogna iterare ilprocedimento.

    do

    ISTRUZIONI

    while CONDIZIONE

    Questo tipo di iterazione non molto comune e siutilizza solo in determinati casi, come ad esempioper controllare che un valore di input corrisponda adun certo range:

    int A;

    do

    {

    cout > A;

    }

    while( A < 0);

  • 7/29/2019 Basi Programmazione c++

    29/55

    Le Basi della Programmazione 29

    Iterazioni enumerative

    Le iterazioni enumerative, o con contatore, sono una struttura derivata dalle iterazioni

    PREcondizionali. Sono molto comuni perch permettono di mettere in evidenza un contatore interonella condizione che indicher il numero di ripetizioni da eseguire. E questa quindi la struttura dautilizzare nel caso in cui sia noto a priori il numero di iterazioni.

    for ( INIZIALIZZAZIONE, CONDIZIONE, INCREMENTO )

    ISTRUZIONI

    Vediamo un esempio: scrivere i primi 10 numeri interi

    for( int i = 1; i

  • 7/29/2019 Basi Programmazione c++

    30/55

    Le Basi della Programmazione 30

    Esercizi sulla struttura iterativa

    1. Visualizzare i primi 100 numeri.

    2. Fare la somma dei primi 100 numeri e poi dei primi n numeri, con n inserito dallutente.3. Fare la somma di 10 numeri inseriti a scelta dallutente

    4. Calcolo dello zero di macchina

    5. Programma per il calcolo del fattoriale di un numero dato e poi di tutti i fattoriali dei numeriminori di quello.

    6. Visualizzazione Tavola Pitagorica

    7. Visualizzazione di un rettangolo con cornice + e interno = di misure A e B, decisedallutente

    8. Predisporre un programma, che determini il maggiore, il minore e la media degli n valoriimmessi dallutente.

    9. Divisori di un numero intero A, inserito dallutente

    10. Dato B, verificare se primo

    11. Programma che calcola tutti i numeri primi minori di X

    12. Dato C, verificare se perfetto e poi calcolare tutti i numeri perfetti minori di C.

    13. Programma che disegna un rettangolo di caratteri di BASE e ALTEZZA scelti dallutente. Ilrettangolo formato da un carattere a scelta come cornice e da un carattere a scelta allinterno.

    14. Scrivere un programma che, richiesti i coefficienti (a, b, c) di unequazione di secondo grado,

    determini il numero delle soluzioni possedute e i valori, se esistono, delle soluzioni.15. Scrivere un programma che calcoli il podio di una gara con 10 corridori. I corridori sono

    identificati da un numero di gara e hanno un tempo sul giro espresso in primi, secondi,millesimi decisi da una funzione random.

  • 7/29/2019 Basi Programmazione c++

    31/55

    Le Basi della Programmazione 31

    5. Array

    Gli array sono una particolare struttura derivata molto utilizzata in programmazione. Rappresentano untipo di dato derivato da altri preesistenti e raggruppano un insieme di dati omogenei (= dello stessotipo) fra loro. Con una sola variabile di tipo array dunque, possiamo indicare tanti dati (e quindi tantivalori) dello stesso tipo.

    Gli array sono insiemi collettivi omogenei di grandezza predefinita, quindi il numero di elementi

    facenti parte della collezione viene decretato in fase di dichiarazione dello stesso.Ognuno degli elementi dellarray viene numerato per poterlo distinguere dagli altri; la variabile ocostante intera utilizzata per riferirsi a questo numero viene definita indice dellarray.

    La dichiarazione di un array analoga a quella delle altre variabili, ricordandosi per che questo untipo derivato: non esiste un array in s, ma esistono array di interi, array di reali, di caratteri o diqualsiasi tipo di dato definito in precedenza. La dichiarazione assume dunque la forma:

    tipo nome [ dimensione ] ;

    dove:

    tipo il tipo degli elementi della collezione;

    nome il nome (identificatore) della variabile array;

    dimensione un intero o una costante intera che rappresenta il numero di elementi dellacollezione.

    Ad esempio, per dichiarare un array di 12 interi di nome giorniMese dovremo scrivere:

    int giorniMese[12];

    Larray giorniMese conterr dunque 12 variabili numerate da 0 a 11. La numerazione degli elementi diun array infatti parte sempre da ZERO! Questo significa che per assegnare ad esempio il valore 31 alprimo elemento (il numero di giorni del primo mese) dovremo scrivere:

  • 7/29/2019 Basi Programmazione c++

    32/55

    Le Basi della Programmazione 32

    giorniMese[0] = 31;

    Per assegnare il valore 30 allundicesimo mese scriveremo

    giorniMese[10] = 30;

    La posizione 10 rappresenta infatti lundicesimo elemento dellarray. Molto utile, quando si tratta diarray, lavorare in collaborazione con il costrutto for. Ad esempio per azzerare tutti i valori dellarraygiorniMese, sar sufficiente scrivere:

    for(int i=0; i< 12; ++i)

    {

    giorniMese[i] = 0;

    }

    Allo stesso modo per permettere ad un utente di inserire 10 valori baster scrivere:

    int valoriUtente[10];

    for(int i=0; i

  • 7/29/2019 Basi Programmazione c++

    33/55

    Le Basi della Programmazione 33

    Esercizi svolti

    Dichiarare un array di 100 interi e riempirlo con i primi 100 numeri dispari.

    int a[100];

    for(int i = 0; i

  • 7/29/2019 Basi Programmazione c++

    34/55

    Le Basi della Programmazione 34

    Esercizi semplici sugli array

    1. Dichiarare e inizializzare larray di stringhe mesiAnno e visualizzarne il contenuto.

    2. Permettere allutente di inserire 5 valori interi memorizzati tramite array, poi visualizzarli efarne la somma.

    3. Eseguire la media aritmetica di 8 valori numerici inseriti dallutente e memorizzati in un arraydi double.

    4. Inserimento random di valori float in un array di 5 posti e visualizzazione.

    5. Visualizzare uno qualsiasi degli array precedenti in ordine inverso (dallultimo elemento alprimo).

    6. Dato un array di 100 interi, inizializzato con valori random, trovare: il massimo e la suaposizione, il minimo e la sua posizione.

  • 7/29/2019 Basi Programmazione c++

    35/55

    Le Basi della Programmazione 35

    Ricerca di un elemento

    La ricerca di un elemento in un array una operazione tra le pi comuni in assoluto in informatica:immaginate ogni volta che inserite un nome utente, un codice, una password oppure semplicementecercate un numero di telefono nella rubrica del telefonino!

    Tutte queste sono operazioni in cui informaticamente avviene una ricerca su un array di elementiomogenei fra loro.

    Vi sono vari tipi di ricerche effettuabili su un array; per ora vedremo la cosiddetta ricerca sequenziale.Questa ricerca esamina le componenti dellarray fino a trovare lelemento desiderato oppurearrestandosi alla fine dellarray se lelemento non presente. Per semplicit descriveremo la proceduraper un array di interi.

    // array inizializzato

    int ar[10] = {1,12,23,34,45,56,67,78,89,90};

    int pos = -1; // posizione dellelemento da cercare;

    // -1 significa NON trovato

    int daCercare;

    cout > daCercare;

    int i = 0;

    while( pos == -1 && i < 10 )

    {

    if( ar[i] == daCercare )

    {

    pos = i;

    }

    i++;

    }

    // se ar[i] non mai stato uguale a daCercare significa che

    // lelemento non presente nell'array

    // (e che pos rimasto -1!!)

    if (pos == -1)

  • 7/29/2019 Basi Programmazione c++

    36/55

    Le Basi della Programmazione 36

    {

    cout

  • 7/29/2019 Basi Programmazione c++

    37/55

    Le Basi della Programmazione 37

    Ordinamento degli elementi

    Ordinare gli elementi di un array (array sorting) unaltra fra le operazioni pi comuni esistenti ininformatica: mai riusciremmo a leggere un elenco del telefono o un vocabolario disordinato!!

    I metodi di ordinamento sono numerosi e spesso molto ingegnosi: qui ne vengono presentati due fra ipi semplici e comuni.

    Il primo il classicoBubble Sort, un metodo che permette di far salire in alto gli elementi pi grandidi un array, cos come le bolle di sapone pi grandi salgono pi velocemente. Il risultato finale sarovviamente un array ordinato in senso crescente.

    Il secondo il cosiddetto Insert Sort, ovvero Inserimento Ordinato. In questo modo ogni array sempre ordinato perfettamente perch ogni nuovo elemento viene inserito al punto giusto, spostando

    i successivi di una posizione in avanti.Una semplice ricerca in Rete permetter di scovare almeno unaltra decina di algoritmi di ordinamentoognuno con la sua peculiarit e i suoi punti di forza. Come detto, i due che verranno citati sono statiscelti in base alla semplicit di comprensione (del primo) e utilit nella programmazione (di entrambi,soprattutto il secondo).

    // BUBBLE SORT

    int ar[ 10 ];

    srand( time(0) );

    for(int i = 0; i < 10; i++)

    {

    ar[i] = rand();

    }

    // ordinamento

    for(int j = 1; j < 10; j++)

    {

    for( int i = 0 ; i < 10 -j; i++)

    {

    // se il valore del precedente maggiore del successivo, scambiali

    if(ar[i] > ar[i+1])

    {

    int temp;

    temp = ar[i];

  • 7/29/2019 Basi Programmazione c++

    38/55

    Le Basi della Programmazione 38

    ar[i] = ar[i+1];

    ar[i+1] = temp;

    }

    }}

    Il secondo algoritmo, piuttosto che un ordinamento di un insieme di valori disordinati, una proceduraper inserire sempre nel punto giusto i valori in un array. E molto utile in quanto molti elenchi hannoun naturale bisogno di essere ordinati e comunque aggiornabili e una procedura completa diordinamento richiederebbe un lavoro inutile e da ripetere ogni volta per ordinare un solo elemento.

    // INSERT SORT

    int ar[ 10 ];

    int n = 0;

    ...

    // numero elementi inseriti nel array

    // va eseguito ogni volta che si vuole inserire un numero nellarray

    if(n temp;

    if(n==0)

    {

    array[n] = temp;

    n++;

    }

    else

    {

    int i = n - 1;

    while(temp < array[i] && i >= 0)

    {

    array[i+1] = array[i];

    i--;

  • 7/29/2019 Basi Programmazione c++

    39/55

    Le Basi della Programmazione 39

    }

    array[i+1] = temp;

    n++;

    }}

    Ognuno di questi algoritmi merita sicuramente di essere testato personalmente. Fatelo. E poi anche gliesercizi di comprensione e approfondimento che seguono.

    Esercizi su ordinamenti degli array

    1. Ordinamento di un array di caratteri.

    2. Ordinamento di un array di caratteri case-insensitive (dove a conta come A).

    3. Ordinamento decrescente di un array di interi random.

    4. Inserimento ordinato decrescente di un array di float.5. Men di scelta che permette inserimento ordinato e visualizzazione dei cognomi dei

    componenti della classe.

  • 7/29/2019 Basi Programmazione c++

    40/55

    Le Basi della Programmazione 40

    Ricerca Binaria (ricerca su array ordinato)

    La ricerca binaria (o dicotomica) un altro degli algoritmi fondamentali che studieremo nel corso. un algoritmo di ricerca molto veloce che si pu utilizzare solo nei vettori ordinati. Per dare unidea dicome funziona immaginate di cercare una parola nel vocabolario: apriamo a caso il tomo e guardiamo ache punto siamo; se la parola si trova prima apriamo unaltra pagina a caso tra quelle precedenti,viceversa in quelle successive. Ripetiamo restringendo il campo di ricerca finch non troviamo lapagina in cui deve trovarsi la nostra parola e solo a quel punto consultiamo la pagina!

    Il seguente algoritmo funziona esattamente cos: cerca allesatta met del array il valore da cercare. Selo trova bene, altrimenti se il valore da trovare minore di quello trovato si cerca nella prima met (amet della prima met), se il valore da trovare maggiore di quello trovato si cerca nella seconda met(la met della seconda met).

    Il procedimento si itera finch non si trova il valore o finch ci sono caselle in cui cercare. Nell'esempio

    seguente il campo di ricerca delimitato ad ogni iterazione dai valori low e high, che ne rappresentanoestremo inferiore e superiore.

    // RICERCA DICOTOMICA

    int daCercare;

    cout > daCercare;

    int high = 10 1; // 10 la dimensione dell'array

    int low = 0;

    int pos = -1;

    do

    {

    int i = (high + low)/2;

    if ( ar[i] == daCercare )

    {

    pos = i;

    }

    else

    {

    if( ar[i] < daCercare )

    {

    low = i + 1;

  • 7/29/2019 Basi Programmazione c++

    41/55

    Le Basi della Programmazione 41

    }

    else

    {

    high = i - 1;}

    }

    }

    while(high >= low && pos == -1);

    if (pos == -1)

    {

    cout

  • 7/29/2019 Basi Programmazione c++

    42/55

    Le Basi della Programmazione 42

    6. Stringhe in C++

    Nel linguaggio C++, la classe std::string la rappresentazione standard per una stringa di testo. Questaclasse rimuove molti dei problemi introdotti nel linguaggio C++ nella gestione delle stringhe epermette pure una conversione implicita dal tipico array di caratteri del linguaggio C alla nuova classeC++.

    Inoltre introduce nuovi importanti benefici nella trattazione delle stringhe, come la possibilit diconfronto tramite gli appositi operatori ==, !=, , = invece dellutilizzo delle funzioni dellalibreria C string.h che diviene sostanzialmente deprecata (in C++).

    Vediamo un semplice esempio di utilizzo per capire quanto sia facile gestire stringhe in C++:

    string uno = "ciao";

    string due = "hello";

    if( uno == due )

    cout

  • 7/29/2019 Basi Programmazione c++

    43/55

    Le Basi della Programmazione 43

    Stringhe e Puntatori

    Poich il tipo char* pu essere implicitamente trasformato in string &, questo modo di dichiarare i

    parametri permette un uso pi semplice e universale della funzione.

    const char* a = "ciccio";

    string b = "pippo";

    // tutti e tre i metodi funzionano!!

    scrivi( a );

    scrivi( "poldo" );

    scrivi( b );

    Operatori su stringhe

    Le stringhe in C++ possono utilizzare una serie interessante di operatori di convenienza, in modo darendere semplici e intuitive certe operazioni altrimenti piuttosto laboriose nel linguaggio C.

    Il pi semplice e ovvio loperatore di assegnazione:

    string str;

    str = "andrea"; // possibile assegnare parole

    str = a; // ERRORE: una stringa non un carattere

    str = "a"; // cos funziona

    char pippo[30] = "diamantini";

    str = pippo; // CORRETTO

    char *pluto = str; // ERRORE

    Inoltre, le stringhe usano loperatore aritmetico + per le concatenazioni

    string nome = "andrea";

    string cognome = "diamantini";

    string spazio = " ";

  • 7/29/2019 Basi Programmazione c++

    44/55

    Le Basi della Programmazione 44

    string nomeCompleto = nome + spazio + cognome;

    cout

  • 7/29/2019 Basi Programmazione c++

    45/55

    Le Basi della Programmazione 45

    7. Tipi Derivati

    I tipi derivati (o composti) sono cos detti perch nelle basi del linguaggio di programmazione nonesistono, ma devono essere dichiarati dal programmatore a partire dai tipi fondamentali (o semplici).

    I linguaggi di programmazione fanno un grande uso dei tipi derivati, perch tendono ad avvicinarsimolto di pi alle strutture dati necessarie per risolvere un problema, favorendo la leggibilit e lachiarezza del programma.

    In C++ abbiamo gli strumenti per definire infiniti tipi derivati, classificabili per in poche categorie:

    array,

    funzioni,

    puntatori,

    strutture,

    unioni,

    campi,

    file.

    Quindi qualsiasi tipo derivato sar comunque in una di queste categorie e quindi soggetto alle regoleproprie della stessa.

    Alcuni di questi tipi sono gi stati affrontati nel corso della nostra trattazione, vediamo gli altri ancorasconosciuti.

  • 7/29/2019 Basi Programmazione c++

    46/55

    Le Basi della Programmazione 46

    Strutture

    la struttura serve a definire in un unico tipo un insieme di dati che non sono slegati fra loro, ma cheinsieme rappresentano un unico concetto. Quando, ad esempio, si parla di un compleanno, si ha inmente un unico dato, quello relativo alla propria data di nascita.

    Secondo le nostre attuali conoscenze, avremmo per dovuto dichiarare almeno tre variabili interediverse per memorizzare ci che nella nostra testa un unico concetto.

    La struttura si pone di superare questo limite, insito nella semplicit dei tipi fondamentali e permette didichiarare un nuovo tipo, data, che contenga informazioni sul giorno, mese, anno di ogni data.

    struct data

    {

    int gg;

    int mm;

    int aa;

    };

    Come si vede, tramite la parola chiave struct, abbiamo definito il nuovo tipo data, che contiene al suointerno tre interi, uno per il giorno, uno per il mese, uno per lanno. I dati contenuti allinterno di unastruct sono solitamente definiti campi.

    Attenzione per!

    La struct cos definita NON una variabile, ma un tipo, che dovr essere istanziato per poter essereutilizzato.

    data compleannoAndrea;

    compleannoAndrea.gg = 3;

    compleannoAndrea.mm = 7;

    compleannoAndrea.aa = 1976;

    Come visto nellesempio, i campi sono accessibili dallistanza tramite loperatore punto (.). A quelpunto, possibile lavorare coi dati come si sempre fatto.

    I campi di una struct possono essere di qualsiasi tipo (semplice o derivato), ma che deve gi esserestato definito.

    Cos se la struct data gi definita, possiamo ora creare:

  • 7/29/2019 Basi Programmazione c++

    47/55

    Le Basi della Programmazione 47

    struct indirizzo

    {

    string via;

    int numero;string citta;

    char provincia[2];

    int cap[5];

    };

    struct datiPersonali

    {

    string nome;

    string cognome;

    data dataNascita;

    indirizzo indResidenza;

    };

    Da notare che la dichiarazione di una struct richiede il punto e virgola ; finale dopo la chiusura delleparentesi graffe. In C++ esistono solo due casi in cui assolutamente necessario (e questo il primo

    che incontriamo)!

    Esercizi sulle struct

    1. Programma che utilizza la struttura data sopra descritta per memorizzare la propria data dinascita e visualizzarla nella forma gg/mm/aaaa

    2. Programma che utilizza la struttura datiPersonali sopra descritta per memorizzare i propri datipersonali e che al termine dellinserimento li visualizza.

    3. Programma che gestisce la classifica finale di una gara di nuoto con nome dellatleta, vasca incui ha gareggiato, posizione finale raggiunta e tempo di gara.

    4. Programma che simula la rubrica del proprio cellulare.

    5. Programma che gestisce i dati per la compravendita di automobili.

  • 7/29/2019 Basi Programmazione c++

    48/55

    Le Basi della Programmazione 48

    Unioni

    Le unioni sono un costrutto analogo alle strutture, ma con tuttaltra funzionalit: se infatti le strutture

    introducono una organizzazione logica dei dati, le union raggruppano nello stesso spazio di memoriatutti i campi presenti. Questo permette di memorizzare un solo campo per volta tra tutti quelli presentinella union.

    Vediamo la sintassi generale:

    union Identificativo

    {

    tipo_campo1 nome_campo1;

    tipo_campo2 nome_campo2;

    . . .

    };

    Ovviamente, visto come sono definite, sar facile intuire che le union occupano in memoria lo stessospazio del loro campo pi grande.

    E possibile utilizzare le union per memorizzare nella stessa variabile (alternativamente) dati di tipodiverso. Immaginiamo di avere un elenco di oggetti di cui per lidentificazione si hanno una sigla diTOT lettere, tipo codice a barre oppure un numero di serie.

    In quel caso sar possibile definire una union del tipo:

    union oggetto

    {

    char codiceBarre[20];

    int numeroSerie;

    };

    Il tipo union oggetto potr dunque contenere o una sequenza di 20 caratteri oppure un intero.le union, vista la loro estrema particolarit e la difficolt nel trattamento dei dati memorizzati, sonopoco usate se non in casi particolari, che qui non tratteremo.

  • 7/29/2019 Basi Programmazione c++

    49/55

    Le Basi della Programmazione 49

    Campi

    I campi (fields) sono un costrutto tipico del C, che permette di accedere direttamente ai singoli bit che

    compongono una variabile. La sintassi generale analoga alle precedenti incontrate:

    struct Identificativo

    {

    unsigned nome_campo1 : numero_bit1;

    unsigned nome_campo2 : numero_bit2;

    . . .

    };

    Vediamo con un esempio pratico di illustrare al meglio il concetto:

    struct Date

    {

    unsigned nWeekDay : 3; // 0..7 (3 bits)

    unsigned nMonthDay : 6; // 0..31 (6 bits)

    unsigned nMonth : 5; // 0..12 (5 bits)

    unsigned nYear : 8; // 0...100 (8bits)};

    Date today;

    La variabile today di tipo Date occupa uno spazio di memoria pari alla somma dei bit utilizzati in ognicampo, arrotondato (sempre) per eccesso ad un multiplo della word di macchina. Nel nostro caso,abbiamo 3 + 6 + 5 + 8 = 22 bit utilizzati, mentre le macchine moderne hanno attualmente word a 32 o64 bit. Questo significa, nel caso di word = 32, che la variabile today occupa 4 byte, pari a 32 bit dimemoria (22 utilizzati, 10 sprecati).

    I bit della variabile si accedono con la solita sintassi (dot notation), utilizzata anche per le strutture e leunioni e i bit possono essere trattati come semplici numeri interi non negativi.

    Ad esempio, sar possibile scrivere, nella variabile today, qualcosa come:

    today.nMonth = 3;

    Come le union, anche i campi sono costrutti poco usati, se non nellinterazione diretta bit a bit condeterminati dati. Il loro utilizzo tipico non sar oggetto del corso.

  • 7/29/2019 Basi Programmazione c++

    50/55

    Le Basi della Programmazione 50

    Puntatori

    Un Puntatore in C++ una variabile che contiene lindirizzo di memoria in cui si trova un oggetto,

    invece che memorizzare direttamente quello.Il tipo di dato puntatore dunque tipicamente un tipo di dato derivato dal tipo delloggetto di cuicontiene lindirizzo di memoria. Vediamo un esempio di codice che possa chiarirci le idee:

    int main()

    {

    int a, b;

    int *p; // p un puntatore a intero

    a = 2;

    p = &a; // p contiene lindirizzo di a

    *p = 3; // allindirizzo individuato da p

    // viene assegnato il valore 3

    b = a; // allintero b viene assegnato il valore di a.

    // Quanto vale b??

    }

    Un puntatore nullo un puntatore a cui non stato assegnato nessun indirizzo (p = 0, oppure p =NULL). Quando si tenta di utilizzare un puntatore nullo, si ottiene un crash dellapplicazione con unpoco rassicurante Segmentation Fault.

    I problemi tipici con i puntatori sono suddivisibili in due categorie, entrambe da evitare accuratamente:

    Problema 1: Dangling Reference

    La problematica definita dangling reference (riferimento sospeso) si verifica quando un valore vienememorizzato tramite puntatore e il puntatore perde il riferimento all'oggetto. Questo rimane perso inmemoria in un punto indefinito, occupando il blocco fino allo spegnimento della macchina!

    int n = 4;

  • 7/29/2019 Basi Programmazione c++

    51/55

    Le Basi della Programmazione 51

    double *p = & sqrt(n); // Assegnato a p lindirizzo del calcolo

    // della radice quadrata di n.

    p = 0; // il numero precedentemente calcolato

    // NON stato cancellato,// ma non pi raggiungibile

    Problema 2: Dangling Pointer

    La problematica definita dangling pointer (puntatore sospeso) si verifica quando un puntatorecontiene un indirizzo inutile, non contenente nessun dato del problema.

    Quando si cerca di accedere al dato contenuto nel puntatore si viola un blocco di memoria nonaccessibile e l'applicazione va in crash!

    int *p;

    int i = 1;

    while(i

  • 7/29/2019 Basi Programmazione c++

    52/55

    Le Basi della Programmazione 52

    Riferimenti

    Oltre ai puntatori, il C++ supporta anche il concetto di riferimenti. Come un puntatore, un

    riferimento contiene lindirizzo di un oggetto. Le differenze sostanziali sono che:

    i riferimenti sono dichiarati usando & anzich *

    i riferimenti devono essere inizializzati (cio bisogna subito assegnargli un indirizzo) e nonpossono essere poi riassegnati.

    loggetto associato ad un riferimento direttamente accessibile con la solita sintassi (no >)

    un riferimento non pu essere nullo

    I riferimenti sono usati soprattutto per la dichiarazione dei parametri. Per default, il C++ utilizza ilpassaggio di parametri per valore:

    int moltiplicazione(int a, int b)

    {

    return a*b;

    }

    E in questo caso dovremmo invocare la funzione nel seguente modo:

    int primo = 2;

    int secondo = 3;

    int d = moltiplicazione(primo,secondo);

    Questo crea nel calcolo della funzione distanza un inutile spreco di memoria dato dalla duplicazionedei valori passati come parametri. Il programmatore attento scriver dunque:

    int moltiplicazione(int* a, int* b)

    {

    return (*a) * (*b);

    }

    E utilizzer cos la funzione:

  • 7/29/2019 Basi Programmazione c++

    53/55

    Le Basi della Programmazione 53

    int primo = 2;

    int secondo = 3;

    int d = moltiplicazione(&primo,&secondo);

    Questa accortezza per rende le cose pi dificili e introduce ulteriori problemi, ad esempio nel caso delpassaggio di puntatori nulli, oppure rischiando che il codice della funzione moltiplicazione modifichi ivalori dei nostri dati. Utilizzando riferimenti al posto dei puntatori, faremo cos:

    int moltiplicazione(int& a, int& b)

    {

    return a*b;

    }

    E potremo utilizzare il semplice codice:

    int primo = 2;

    int secondo = 3;

    int d = moltiplicazione(primo,secondo);

    Se infine NON vogliamo rischiare modifiche indesiderate ai nostri valori, possiamo utilizzareriferimenti costanti:

    int moltiplicazione(const int& a, const int& b)

    Puntatori e riferimenti rappresentano le stesse informazioni in memoria. Per convertire uno nellaltro sufficiente utilizzare gli operatori unari & e *

    int p;

    int *ptr = p;

    int &ref = *ptr;

    int *p2 = &ref;

  • 7/29/2019 Basi Programmazione c++

    54/55

    Le Basi della Programmazione 54

    I riferimenti hanno una sintassi molto semplice e conveniente, ma i puntatori possono essere sempreriassegnati, possono contenere valore nullo e la loro sintassi esplicita li individua senza ombra didubbio. Per queste motivazioni in programmazione si usano di solito i puntatori lasciando airiferimenti, per lo pi costanti, il ruolo di parametri nelle funzioni.

    Strutture e Puntatori

    Data una struttura, possibile accedere ai suoi campi anche tramite un opportuno puntatore. I puntatoriper, utilizzano loperatore arrow ( >) per accedere ai campi della struttura, al posto delloperatore dot(.).

    Data la struttura data, definita precedentemente, in una variabile normale possibile riferirsi ai suoicampi tramite il solito operatore dot (.).

    struct data n;

    n.gg = 30;

    n.mm = 3;

    n.aa = 2009;

    Se utilizziamo un puntatore invece, dobbiamo riferirci ai campi tramite loperatore arrow ( >):

    struct data m;

    struct data *p;

    p = &m;

    p->gg = 31;

    p->mm = 3;

    p->aa = 2009;

    Inoltre quando utilizziamo gli operatori unari & e *, dobbiamo ricordarci che loperatore . e > hannosempre precedenza su di essi.

  • 7/29/2019 Basi Programmazione c++

    55/55

    Le Basi della Programmazione 55

    struct data m;

    struct data *p;

    p = &m;

    p->gg = 6;(*p).mm = 4;

    cout