Linguaggi di programmazione
– Tempo di lettura: 13 minuti-

Se vuoi diventare un buon hacker, una delle cose che devi imparare a fare è programmare. Questo articolo si pone come introduzione di tutta una serie di corsi che saranno dedicati proprio allo studio di diversi linguaggi di programmazione. Visto che amo non dare mai nulla per scontato, oggi ti spiegherò alcuni dei concetti base che ti serviranno per affrontare questi corsi in maniera più consapevole. Partirò dal funzionamento del computer: lo strumento che ti accompagnerà durante tutti i corsi e che imparerai a sfruttare come mai prima d’ora. Ti illustrerò il suo funzionamento e le sue componenti più cruciali, consentendoti alla fine di comprendere appieno la natura di un linguaggio di programmazione. Nello specifico, ecco di cosa ti parlerò oggi:

  1. Computer
  2. Memoria
  3. Rappresentazione delle informazioni
  4. CPU
  5. Linguaggi di programmazione

1. Computer

Un computer è uno strumento di fondamentale importanza per la nostra vita di tutti i giorni. Ci permette di fare cose che fino ad un secolo fa risultavano essere impensabili ma cos’è effettivamente e come funziona?

Senza scendere in troppi dettagli, possiamo vedere un computer come una macchina che attende istruzioni da eseguire. Come una sorta di calcolatrice, non mostra niente fino a quando non iniziamo a chiedergli di fare una somma, una moltiplicazione ecc.

So che ti sembrerà strano, infatti, siamo abituati ad un’idea molto diversa: in genere ci basta accendere il computer e questo inizia già a fare cose per noi. In realtà ciò avviene perché c’è qualcuno che prima di noi lo ha istruito su cosa fare dopo l’accensione. Dunque, c’è qualcuno che in un qualche modo ha detto al nostro computer “Ogni volta che ti accendono, prepara tutte le tue componenti e poi fai partire il sistema operativo”.

Il sistema operativo stesso (Windows, macOS, Linux o altri) non è altro che un insieme di istruzioni. Ciò significa che ad esempio, per gestire l’avvio, chi ha costruito il tuo sistema operativo si è occupato di fare in modo che il tuo computer comprendesse questa serie di comandi: “1.Prepara tutto ciò che ti serve per far funzionare il sistema e nel mentre mostra sullo schermo un’icona di caricamento; 2.Mostra la schermata di login; 3.Attendi che l’utente inserisca la sua password; 4.Controlla la password e, se è corretta, fallo entrare e mostragli il desktop e tutte le applicazioni disponibili” e così via.

Ovviamente sto semplificando molto le cose ma voglio che tu capisca il concetto alla base: qualunque applicazione hai utilizzato fino ad oggi sul tuo computer funziona perché c’è qualcuno che in passato ha scritto un programma, cioè un insieme di istruzioni, che dice al tuo computer cosa fare nel momento in cui tale applicazione viene avviata. Il sistema operativo è il programma fondamentale perché funge da intermediario tra l’hardware1 del tuo computer e le applicazioni che girano su di esso. Questo è il motivo per cui viene avviato automaticamente all’accensione e non richiede l’azione manuale di cliccare su un’icona specifica, come invece avviene per le applicazioni comuni. Imparando un linguaggio di programmazione potrai scrivere tu stesso in prima persona un determinato programma, sfruttando il pieno potenziale del tuo computer.

Verso la fine dell’articolo ti sarà più chiaro come si può scrivere un programma. Per il momento ti chiedo però di ignorare tutta questa parte software2 e di considerare solo il computer in sé. Ecco, come ti anticipavo, in questo caso avremmo semplicemente un dispositivo in attesa di qualcuno che gli dica cosa fare e qui torniamo all’esempio della calcolatrice. Ovviamente un computer è molto più complesso di una semplice calcolatrice. Visto che per presentartelo nel dettaglio mi ci vorrebbe un intero corso, oggi mi limiterò a parlarti delle sue 3 componenti hardware fondamentali: memoria primaria o centrale(es. RAM), memoria secondaria o di massa (es. Hard Disk o SSD) e processore (CPU). Una volta capito come funzionano queste ultime, avrai una panoramica generale del funzionamento base di un computer. Queste tre, infatti, lavorano insieme per rendere possibile tutto ciò che oggi riesce a fare questa macchina. 

Nota bene, quando parlo di computer mi riferisco anche a smartphone e tablet perché le loro architetture sono molto simili.

2. Memoria

Proprio come se stessimo parlando di un essere umano, la memoria del computer è quella sua parte che gli permette di ricordare tutte le informazioni che incontra.  Come ti ho già anticipato, abbiamo principalmente due tipi di memoria: la memoria centrale e la memoria di massa. La prima è un tipo di memoria “volatile”, cioè perde tutte le informazioni nel momento in cui si spegne il computer. La seconda invece è un tipo di memoria “non volatile”, ciò significa che, quando spegni il computer, i dati contenuti in essa non andranno persi. La memoria di massa serve per contenere file, applicazioni e tutto ciò che deve poter essere sempre recuperato. La memoria centrale invece serve per contenere quelle informazioni temporanee che servono alle applicazioni stesse per gestire la loro esecuzione. 

A questo punto potrai chiederti: perché c’è bisogno di questa distinzione? Le informazioni temporanee di cui hanno bisogno le applicazioni non possono essere gestite direttamente dalla memoria di massa? Abbiamo veramente bisogno di una memoria volatile? Devi sapere che in genere la memoria di massa è un tipo di memoria molto più lenta rispetto alla memoria centrale. Questo è un problema perché gli utenti che utilizzano le applicazioni si aspettano di usare uno strumento veloce e reattivo. E’ questo il motivo per il quale in genere, durante l’esecuzione delle applicazioni, ci si appoggia sulla RAM mentre si salvano sulla memoria secondaria solo quelle informazioni importanti che non devono essere perse.

Per farti un esempio, supponiamo di avere un programma di fotoritocco. Quando l’utente apre un’immagine all’interno dell’applicazione, il file dell’immagine viene caricato dalla memoria di massa alla RAM. Caricare l’immagine in RAM rende molto più veloce la gestione delle modifiche mantenendo l’esperienza utente fluida e reattiva. Quando l’utente apporta cambiamenti all’immagine (ad esempio, aggiunge filtri, ritaglia l’immagine o cambia il colore), queste modifiche vengono temporaneamente salvate nella RAM. In questo modo, l’utente potrà vedere immediatamente l’effetto delle modifiche apportate senza doverle applicare al file originale memorizzato sulla memoria di massa. In altri termini, in questo caso la RAM funge da “area di lavoro temporanea” per le modifiche in sospeso. Quando l’utente deciderà di salvare l’immagine dopo aver apportato le modifiche, l’applicazione copierà la versione modificata dalla RAM nel file originale sulla memoria secondaria.

Bene, a questo punto dovrebbe esserti chiaro come interagiscono le varie memorie, tuttavia, ti manca ancora un pezzo. Sapresti dirmi come vengono rappresentate le informazioni all’interno memoria?

3. Rappresentazione delle informazioni

Supponiamo che tu abbia sul tuo computer un documento. Ovviamente, quando lo aprirai, ne vedrai il contenuto sotto forma di una serie di caratteri. Devi sapere però che questa è solo una rappresentazione che fa comodo a noi persone. Siamo abituati a comunicare con la nostra lingua, dunque, nel leggere le informazioni ci aspettiamo di trovare parole da noi conosciute.

In realtà un computer non conosce il nostro linguaggio, per lui esistono solamente due valori: 0 e 1. Questi ultimi rappresentano la più piccola parte di informazione memorizzabile e sono conosciuti come “bit”. Attenzione perché quando parlo di 0 e 1 sto sempre usando una “rappresentazione a noi utile”. Di fatto, se aprissimo le celle3 della memoria non troveremmo scritto da nessuna parte i caratteri 0 o 1. Ciò che potremmo osservare proiettandoci all’interno di quest’ultima sono semplicemente due condizioni: passaggio di corrente (1) e assenza di corrente (0). Ma allora come facciamo a rappresentare mediante questi due stati le informazioni che ci accompagnano ogni giorno?

Nella pratica si utilizzano dei sistemi di codifica. Ad esempio, supponiamo di voler salvare in memoria la parola “ciao”. Potremmo definire una codifica associando ad ogni carattere un numero. Le codifiche più utilizzare sono ASCII e UNICODE, di seguito puoi visualizzare la codifica ASCII:

tabella ASCII

Vediamo che, secondo tale codifica, alla ‘c’ viene associato il numero 99, alla ‘i’ 105, alla ‘a’ 97 e alla ‘o’ 111. Dunque, secondo tale codifica, la parola “c i a o”, potrebbe essere rappresentata con questa sequenza “99 105 97 111”. Perché ci serve trasformare le parole in questo modo se avevamo detto che un computer comprende solo 0 e 1?

Devi sapere che i numeri possono essere rappresentati sotto diversi sistemi. Ti spiego meglio: quello al quale siamo abituati noi è il sistema numerico decimale ma è possibile rappresentare un qualunque numero anche secondo il sistema numerico binario. Mentre il sistema decimale sfrutta tutte le cifre decimali (da 0 a 9), il sistema binario si basa su due soli numeri: 0 e 1. Ciò significa che con questo sistema si riesce a scrivere un qualunque numero mediante una sequenza di 0 e 1. Ad esempio, quella serie di numeri che abbiamo visto prima può essere riscritta come “01100011 01101001 01100001 01101111”. Per il momento ti chiedo di credermi sulla parola. Nelle lezioni future, quando sarà necessario, ti spiegherò meglio come funziona questo sistema.

Ciò che ti interessa per il momento è che abbiamo trovato un modo per memorizzare la parola “ciao” in una maniera comprensibile da un computer. Questo era giusto un esempio ma ci sono diversi tipi di codifica per memorizzare diverse tipologie di dati, il concetto alla base però è sempre lo stesso: bisogna trovare un modo per passare dalla “lingua dei computer” alla nostra lingua e viceversa.

4. CPU

La CPU (Central Processing Unit) è quella componente di un computer che è in grado di eseguire delle operazioni. Per completare queste ultime essa si appoggia proprio sulle memorie che abbiamo appena introdotto. Possiamo dire alla CPU quale operazione eseguire mediante delle istruzioni. Sì, in un certo senso, sto parlando delle stesse istruzioni delle quali ti accennavo prima. C’è però da fare una precisazione. Prima ti ho parlato di istruzioni come “Mostra la schermata di login” oppure “Attendi che l’utente inserisca la sua password”. La verità è che, anche se può sembrare strano, la CPU può fare solo poche operazioni elementari come ad esempio: addizione, sottrazione o operazioni di confronto. Dunque, quella che può sembrare un’operazione semplice come “Controlla la password e, se è corretta, fallo entrare” deve essere scomposta in un sacco di operazioni elementari da eseguire in un certo ordine.

Ciò che è straordinaria è l’estrema velocità con la quale la CPU riesce a fare queste operazioni. E’ tale velocità che ci permette di arrivare ad ottenere delle applicazioni complesse come quelle che utilizziamo oggi. In generale però è estremamente difficile costruire un programma utilizzando direttamente le istruzioni del processore. Proprio per questo si utilizzano i cosiddetti “linguaggi di programmazione”. L’azione di utilizzare tali linguaggi per creare un’applicazione si chiama “programmare”.

5. Linguaggi di programmazione

Un linguaggio di programmazione fornisce un’astrazione a un livello più alto rispetto a quello delle istruzioni della CPU, rendendo più accessibile la scrittura e la comprensione dei programmi da parte dei programmatori. Ovviamente, l’architettura del computer rimane la stessa che ti ho appena presentato: la CPU non può comprendere direttamente le istruzioni di questi linguaggi. Proprio per questo, si ha la necessità di altri programmi come i compilatori che si occupano proprio di prendere tale linguaggio e di tradurlo in istruzioni supportate dalla CPU.

Vi sono diversi possibili livelli di astrazione. Esistono linguaggi a basso livello (es. l’Assembly) la cui logica si avvicina molto alle istruzioni della CPU. Sono i linguaggi in cui si riesce ad avere il pieno controllo dell’hardware sottostante. Rimanendo su questi livelli, tuttavia, rimane comunque difficile progettare una grossa applicazione. Infatti ciò richiede di dover ragionare in termini di operazioni elementari. E’ necessario, dunque, avere una comprensione dettagliata dell’architettura della CPU. Inoltre, richiede profonda conoscenza della memoria e di tutte le componenti che è possibile sfruttare in un computer. E’ un lavoro altamente tecnico e soggetto ad errori. Proprio per questo la programmazione in questi linguaggi è spesso riservata a scenari specifici.

La maggior parte degli sviluppatori lavora invece utilizzando linguaggi di programmazione ad alto livello. Un linguaggio di programmazione ad alto livello è un linguaggio progettato per essere comprensibile e più facilmente gestibile dagli esseri umani. Questi linguaggi offrono un alto livello di astrazione rispetto alle istruzioni macchina, il che significa che sono più vicini al linguaggio umano e meno dettagliati rispetto al funzionamento interno del computer. Questi linguaggi sono progettati per semplificare il processo di sviluppo del software, consentendo ai programmatori di concentrarsi sulla logica e sulla struttura del programma, piuttosto che sulle complessità dell’hardware sottostante. 

Il primo linguaggio che ti consiglio di studiare è C. Quest’ultimo è uno dei linguaggi di programmazione più importanti. E’ stato utilizzato ampiamente per molti decenni e continua ad essere utilizzato anche oggi. Imparare C fornisce una solida base per la comprensione di altri linguaggi di programmazione. E’ un linguaggio di livello medio-basso, il che significa che fornisce abbastanza controllo sulle risorse hardware del computer senza arrivare ai livelli di complessità trattati dai linguaggi a basso livello. Questo lo rende potente e veloce anche se comunque richiede una maggiore attenzione da parte del programmatore per gestire la memoria e le risorse in modo appropriato. Iniziare a programmare con questo livello di complessità ti permetterà di comprendere bene alcuni dettagli del funzionamento di un computer senza complicarti eccessivamente la vita.

Col passare del tempo, nei vari corsi approfondirò tutti i principali linguaggi di programmazione. Ogni corso si dividerà in diverse lezioni, tra una lezione e l’altra pubblicherò sul mio profilo Instagram delle anticipazioni. Da queste ultime potrai già imparare parte degli argomenti che saranno poi ben approfonditi nelle lezioni definitive che pubblicherò.

1 L’hardware è l’insieme di tutte le componenti fisiche che costituiscono un computer (CPU, memorie ecc.).

2 Con il termine “software” ci riferiamo in genere all’insieme di tutti i programmi (applicazioni, sistemi operativi ecc.) che possono girare su suo hardware. In alcuni contesti si usa la parola “software” anche per indicare un singolo programma.

3 Con “celle di memoria” ci si riferisce ai singoli elementi di memorizzazione di dati presenti nei dispositivi di memoria. Ogni cella di memoria può memorizzare un singolo bit di informazione, che può essere un valore binario 0 o 1.