Nel corso degli anni sono nati migliaia di linguaggi di programmazione: molti di questi sono stati usati da poche persone e poi abbandonati, mentre altri hanno avuto un maggior successo. Ciascun linguaggio ha delle particolari caratteristiche, che determinano come esso possa essere classificato secondo vari aspetti. In particolare, in questo corso saranno trattati i linguaggi C e C++, che sono:
La programmazione procedurle è uno dei paradigmi di programmazione più noti e storicamente importanti. Esso è un caso particolare di programmazione imperativa, un paradigma più generale che vede una computazione (finalizzata a risolvere un determinato problema) come una sequenza di istruzioni (azioni, “ordini”). In particolare, la programmazione procedurale divide tale sequenza di istruzioni in delle procedure e funzioni che si chiamano tra di loro, interagendo tramite la condivisione di alcuni dati (le variabili globali e il passaggio di parametri). La differenza tra procedure e funzioni è che:
Nella progettazione di un linguaggio di programmazione procedurale, ci sono diversi aspetti che possono variare, tra cui ad esempio:
Tali aspetti, così come quelli che verranno presentati in seguito, corrispondono a scelte progettuali per le quali non esiste un’opzione “migliore” delle altre: ogni scelta rende un linguaggio più adatto per determinati usi e meno adatto per altri.
A basso livello, esistono sostanzialmente solo i tipi di dati numerici. Tutti i tipi più complessi devono dunque essere definiti come astrazione sulla base dei tipi numerici.
In genere, i linguaggi procedurali prevedono una serie di tipi predefiniti che corrispondono più o meno ai tipi a basso livello (numeri interi e reali, caratteri, ecc), e permettono al programmatore di definire tipi più complessi a partire da essi, tramite i costruttori di tipo, ma tendono a non supportare l’overloading degli operatori.
La dimensione e il layout in memoria delle strutture dati sono in genere fissate nella fase di compilazione (le strutture dati dinamiche vengono quindi implementate tramite puntatori e gruppi di celle di dimensione fissa), e l’allocazione della memoria (dinamica) viene di solito gestita esplicitamente.
Una variabile corrisponde a una zona in memoria, che comprende un determinato numero di bit. Il significato della variabile dipende allora da come tali bit sono interpretati, il che è a sua volta determinato dal tipo della variabile stessa. Il processo che assegna un tipo a una variabile è detto tipizzazione. In base a come esso avviene, si distinguono due categorie di linguaggi: