





































Studia grazie alle numerose risorse presenti su Docsity
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Prepara i tuoi esami
Studia grazie alle numerose risorse presenti su Docsity
Prepara i tuoi esami con i documenti condivisi da studenti come te su Docsity
Trova i documenti specifici per gli esami della tua università
Preparati con lezioni e prove svolte basate sui programmi universitari!
Rispondi a reali domande d’esame e scopri la tua preparazione
Riassumi i tuoi documenti, fagli domande, convertili in quiz e mappe concettuali
Studia con prove svolte, tesine e consigli utili
Togliti ogni dubbio leggendo le risposte alle domande fatte da altri studenti come te
Esplora i documenti più scaricati per gli argomenti di studio più popolari
Ottieni i punti per scaricare
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Appunti completi di programmazione I, linguaggio go, lezioni + slide + libro
Tipologia: Appunti
1 / 45
Questa pagina non è visibile nell’anteprima
Non perderti parti importanti!






































2
Le prime macchine per il calcolo: abaco(concettualmente parlando) e Different Engine(Babbage 1833), venivano utilizzate per svolgere funzioni ARITMETICHE ; I Computer ➔ macchine per il calcolo; Correlazione: ASTRONOMIA → con i telescopi = INFORMATICA → con i computer; Konrad Zuse uno dei primi che realizzò la Z4, macchina per configurare e svolgere funzioni , utilizzando una logica di vettori: A +1 A V 4 5 S 1.n 1.n Nr interi di n bit E. Dijkstra → interpretò il comportamento del PC = traduzione, dal quale nacquero i linguaggi di programmazione.
La macchina di Turing è un esempio di modello di calcolo astratto (modello teorico di hardware o software, in grado di eseguire operazioni, memorizzarne il risultato e seguire il flusso dell'algoritmo) che utilizza architetture reali , che sono utili avendo pochi elementi formali, contenente celle nelle quali inserire dati , avendo un nastro infinito. La macchina di Von Neumann invece ha una memoria prefissata (non infinita) che indica lo stato della macchina e conteneva una CPU , ovvero un processore avente istruzioni che si svolgono in sequenza: Quindi ha una memoria che controlla lo stato della macchina e una CPU divisa in due parti, la ALU ovvero l’Unità Logico - Aritmetica, utilizzata per sommare, elevare, calcoli aritmetici e la CU ovvero l’unità di Controllo che serviva per attivare e disattivare i collegamenti per mettere in funzione la ALU. Per programmare è necessario avere un programma con delle istruzioni con vari collegamenti che permettano di fare delle specifiche operazioni; Es. SOMMA = serie di circuiti da aprire e chiudere per permettere di sommare delle celle; Quindi i passi da fare sono: 1) costruire la macchina, 2) scrivere in memoria dati e istruzioni, 3) macchina lavora e da l’output; Un esempio reale: Assembly MIPS 32 , nella quale creo un insieme di istruzioni (pre-settate) che usino un linguaggio specifico , in questo caso l’Assembly language; Es. La funzione ADD serve per sommare i dati inseriti (questo viene specificato nel momento della programmazione del linguaggio stesso/della macchina); La programmazione di queste macchine permette di costruire qualcosa per poi utilizzarlo a legare diverse celle con dati e istruzioni; Il funzionamento della macchina = prevede l’interazione tra un registro, una CPU e il Program Counter: Se A è un vettore = A[4]+
In questo pezzo di codice l’obiettivo era quello di creare una funzione che mi permettesse di saltare 4 da un’azione a un’altra, qualora il contenuto di una cella sia uguale a 0 :
5 Nel seguente codice si vuole calcolar e la somma di 2 numeri, Ra + Rb e metterli all’interno di Rd: Per prima cosa azzero Rd (ovvero il registro in cui inserisco la somma); Uso la funzione INC per incrementare Ra con il valore di Rb; Ora avrò la somma di Ra e Rb all’interno di Ra , quindi uso la funzione COPY(creata sopra) per inserirla in Rd. Programmiamo la complessità : analizziamo il quesito e organizziamo un processo per aiutare l’utente , con le istruzioni assembly teoricamente è possibile, ma è impercorribile, su utilizza quindi:
7
Pattern_0 ➔ struttura minimale che hanno tutti i programmi Go; è già un sorgente Go eseguibile , come se “invocassi” il compilatore Import “fmt” ➔ per utilizzare delle librerie , solitamente “fmt” (dico al linker go le librerie da prelevare); Fmt.Println → significa che la println (print line) sta all’interno dell’istruzione fmt; fmt.Println(“Hello World”); Var valore_da_calcolare int → per dichiarare ed introdurre l’utilizzo di una variabile ( var = parola chiave) tramite un indicatore ( valore_da_calcolare ) e gli do il tipo della variabile( int ), per marcare la variabile; I VARI MOMENTI DI UNA VARIABILE Allocazione ➔ la variabile inizia ad avere una corrispondente in memoria, per poi perderla nella fase di Rilascio
Esistono regole che il compilatore mette e avvisa il programmatore cosa non va bene, e si suddividono su diversi livelli: Se sbaglio a scrivere:
8 o Quando ho un assegnamento, devo avere a sinistra un identificatore e a destra un’espressione valutabile; Se sbaglio ad esprimere un concetto:
Le variabili hanno le seguenti caratteristiche:
10 Vogliamo creare una tabella con i valori di a e b booleani, con le varie possibilità vero o falsi, e vedere come si comportano nella somma dei valori: stampa l'intestazione della prima riga: val.a , val.b, == poi assegna riassegna true o false a b / a e ti stampa il valore di a , valore di b , valore della loro somma nei vari casi (a e b si alternano di valore) \t ➔ serve per inserire uno spazio tra dei valori (qua lo metto per creare una tabellina) La tabella che si crea, facendo partire il file eseguibile è la seguente: Se con il comando go build esercizio.go → compila , vuol dire che non ci sono errori logici , e crea l’seguibile, però solo con l’eseguibile posso capire se funziona bene.
11 Solitamente si utilizzano tipi booleani all’interno di cicli, nei quali voglio confrontare dei dati, ad esempio: Voglio creare un programma che richieda all’utente di inserire un numero, se il valore inserito è maggiore di 10( if n > 10 ), allora il valore alla variabile b (b = true ) è vera, perciò entra nel if alla prima condizione e stampa ( if b { fmt.Println ( “Il valore inserito è maggiore di 10”) } , altrimenti va nell’ else e stampa { fmt.Println ( “Il valore inserito è minore di 10”) } Se volessi fare un test con degli operatori che non ci sono posso comporre quelli che già esistono. Le parentesi servono a dare un ordine di esecuzione, svolgo prima quello che c’è in parentesi; Le operazioni sono soggette a delle regole di precedenza: Regole di priorità Regole di associatività Le operazioni sui booleani, non sono le uniche che restituiscono risultati booleani, bensì ci sono altri tipi, che partono da tipi diversi di booleani e arrivano ad avere bool; Un operatore di confronto prende 2 operandi (2 nr, ad esempio interi) li confronta e ottiene un vero o falso, tipo < o > ;
13 Si vuole creare un programma che richieda all’utente un valore e il codice capisca se è positivo, nul lo o negativo. Creo un flowchart con 2 cicli If, il primo controlla se il valore è maggiore o uguale di zero, e all’interno di esso, richiedo se è maggiore di zero oppure uguale e in base al confronto stampo in output la soluzione, se la variabile non sodd isfa il primo if, stampo direttamente l’output, dicendo che il valore è negativo.
14 Ciclo For → è un ciclo iterativo, che permette di richiedere un’azione , quando la condizione è vera, altrimenti esce dal ciclo; Se non si verifica la condizione, allora esce dal ciclo for; Se si verifica, ovvero a è minore di zero, richiede con Scan(&a) il valore di a;
Voglio un programma che riceva in I un nr R e restituisca in O un messaggio: “pari” = se la prima cifra decimale è pari; “ dispari ” = se la prima cifra decimale è dispari; Metodo risolutivo: se avessi un intero, potrei calcolare il resto della divisione per 2 (operatore modulo % in GO): Tronca il numero: Se avessi come n = 77,64 → moltiplico per 10, n = 776,4 → tronca all’intero, n = 776 Infine, calcolo il resto della divisione per 2, se RESTO = 0, stampa pari; se RESTO ≠ 0, stampo dispari;
Analisi delle esigenze: per capire cosa serve progettare: Studio di fattibilità → (capire se è possibile da programmare); Stesura delle specifiche → vedere cosa scrivere in input e output; Progettazione: Sviluppo vero e proprio → dopo la codifica realizza il metodo che ho progettato; Testing e debugging → provare il programma, se il testing risponde bene siamo a buon passo e poi con il debugging sistemo i problemi; Rilascio → il software che ho scritto e lo porto al cliente; Uso , aggiornamento e manutenzione → lo utilizzo, aggiorno in base a cambiamenti e con il tempo magari il server cambia e quindi il programma può richiedere manutenzione; Dalla selezione ai cicli: Idea → si sviluppa su esempi di controllo dell’input , per verificare se ha senso la codifica proposta; Si parte da un costrutto di selezione if-then-else (esiste anche la versione senza else, + usata); Si rende poi il costrutto iterativo, ovvero valuta la condizione e vede cosa fare for condizione> e
16
Costrutto 1 = sequenza Costrutto 2 = selezione binaria (If
17 Esistono 2 funzioni che influenzano il funzionamento del codice (vanno usate con parsimonia), sono break e continue che sono una l ’opposta dell’altra. La prima permette di fermare un loop, per andare in una determinata linea proposta, mentre la seconda serve per fare ripartire una determinata selezione (solitamente ciclo if, lo permette di far diventare come un ciclo for): BREAK = h a l’effetto di mandare fuori dal ciclo la prossima iterazione, quindi nel momento in cui l’utente arriva alla condizione connessa alla funzione “break”, va fuori dal ciclo for e va a riprendere le azioni dopo (è simile al JUMP di MIPS32); Il ciclo for che ho creato serve per richiedere all’infinito all’utente un numero, finche questo non digita 0 (momento in cui entra la funzione break) e salta alle righe di codice dopo. CONTINUE = continua a far iterare un ciclo if, fino a che la condizione rimane vera Utilizzo in primis un ciclo for per scansionare i vari numeri, per farli inserire da un utente, però potrebbe inserirli fino all’infinito finché non c’è un avvenimento scritto, ovvero: CONTINUE se inserissi un numero < 1(quindi negativo) il programma torna su all’iterazione precedente per richiedere un numero diverso (come se non prendesse in memoria il numero negativo); BREAK se inserissi uno 0, il codice termina il ciclo, si interrompe e mi restituisce il codice finale (in questo caso stampa la somma dei numeri precedentemente inseriti.
19 Il MAIN è un sottoprogramma speciale, perché funziona uguale. Il MAIN è il programma vero e proprio (cioè la parte principale). I sottoprogrammi dichiarati sopra vengono usati al suo interno attraverso il meccanismo della chiamata. Una chiamata di procedura può apparire in ogni punto dove potrebbe apparire uno statement, mentre una chiamata di funzione può apparire in ogni punto dove potrebbe apparire un'espressione del tipo corrispondente. Una chiamata = di un sottoprogramma è costituita dal nome del sottoprogramma e dagli elementi che istanziano i parametri (i cosiddetti parametri attuali).
Function call frame = è un record di attivazione dei sottoprogrammi , è una zona di memoria, attivata alla chiamata che contiene delle informazioni: VARIABILI LOCALI → Variabili definite nel sottoprogramma; Parametri dei sottoprogrammi (input e output) Altre informazioni per il controllo Il principio di località = dice che è meglio che ogni effetto del mio codice, funzioni sulla mia istruzione o nei pezzi di codice intorno, per evitare di “perdersi” tra le variabili ; Scope di variabili = luogo nel quale la variabile dichiarata, può essere utilizzata (regione della variabile locale); Il passaggio di parametri a sottoprogrammi, in input ho un valore, poi chiamo con il sottoprogramma la variabile(var tmp float) e ottengo in output il valore lavorato all’interno del sottoprogramma , quindi quelle che hanno seguito le istruzioni del sottoprogramma; Con RETURN = ottengo il controllo del programma iniziale, restituzione della variabile elaborata nel sottoprogramma;
Vengono passati i dati in input per copia, quindi una volta che si fa una copia, la variabile iniziale diventa una variabile locale del sottoprogramma; Le inizializzo come variabili del sottoprogramma, potendole manipolare come variabili locali; Differenza tra variabili locali e di output, è che al momento del return, il valore del parametro di output, viene copiato, nell’istruzione del chiamante ;
Il Ruolo concettuale, nella testa di un programmatore un dato può essere Input, Output o Entrambi; Dal punto di vista meccanico invece, go usa strumenti per rendere possibili le esistenze di questi tipi di variabili, non mette una gestione diretta(come invece permette c++ per reference), quindi il meccanismo interno è per copia di parametri MECCANISMO DELLE VARIABILI:
20
La Function Call Frame serve per la memoria, per attivare i record dei sottoprogrammi; Così per fare nuove chiamate utilizzo sempre Function call frame, per chiamare altre funzioni, altri sottoprogrammi con le loro variabili; Al momento della chiamata, le variabili vengono copiate nelle variabili del sottoprogramma; Una volta che terminar il funzionamento del sottoprogramma, il Function call frame perde di valore , finisce, copia i valori dal Function call frame del chiamato al Function call frame del chiamante. Se ad esempio all’interno del sottoprogramma, viene chiamato un al tro programma, fa lo stesso passaggio sopra, che quindi va a copiare le informazioni nelle variabili locali del sottoprogramma appena chiamato ; Ogni Function call frame, ogni sottoprogramma ha delle variabili locali “nuove”, si chiamano uguali, ma hanno indirizzi diversi, e il valore, prendono quelle appena inserito nel programma chiamante; Le variabili locali = l ’indirizzo delle variabili locali, diventa noto, quando attivo la chiamata al sottoprogramma:
Quando posso usare una variabile e quando no , se è in memoria posso usare la variabile,
Se guardo solo il main, penso che il programma stampi 4; Però è costruito male, poiché usa il nome uguale per 2 variabili: Quindi la prima a, viene inizializzata a zero (come tutte le variabili), e quindi la func double da output in res = 0, poi la inserisco nella principale, func main